batch retrieval in statistics
authorJiří Filipovič <fila@ics.muni.cz>
Fri, 9 Jul 2010 11:05:03 +0000 (11:05 +0000)
committerJiří Filipovič <fila@ics.muni.cz>
Fri, 9 Jul 2010 11:05:03 +0000 (11:05 +0000)
13 files changed:
org.glite.lb.client/examples/stats-duration-fromto.c
org.glite.lb.client/examples/stats.c
org.glite.lb.client/interface/statistics.h
org.glite.lb.client/src/statistics.c
org.glite.lb.common/interface/xml_conversions.h
org.glite.lb.common/interface/xml_parse.h
org.glite.lb.common/src/xml_conversions.c
org.glite.lb.common/src/xml_parse.c.T
org.glite.lb.server/src/lb_proto.c
org.glite.lb.server/src/lb_xml_parse.c.T
org.glite.lb.server/src/lb_xml_parse.h
org.glite.lb.server/src/stats.c
org.glite.lb.server/src/stats.h

index 79d7385..5603998 100644 (file)
@@ -34,8 +34,9 @@ int main(int argc,char **argv)
        time_t  now,from,to;
        char    *cfrom,*cto;
        int     from_res,to_res;
-       float   duration, dispersion;
-
+       float   *durations, *dispersions;
+       char    **groups;
+       int     i;
 
        edg_wll_InitContext(&ctx);
 
@@ -55,7 +56,9 @@ int main(int argc,char **argv)
         to = now;
         from = now - 600;
 
-       if (edg_wll_StateDurationFromTo(ctx,group,atoi(argv[2]),atoi(argv[3]),argc >=5 ? atoi(argv[4]) : 0, &from,&to,&duration,&dispersion,&from_res,&to_res))
+       if (edg_wll_StateDurationFromTo(ctx,group,atoi(argv[2]),atoi(argv[3]),
+               argc >=5 ? atoi(argv[4]) : 0, &from,&to,&durations,&dispersions,
+               &groups,&from_res,&to_res))
        {
                char    *et,*ed;
                edg_wll_Error(ctx,&et,&ed);
@@ -68,11 +71,19 @@ int main(int argc,char **argv)
        cfrom[strlen(cfrom)-1] = 0;
        cto[strlen(cto)-1] = 0;
 
-       printf("Average duration at \"%s\": %f s\n"
-              "Dispersion index: %f\n"
-              "  Measuered from %s to %s\n"
-              "  With resolution from %d to %d s\n",
-              argv[1],duration,dispersion,cfrom,cto,from_res,to_res);
+       for (i = 0; groups[i]; i++)
+               printf("Average duration at \"%s\": %f s\n"
+                      "Dispersion index: %f\n"
+                      "  Measuered from %s to %s\n"
+                      "  With resolution from %d to %d s\n",
+                      /*argv[1]*/groups[i],durations[i],dispersions[i],cfrom,
+                       cto,from_res,to_res);
+
+       free(durations);
+       free(dispersions);
+       for (i = 0; groups[i]; i++)
+               free(groups[i]);
+       free(groups);
 
        return 0;
 }
index 82cab20..d284905 100644 (file)
@@ -34,7 +34,10 @@ int main(int argc,char **argv)
        time_t  now,from,to;
        char    *cfrom,*cto;
        int     from_res,to_res;
-       float   val;
+       float   *vals;
+       char    **groups;
+       int     i;
+       char    ce = NULL;
 
 
        edg_wll_InitContext(&ctx);
@@ -81,7 +84,7 @@ int main(int argc,char **argv)
        from = now - 60;
 
        if (edg_wll_StateRate(ctx,group,atoi(argv[2]),argc >=4 ? atoi(argv[3]) : 0,
-                               &from,&to,&val,&from_res,&to_res))
+                               &from,&to,&vals,&groups,&from_res,&to_res))
        {
                char    *et,*ed;
                edg_wll_Error(ctx,&et,&ed);
@@ -94,11 +97,16 @@ int main(int argc,char **argv)
        cfrom[strlen(cfrom)-1] = 0;
        cto[strlen(cto)-1] = 0;
 
-       printf("Average failure rate at \"%s\": %f jobs/s\n"
-              "  Measuered from %s to %s\n"
-              "  With resolution from %d to %d s\n",
-              argv[1],val,cfrom,cto,from_res,to_res);
+       for (i = 0; groups[i]; i++)
+               printf("Average failure rate at \"%s\": %f jobs/s\n"
+                      "  Measuered from %s to %s\n"
+                      "  With resolution from %d to %d s\n",
+                       /*argv[1]*/groups[i],vals[i],cfrom,cto,from_res,to_res);
 
+       free(vals);
+       for (i = 0; groups[i]; i++)
+               free(groups[i]);
+       free(groups);
        return 0;
 }
 
index 7e8a656..9cc79c3 100644 (file)
@@ -46,7 +46,8 @@ int edg_wll_StateRate(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *rate,
+       float   **rates,
+       char    ***groups,
        int     *res_from,
        int     *res_to
 );
@@ -63,7 +64,8 @@ int edg_wll_StateDuration(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *duration,
+       float   **durations,
+       char    ***groups,
        int     *res_from,
        int     *res_to
 );
@@ -76,8 +78,9 @@ int edg_wll_StateDurationFromTo(
         int     minor,
         time_t  *from,
         time_t  *to,
-        float   *duration,
-       float   *dispersion,
+        float   **durations,
+       float   **dispersions,
+       char    ***groups,
         int     *res_from,
         int     *res_to
 );
index cd2ece4..f3e33a6 100644 (file)
@@ -55,13 +55,14 @@ int edg_wll_StateRate(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *rate,
+       float   **rates,
+       char    ***groups,
        int     *res_from,
        int     *res_to)
 
 {      
        char    *response = NULL, *send_mess = NULL, *message = NULL;
-       float   not_returned;
+       float   *not_returned;
        
        
        edg_wll_ResetError(ctx);
@@ -80,8 +81,8 @@ int edg_wll_StateRate(
        if (http_check_status(ctx,response))
                goto err;
 
-       edg_wll_ParseStatsResult(ctx,message, from, to, rate, 
-                       &not_returned, &not_returned, res_from, res_to);
+       edg_wll_ParseStatsResult(ctx,message, from, to, rates
+               &not_returned, &not_returned, groups, res_from, res_to);
 
 err:
        free(response);
@@ -102,12 +103,13 @@ int edg_wll_StateDuration(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *duration,
+       float   **durations,
+       char    ***groups,
        int     *res_from,
        int     *res_to)
 {
        char    *response = NULL, *send_mess = NULL, *message = NULL;
-       float   not_returned;
+       float   *not_returned;
        
        
        edg_wll_ResetError(ctx);
@@ -127,7 +129,7 @@ int edg_wll_StateDuration(
                goto err;
 
        edg_wll_ParseStatsResult(ctx,message, from, to, &not_returned, 
-                       duration, &not_returned, res_from, res_to);
+               durations, &not_returned, groups, res_from, res_to);
 
 err:
        free(response);
@@ -149,14 +151,15 @@ int edg_wll_StateDurationFromTo(
        int     minor,
         time_t  *from,
         time_t  *to,
-        float   *duration,
-       float   *dispersion,
+        float   **durations,
+       float   **dispersions,
+       char    ***groups,
         int     *res_from,
         int     *res_to
 )
 {
         char    *response = NULL, *send_mess = NULL, *message = NULL;
-        float   not_returned;
+        float   *not_returned;
 
 
         edg_wll_ResetError(ctx);
@@ -176,7 +179,7 @@ int edg_wll_StateDurationFromTo(
                 goto err;
 
         edg_wll_ParseStatsResult(ctx,message, from, to, &not_returned,
-                        duration, dispersion, res_from, res_to);
+                        durations, dispersions, groups, res_from, res_to);
 
 err:
         free(response);
index 6cb9038..a4ae7dd 100644 (file)
@@ -97,7 +97,8 @@ typedef struct _edg_wll_XML_ctx {
        edg_wll_JobStatCode     statsFinalState;
        int                     statsMinor;
        time_t                  statsFrom, statsTo;
-       float                   statsRate, statsDuration, statsDispersion;
+       float                   *statsRate, *statsDuration, *statsDispersion;
+       char                    **statsGroup;
        int                     statsResFrom, statsResTo;
        glite_jobid_t           jobId;
        char                    *source;
index b53c510..53d66a3 100644 (file)
@@ -93,7 +93,7 @@ extern int edg_wll_StatsRequestToXML(edg_wll_Context,const char *,const edg_wll_
 
 extern int edg_wll_StatsDurationFTRequestToXML(edg_wll_Context,const char *,const edg_wll_QueryRec *,edg_wll_JobStatCode,edg_wll_JobStatCode,int,time_t *,time_t *,char **);
        
-extern edg_wll_ErrorCode edg_wll_ParseStatsResult(edg_wll_Context ctx, char *messageBody, time_t *from, time_t *to, float *rate, float *duration, float *dispersion, int *res_from, int *res_to);
+extern edg_wll_ErrorCode edg_wll_ParseStatsResult(edg_wll_Context ctx, char *messageBody, time_t *from, time_t *to, float **rate, float **duration, float **dispersion, char ***group, int *res_from, int *res_to);
 
 #ifdef __cplusplus
 }
index 00f5a78..1a7ba37 100644 (file)
@@ -89,9 +89,10 @@ void edg_wll_initXMLCtx(edg_wll_XML_ctx *c) {
        c->statsBaseState = EDG_WLL_JOB_UNDEF;
        c->statsFinalState = EDG_WLL_JOB_UNDEF;
        c->statsMinor = 0;
-       c->statsRate = 0;
-       c->statsDuration = 0;
-       c->statsDispersion = 0;
+       c->statsRate = NULL;
+       c->statsDuration = NULL;
+       c->statsDispersion = NULL;
+       c->statsGroup = NULL; 
        c->statsFrom = 0;
        c->statsTo = 0;
        c->statsResFrom = 0;
@@ -105,11 +106,20 @@ void edg_wll_initXMLCtx(edg_wll_XML_ctx *c) {
 
 
 void edg_wll_freeXMLCtx(edg_wll_XML_ctx *c) {
+       int i;
         if (c->char_buf) free(c->char_buf);
         if (c->errtxt) free(c->errtxt);
         if (c->warntxt) free(c->warntxt);
        if (c->XML_tag) free(c->XML_tag);
        if (c->XML_tag2) free(c->XML_tag2);
+       if (c->statsRate) free(c->statsRate);
+       if (c->statsDuration) free(c->statsDuration);
+       if (c->statsDispersion) free(c->statsDispersion);
+       if (c->statsGroup){
+               for (i = 0; c->statsGroup[i]; i++)
+                       free(c->statsGroup[i]);
+               free(c->statsGroup);
+       }
 }
 
 
index 3a3a6f9..f449c77 100644 (file)
@@ -724,14 +724,29 @@ static void startStatsResult(void *data, const char *el, const char **attr)
                                 else if (!strcmp(attr[i],"desc"))
                                         XMLCtx->errDesc = strdup(attr[i+1]);
                                 else { unexpError() }
-                        }       
+                        }      
+                       XMLCtx->statsGroup = (char**)malloc(1*sizeof(char*));
+                       XMLCtx->statsGroup[0] = NULL;
+                       XMLCtx->position = -1;
+       
                         break;          
-                case 1: if (strcasecmp(el,"from") && strcasecmp(el,"to") &&
-                               strcasecmp(el,"rate") && strcasecmp(el,"duration") && 
-                               strcasecmp(el,"dispersion") && strcasecmp(el,"res_from") &&
-                               strcasecmp(el,"res_to")) 
-                                       unexpWarning()
-                        break;  
+               case 1: if (strcasecmp(el,"from") && strcasecmp(el,"to") &&
+                       strcasecmp(el,"res_from") && strcasecmp(el,"res_to") &&
+                       strcasecmp(el, "stat"))
+                               unexpWarning()
+                       if (strcasecmp(el, "stat") == 0){
+                               XMLCtx->position++;
+                               XMLCtx->statsGroup = (char**)realloc(XMLCtx->statsGroup, (XMLCtx->position+2)*sizeof(char*));
+                                XMLCtx->statsGroup[XMLCtx->position+1] = NULL;
+                                XMLCtx->statsRate = (float*)realloc(XMLCtx->statsRate, (XMLCtx->position+1)*sizeof(float));
+                                XMLCtx->statsDuration = (float*)realloc(XMLCtx->statsDuration, (XMLCtx->position+1)*sizeof(float));
+                                XMLCtx->statsDispersion = (float*)realloc(XMLCtx->statsDispersion, (XMLCtx->position+1)*sizeof(float));
+                       }
+                       break;
+               case 2: if (strcasecmp(el,"rate") && strcasecmp(el,"duration") 
+                       && strcasecmp(el,"dispersion") && strcasecmp(el,"group"))
+                               unexpWarning()
+                       break;
                 default: unexpWarning()
                          break;
         }       
@@ -1318,17 +1333,25 @@ static void endStatsResult(void *data, const char *el UNUSED_VAR)
                         XMLCtx->statsFrom = edg_wll_from_string_to_time_t(XMLCtx);
                 else if (!strcmp(XMLCtx->element,"to"))
                         XMLCtx->statsTo = edg_wll_from_string_to_time_t(XMLCtx);
-                else if (!strcmp(XMLCtx->element,"rate"))
-                        XMLCtx->statsRate = edg_wll_from_string_to_float(XMLCtx);
-                else if (!strcmp(XMLCtx->element,"duration"))
-                        XMLCtx->statsDuration = edg_wll_from_string_to_float(XMLCtx);
-               else if (!strcmp(XMLCtx->element,"dispersion"))
-                        XMLCtx->statsDispersion = edg_wll_from_string_to_float(XMLCtx);
                 else if (!strcmp(XMLCtx->element,"res_from"))
                         XMLCtx->statsResFrom = edg_wll_from_string_to_int(XMLCtx);
                 else if (!strcmp(XMLCtx->element,"res_to"))
                         XMLCtx->statsResTo = edg_wll_from_string_to_int(XMLCtx);
        }
+       else if (XMLCtx->level == 3){
+               if (!strcmp(XMLCtx->element,"rate"))
+                        XMLCtx->statsRate[XMLCtx->position] = 
+                               edg_wll_from_string_to_float(XMLCtx);
+                else if (!strcmp(XMLCtx->element,"duration"))
+                        XMLCtx->statsDuration[XMLCtx->position] = 
+                               edg_wll_from_string_to_float(XMLCtx);
+                else if (!strcmp(XMLCtx->element,"dispersion"))
+                        XMLCtx->statsDispersion[XMLCtx->position] = 
+                               edg_wll_from_string_to_float(XMLCtx);
+                else if (!strcmp(XMLCtx->element,"group"))
+                        XMLCtx->statsGroup[XMLCtx->position] = 
+                               edg_wll_from_string_to_string(XMLCtx);
+       }
 
        edg_wll_freeBuf(XMLCtx);
        XMLCtx->level--;
@@ -2385,11 +2408,12 @@ edg_wll_ErrorCode edg_wll_ParseQuerySequenceCodeResult(edg_wll_Context ctx, char
 
 
 /* parse statistics result from client */
-edg_wll_ErrorCode edg_wll_ParseStatsResult(edg_wll_Context ctx, char *messageBody, time_t *from, time_t *to, float *rate, float *duration, float *dispersion, int *res_from, int *res_to)
+edg_wll_ErrorCode edg_wll_ParseStatsResult(edg_wll_Context ctx, char *messageBody, time_t *from, time_t *to, float **rate, float **duration, float **dispersion, char ***group, int *res_from, int *res_to)
 {
        edg_wll_XML_ctx XMLCtx;
        edg_wll_ErrorCode errorCode;
        XML_Char *encoding = "ISO-8859-1";
+       int i;
 
        if (!messageBody)
                return edg_wll_SetError(ctx, EDG_WLL_ERROR_XML_PARSE, "Parse error: empty response");
@@ -2422,17 +2446,30 @@ edg_wll_ErrorCode edg_wll_ParseStatsResult(edg_wll_Context ctx, char *messageBod
        if ((errorCode = edg_wll_Error(ctx,NULL,NULL))) {
                *from = -1;
                *to = -1;
-               *rate = 0;
-               *duration = 0;
-               *dispersion = 0;
+               *rate = NULL;
+               *duration = NULL;
+               *dispersion = NULL;
+               *group = NULL;
                *res_from = -1;
                *res_to = -1;
        } else {
                *from = XMLCtx.statsFrom;
                *to = XMLCtx.statsTo;
-               *rate = XMLCtx.statsRate;
-               *duration = XMLCtx.statsDuration;
-               *dispersion = XMLCtx.statsDispersion;
+               *rate = NULL;
+                *duration = NULL;
+                *dispersion = NULL;
+               *group = NULL;
+               for (i = 0; XMLCtx.statsGroup[i]; i++){
+                       *rate = (float*)realloc(*rate, (i+1)*sizeof(float));
+                        (*rate)[i] = XMLCtx.statsRate[i];
+                        *duration = (float*)realloc(*duration, (i+1)*sizeof(float));
+                        (*duration)[i] = XMLCtx.statsDuration[i];
+                        *dispersion = (float*)realloc(*dispersion, (i+1)*sizeof(float));
+                        (*dispersion)[i] = XMLCtx.statsDispersion[i];
+                        *group = (char**)realloc(*group, (i+2)*sizeof(char*));
+                        (*group)[i] = strdup(XMLCtx.statsGroup[i]);
+                        (*group)[i+1] = NULL;
+               }
                *res_from = XMLCtx.statsResFrom;
                *res_to = XMLCtx.statsResTo;
        }
index 1cc473d..adf01d9 100644 (file)
@@ -1196,7 +1196,8 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                        edg_wll_JobStatCode final = EDG_WLL_JOB_UNDEF;
                        time_t from, to;
                        int i, j, minor, res_from, res_to;
-                       float rate = 0, duration = 0, dispersion = 0;
+                       float *rates = NULL, *durations = NULL , *dispersions = NULL;
+                       char **groups = NULL;
                        
                        if (parseStatsRequest(ctx, messageBody, &function, &conditions, 
                                                &base, &final, &minor, &from, &to))
@@ -1209,16 +1210,19 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                                if (!strcmp(function,"Rate")) 
                                        err = edg_wll_StateRateServer(ctx,
                                                conditions[0], base, minor, 
-                                               &from, &to, &rate, &res_from, &res_to); 
+                                               &from, &to, &rates, &groups, 
+                                               &res_from, &res_to); 
                                else if (!strcmp(function,"Duration"))
                                        err = edg_wll_StateDurationServer(ctx,
                                                conditions[0], base, minor, 
-                                               &from, &to, &duration, &res_from, &res_to); 
+                                               &from, &to, &durations, &groups,
+                                               &res_from, &res_to); 
                                else if (!strcmp(function, "DurationFromTo"))
                                        err = edg_wll_StateDurationFromToServer(
                                                ctx, conditions[0], base, final,
-                                                minor, &from, &to, &duration,
-                                                &dispersion, &res_from, &res_to);
+                                                minor, &from, &to, &durations,
+                                                &dispersions, &groups, 
+                                               &res_from, &res_to);
                                
                                switch (err) {
                                        case 0: if (html) ret = HTTP_NOTIMPL;
@@ -1236,9 +1240,18 @@ edg_wll_ErrorCode edg_wll_Proto(edg_wll_Context ctx,
                                /* glue errors (if eny) to XML responce */ 
                                if (!html && !fatal)
                                        if (edg_wll_StatsResultToXML(ctx, from,
-                                               to, rate, duration, dispersion,
+                                               to, rates, durations, 
+                                               dispersions, groups,
                                                res_from, res_to, &message))
                                                ret = HTTP_INTERNAL;
+                               if (rates) free(rates);
+                               if (durations) free(durations);
+                               if (dispersions) free(dispersions);
+                               if (groups){
+                                       for(i = 0; groups[i]; i++)
+                                               free(groups[i]);
+                                       free(groups);
+                               }
                        }
                        
                        free(function);
index ffb4c7b..124d96e 100644 (file)
@@ -2073,24 +2073,36 @@ int edg_wll_StatsResultToXML(
                 edg_wll_Context ctx,
                time_t from,
                time_t to,
-               float rate,
-               float duration,
-               float dispersion,
+               float *rates,
+               float *durations,
+               float *dispersions,
+               char  **groups,
                int res_from,
                int res_to,
                 char **message)
 {
         char *pomA, *pomB;
-
+       int i;
 
        pomA = strdup("");
        edg_wll_add_time_t_to_XMLBody(&pomA, from, "from", -1);
        edg_wll_add_time_t_to_XMLBody(&pomA, to, "to", -1);
-       edg_wll_add_float_to_XMLBody(&pomA, rate, "rate", 0);
-       edg_wll_add_float_to_XMLBody(&pomA, duration, "duration", 0);
-       edg_wll_add_float_to_XMLBody(&pomA, dispersion, "dispersion", 0);
        edg_wll_add_int_to_XMLBody(&pomA, res_from, "res_from", -1);
-       edg_wll_add_int_to_XMLBody(&pomA, res_to, "res_to", -1);
+        edg_wll_add_int_to_XMLBody(&pomA, res_to, "res_to", -1);
+
+       if (groups) for (i = 0; groups[i]; i++){
+               asprintf(&pomB, "%s\t\t<stat>\n", pomA);
+               pomA = pomB;
+               edg_wll_add_string_to_XMLBody(&pomA, groups[i], "group", NULL);
+               if (rates)
+                       edg_wll_add_float_to_XMLBody(&pomA, rates[i], "rate", 0);
+               if (durations)
+                       edg_wll_add_float_to_XMLBody(&pomA, durations[i], "duration", 0);
+               if (dispersions)
+                       edg_wll_add_float_to_XMLBody(&pomA, dispersions[i], "dispersion", 0);
+               asprintf(&pomB, "%s\t\t</stat>\n", pomA);
+               pomA = pomB;
+       }
 
        if (ctx->errDesc || ctx->errCode)
                trio_asprintf(&pomB,"%s code=\"%d\" desc=\"%|Xs\">\r\n%s%s",
@@ -2099,6 +2111,8 @@ int edg_wll_StatsResultToXML(
                trio_asprintf(&pomB,"%s>\r\n%s%s", STATS_RESULT_BEGIN, pomA, STATS_RESULT_END);
        free(pomA);
 
+       printf("XXX %s XXX\n", pomB);
+
         *message = pomB;
         return 0;
 }
index 3698ae1..fc92bdd 100644 (file)
@@ -50,7 +50,7 @@ int edg_wll_IndexedAttrsToXML(edg_wll_Context ctx, char **message);
 int edg_wll_NotifResultToXML(edg_wll_Context ctx, time_t validity, char **message);
 int edg_wll_QuerySequenceCodeResultToXML(edg_wll_Context ctx, char *source, char **message);
 
-int edg_wll_StatsResultToXML(edg_wll_Context,time_t,time_t,float,float,float,int,int,char **);
+int edg_wll_StatsResultToXML(edg_wll_Context,time_t,time_t,float*,float*,float*,char**,int,int,char **);
 
 int parseStatsRequest(edg_wll_Context,char *,char **,edg_wll_QueryRec ***,edg_wll_JobStatCode *,edg_wll_JobStatCode *,int *,time_t *,time_t *);
 
index 0918fe7..b4b0296 100644 (file)
@@ -221,6 +221,7 @@ static int stats_search_group(edg_wll_Context ctx, const edg_wll_JobStat *jobsta
                 }
 
                 strcpy((*g)->sig,sig);
+               (*g)->destination = strdup(jobstat->destination);
                 (*g)->last_update = jobstat->stateEnterTime.tv_sec; //now;
         }
         else
@@ -439,59 +440,24 @@ static int findStat(
        return 0;
 }
 
-int edg_wll_StateRateServer(
-       edg_wll_Context ctx,
-       const edg_wll_QueryRec  *group,
-       edg_wll_JobStatCode     major,
-       int                     minor,
-       time_t  *from, 
-       time_t  *to,
-       float   *rate,
-       int     *res_from,
-       int     *res_to
+static int stateRateRequest(
+       edg_wll_Context ctx,
+       edg_wll_Stats *stats,
+       struct edg_wll_stats_group    *g,
+       time_t  *from, 
+        time_t  *to,
+        float   *rate,
+        int     *res_from,
+        int     *res_to
 )
 {
-       edg_wll_Stats *stats = default_stats;   /* XXX: hardcoded */
-       struct edg_wll_stats_group      *g;
-       struct edg_wll_stats_archive    *a;
-       int     i,j,matchi;
-       char    *sig = NULL;
-       time_t  afrom,ato;
-       long    match, diff;
-       int     err;
+       struct edg_wll_stats_archive    *a;
+        int     i,j,matchi;
+       time_t  afrom,ato;
+        long    match, diff;
 
        edg_wll_ResetError(ctx);
 
-       if ((err = findStat(ctx, group, major, EDG_WLL_JOB_UNDEF, minor, from, to, &stats))) return err;
-
-       /* remap the file if someone changed its size */
-       if (stats->map->grpno != stats->grpno)
-       {       
-               if (flock(stats->fd,LOCK_EX)) return edg_wll_SetError(ctx,errno,"flock()");
-               if (stats_remap(stats)) {
-                       edg_wll_SetError(ctx,errno,"shmem remap failed");
-                       goto cleanup;
-               }
-       }
-
-       if (flock(stats->fd,LOCK_SH)) return edg_wll_SetError(ctx,errno,"flock()");
-
-       /* XXX */
-       sig = str2md5base64(group->value.c);
-
-
-       for (i=0, g=stats->map; i<stats->grpno; i++) {
-               if (!strcmp(sig,g->sig)) break;
-               g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
-       }
-
-       if (i == stats->grpno) {
-               glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, 
-                       "no match: %s\n",sig);
-               edg_wll_SetError(ctx,ENOENT,"no matching group");
-               goto cleanup;
-       }
-
        match = 0;
        matchi = -1;
        /* XXX: assumes decreasing resolution of archives */ 
@@ -580,16 +546,107 @@ int edg_wll_StateRateServer(
                 *rate += c->cnt * (float)diff/i;
 
                 if (*to >= afrom && *to < afrom+i) {
-                        glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, "matched to: match %d, rate %f", match, rate);
+                        glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, "matched to: match %d, rate %f", match, *rate);
                         break;
                 }
        }
        *rate /= match;
 
 cleanup:
-       free(sig);
-       flock(stats->fd,LOCK_UN);
-       return edg_wll_Error(ctx,NULL,NULL);
+        return edg_wll_Error(ctx,NULL,NULL);
+}
+
+int edg_wll_StateRateServer(
+       edg_wll_Context ctx,
+       const edg_wll_QueryRec  *group,
+       edg_wll_JobStatCode     major,
+       int                     minor,
+       time_t  *from, 
+       time_t  *to,
+       float   **rates,
+       char    ***groups,
+       int     *res_from,
+       int     *res_to
+)
+{
+       edg_wll_Stats *stats = default_stats;   /* XXX: hardcoded */
+       struct edg_wll_stats_group    *g;
+       int     i;
+       char    *sig = NULL;    
+       int     err;
+
+       edg_wll_ResetError(ctx);
+       *rates = NULL; *groups = NULL;
+
+       if ((err = findStat(ctx, group, major, EDG_WLL_JOB_UNDEF, minor, from, to, &stats))) return err;
+
+       /* remap the file if someone changed its size */
+       if (stats->map->grpno != stats->grpno)
+       {       
+               if (flock(stats->fd,LOCK_EX)) return edg_wll_SetError(ctx,errno,"flock()");
+               if (stats_remap(stats)) {
+                       edg_wll_SetError(ctx,errno,"shmem remap failed");
+                       goto cleanup;
+               }
+       }
+
+       if (flock(stats->fd,LOCK_SH)) return edg_wll_SetError(ctx,errno,"flock()");
+
+       if (strcmp(group->value.c, "ALL")){
+               /* single group */
+               sig = str2md5base64(group->value.c);
+
+               *rates = (float*)malloc(2*sizeof((*rates)[0])); 
+               (*rates)[0] = (*rates)[1] = 0;
+               *groups = (char**)malloc(2*sizeof((*groups)[0])); 
+               (*groups)[0] = (*groups)[1] = NULL;
+
+               for (i=0, g=stats->map; i<stats->grpno; i++) {
+                       if (!strcmp(sig,g->sig)) break;
+                       g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
+               }
+
+               if (i == stats->grpno) {
+                       glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, 
+                               "no match: %s\n",sig);
+                       edg_wll_SetError(ctx,ENOENT,"no matching group");
+                       free(*rates); *rates = NULL;
+                       free(*groups); *groups = NULL;
+                       goto cleanup;
+               }
+
+               if ((err = stateRateRequest(ctx, stats, g, from, to, &((*rates)[0]), res_from, res_to))){
+                       free(*rates);
+                        free(*groups);
+                       goto cleanup;
+               }
+               (*groups)[0] = strdup(g->destination); 
+       }
+       else{
+               /* all groups */
+               *rates = (float*)malloc(stats->grpno * sizeof((*rates)[0]));
+               *groups = (char**)malloc((stats->grpno+1) * sizeof((*groups)[0]));
+               for (i=0, g=stats->map; i<stats->grpno; i++) {
+                       (*rates)[i] = 0;
+                       (*groups)[i] = NULL;
+                       if ((err = stateRateRequest(ctx, stats, g, from, to, &((*rates)[i]), res_from, res_to)))
+                               continue; //TODO in fact breaks results here
+                       (*groups)[i] = strdup(g->destination);
+                       g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
+                }
+               (*groups)[i] = NULL;
+               if (i == 0){
+                       edg_wll_SetError(ctx,ENOENT,"no matching group");
+                        free(*rates); *rates = NULL;
+                        free(*groups); *groups = NULL;
+                        goto cleanup;
+               }
+       }
+
+cleanup:
+        free(sig);
+        flock(stats->fd,LOCK_UN);
+        return edg_wll_Error(ctx,NULL,NULL);
 }
 
 int edg_wll_StateDurationServer(
@@ -599,7 +656,8 @@ int edg_wll_StateDurationServer(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *duration,
+       float   **duration,
+       char    ***groups,
        int     *res_from,
        int     *res_to
 )
@@ -607,61 +665,25 @@ int edg_wll_StateDurationServer(
        return edg_wll_SetError(ctx,ENOSYS,NULL);
 }
 
-int edg_wll_StateDurationFromToServer(
+static int stateDurationFromToRequest(
         edg_wll_Context ctx,
-        const edg_wll_QueryRec  *group,
-        edg_wll_JobStatCode     base_state,
-       edg_wll_JobStatCode     final_state,
-        int                     minor,
+        edg_wll_Stats *stats,
+        struct edg_wll_stats_group    *g,
         time_t  *from,
         time_t  *to,
         float   *duration,
-       float   *dispersion,
+       float   *dispersion,
         int     *res_from,
         int     *res_to
 )
 {
-       edg_wll_Stats *stats = default_stats;   /* XXX: hardcoded */
-        struct edg_wll_stats_group      *g;
-        struct edg_wll_stats_archive    *a;
+       struct edg_wll_stats_archive    *a;
         int     i,j,matchi;
-        char    *sig = NULL;
         time_t  afrom,ato;
         long    match, diff;
-       float   rate;
-       int     err;
+       float   rate;
 
-        edg_wll_ResetError(ctx);
-
-       if ((err = findStat(ctx, group, base_state, final_state, minor, from, to, &stats))) return err;
-
-       /* remap the file if someone changed its size */
-        if (stats->map->grpno != stats->grpno)
-        {       
-                if (flock(stats->fd,LOCK_EX)) return edg_wll_SetError(ctx,errno,"flock()");
-                if (stats_remap(stats)) {
-                        edg_wll_SetError(ctx,errno,"shmem remap failed");
-                        goto cleanup;
-                }
-        }
-
-        if (flock(stats->fd,LOCK_SH)) return edg_wll_SetError(ctx,errno,"flock()");
-
-        /* XXX */
-        sig = str2md5base64(group->value.c);
-
-
-        for (i=0, g=stats->map; i<stats->grpno; i++) {
-                if (!strcmp(sig,g->sig)) break;
-                g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
-        }
-
-        if (i == stats->grpno) {
-                glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG,
-                        "no match: %s\n",sig);
-                edg_wll_SetError(ctx,ENOENT,"no matching group");
-                goto cleanup;
-        }
+       edg_wll_ResetError(ctx);
 
        match = 0;
         matchi = -1;
@@ -684,13 +706,13 @@ int edg_wll_StateDurationFromToServer(
                 }
         }
 
-        glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG,
+         glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG,
                 "best match: archive %d, interval %ld", matchi, match);
 
-       if (matchi < 0) {
+        if (matchi < 0) {
                 if (*from > g->last_update) {
                         /* special case -- we are sure that nothing arrived */
-                       *duration = 0.0f;
+                        *duration = 0.0f;
                         *res_from = *res_to = stats->archives[0].interval;
                         goto cleanup;
                 }
@@ -714,8 +736,8 @@ int edg_wll_StateDurationFromToServer(
         if (afrom + stats->archives[matchi].length * i < *to) *to = afrom + stats->archives[matchi].length * i;
 
         rate = 0.0f;
-       *duration = 0.0f;
-       *dispersion = 0.0f;
+        *duration = 0.0f;
+        *dispersion = 0.0f;
         match = 0;
 
        for (j=0; j<stats->archives[matchi].length; j++,afrom += i) {
@@ -732,42 +754,141 @@ int edg_wll_StateDurationFromToServer(
                 glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG,
                         "search %ld in %ld, %ld", *from, afrom, afrom+i);
 
-               // (from, to) is inside (afrom, afrom+i)
-               if (*from >= afrom && *to < afrom+i) {
-                       printf("branch 1, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);
-                       diff = *to - *from;
-               }
-               // (afrom, afrom+i) is inside (from, to)
-               else if (*from < afrom && *to >= afrom+i) {
-                       printf("branch 2, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);                   
-                       diff = i;
-               }
-               // from is in (afrom, afrom+i)
-               else if (*from >= afrom && *from < afrom+i) {
-                       printf("branch 3, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);
-                       diff = afrom+i - *from;
-               }
-               // to is in (afrom, afrom+i)
-               else if (*to >= afrom && *to < afrom+i) {
-                       printf("branch 4, (%ld %ld), (%ld %ld)\n", *from, *to, afrom, afrom+i);
-                       diff = afrom+i - *to;
+                // (from, to) is inside (afrom, afrom+i)
+                if (*from >= afrom && *to < afrom+i) {
+                        printf("branch 1, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);
+                        diff = *to - *from;
+                }
+                // (afrom, afrom+i) is inside (from, to)
+                else if (*from < afrom && *to >= afrom+i) {
+                        printf("branch 2, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);
+                        diff = i;
+                }
+                // from is in (afrom, afrom+i)
+                else if (*from >= afrom && *from < afrom+i) {
+                        printf("branch 3, (%ld %ld), %ld %ld\n", *from, *to, afrom, afrom+i);
+                        diff = afrom+i - *from;
+                }
+                // to is in (afrom, afrom+i)
+                else if (*to >= afrom && *to < afrom+i) {
+                        printf("branch 4, (%ld %ld), (%ld %ld)\n", *from, *to, afrom, afrom+i);
+                        diff = afrom+i - *to;
+                }
+                printf("diff: %ld\n", diff);
+                match += diff;
+                rate += c->cnt * (float)diff;
+                if (c->cnt)
+                        *duration += (float)diff * c->value/c->cnt;
+                *dispersion += (float)diff * c->value2;
+
+                if (*to >= afrom && *to < afrom+i) {
+                        glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, "matched to: match %d, duration %f, dispersion %f", match, *duration, *dispersion);
+                        break;
+                }
+        }
+        *duration /= match;
+        *dispersion /= match;
+        rate /= match;
+        *dispersion = sqrtf(1/(rate-1) * ((*dispersion) - rate*(*duration)));
+
+cleanup:
+        return edg_wll_Error(ctx,NULL,NULL);
+}
+
+int edg_wll_StateDurationFromToServer(
+        edg_wll_Context ctx,
+        const edg_wll_QueryRec  *group,
+        edg_wll_JobStatCode     base_state,
+       edg_wll_JobStatCode     final_state,
+        int                     minor,
+        time_t  *from,
+        time_t  *to,
+        float   **durations,
+       float   **dispersions,
+       char    ***groups,
+        int     *res_from,
+        int     *res_to
+)
+{
+       edg_wll_Stats *stats = default_stats;   /* XXX: hardcoded */
+        struct edg_wll_stats_group      *g;
+        char    *sig = NULL;
+       int     err;
+       int     i;
+
+        edg_wll_ResetError(ctx);
+       *durations = NULL;
+       *dispersions = NULL;
+       *groups = NULL;
+
+       if ((err = findStat(ctx, group, base_state, final_state, minor, from, to, &stats))) return err;
+
+       /* remap the file if someone changed its size */
+        if (stats->map->grpno != stats->grpno)
+        {       
+                if (flock(stats->fd,LOCK_EX)) return edg_wll_SetError(ctx,errno,"flock()");
+                if (stats_remap(stats)) {
+                        edg_wll_SetError(ctx,errno,"shmem remap failed");
+                        goto cleanup;
+                }
+        }
+
+        if (flock(stats->fd,LOCK_SH)) return edg_wll_SetError(ctx,errno,"flock()");
+
+       if (strcmp(group->value.c, "ALL")){
+               /* single group */
+               sig = str2md5base64(group->value.c);
+               *durations = (float*)malloc(1*sizeof((*durations)[0]));
+                (*durations)[0] = 0;
+               *dispersions = (float*)malloc(1*sizeof((*dispersions)[0]));
+                (*dispersions)[0] = 0;
+               *groups = (char**)malloc(2*sizeof((*groups)[0]));
+                (*groups)[0] = (*groups)[1] = NULL;
+
+               for (i=0, g=stats->map; i<stats->grpno; i++) {
+                       if (!strcmp(sig,g->sig)) break;
+                       g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
+               }
+
+               if (i == stats->grpno) {
+                       glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG,
+                               "no match: %s\n",sig);
+                       edg_wll_SetError(ctx,ENOENT,"no matching group");
+                       goto cleanup;
+               }
+
+               if ((err = stateDurationFromToRequest(ctx, stats, g, from, to, &((*durations)[0]), &((*dispersions)[0]), res_from, res_to))){
+                       free(*durations);
+                       free(*dispersions);
+                       free(*groups);
+                       goto cleanup;
                }
-               printf("diff: %ld\n", diff);
-               match += diff;
-               rate += c->cnt * (float)diff;
-               if (c->cnt)
-                       *duration += (float)diff * c->value/c->cnt;
-               *dispersion += (float)diff * c->value2;
-
-               if (*to >= afrom && *to < afrom+i) { 
-                       glite_common_log(LOG_CATEGORY_LB_SERVER, LOG_PRIORITY_DEBUG, "matched to: match %d, duration %f, dispersion %f", match, *duration, *dispersion);
-                       break;
+               (*groups)[0] = strdup(g->destination);
+       }
+       else{
+               /* all groups */
+               *durations = (float*)malloc(stats->grpno * sizeof((*durations)[0]));
+               *dispersions = (float*)malloc(stats->grpno * sizeof((*dispersions)[0]));
+               *groups = (char**)malloc((stats->grpno+1) * sizeof((*groups)[0]));
+
+               for (i=0, g=stats->map; i<stats->grpno; i++) {
+                       (*durations)[i] = 0;
+                       (*dispersions)[i] = 0;
+                       (*groups)[i] = NULL;
+                       if ((err = stateDurationFromToRequest(ctx, stats, g, from, to, &((*durations)[i]), &((*dispersions)[i]), res_from, res_to)))
+                               continue; //TODO in fact breaks results here
+                       (*groups)[i] = strdup(g->destination);
+                       g = (struct edg_wll_stats_group *) (((char *) g) + stats->grpsize);
                }
-        }
-       *duration /= match;
-       *dispersion /= match;
-       rate /= match;
-       *dispersion = sqrtf(1/(rate-1) * ((*dispersion) - rate*(*duration)));
+               (*groups)[i] = NULL;
+                if (i == 0){
+                        edg_wll_SetError(ctx,ENOENT,"no matching group");
+                        free(*durations); *durations = NULL;
+                       free(*dispersions); *dispersions = NULL;
+                        free(*groups); *groups = NULL;
+                        goto cleanup;
+                }
+       }
 
 cleanup:
        free(sig);
index 7468e15..01863de 100644 (file)
@@ -48,6 +48,7 @@ struct edg_wll_stats_archive {
 struct edg_wll_stats_group {
        int     grpno;
        char    sig[33];
+       char    *destination;
        time_t  last_update;
        struct edg_wll_stats_archive    archive[1];
 };
@@ -75,7 +76,8 @@ int edg_wll_StateRateServer(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *rate,
+       float   **rates,
+       char    ***groups,
        int     *res_from,
        int     *res_to
 );
@@ -88,7 +90,8 @@ int edg_wll_StateDurationServer(
        int                     minor,
        time_t  *from, 
        time_t  *to,
-       float   *duration,
+       float   **duration,
+       char    ***groups,
        int     *res_from,
        int     *res_to
 );
@@ -101,8 +104,9 @@ int edg_wll_StateDurationFromToServer(
         int                     minor,
         time_t  *from,
         time_t  *to,
-        float   *duration,
-       float   *dispersion,
+        float   **duration,
+       float   **dispersion,
+       char    ***groups,
         int     *res_from,
         int     *res_to
 );