diff --git a/pool/page_shifts.php b/pool/page_shifts.php index b83d3ec6..7627c0a3 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -14,10 +14,13 @@ function doshifts($data, $user) $pg .= "Shares"; $pg .= "Avg Share"; $pg .= "\n"; - if ($ans['STATUS'] != 'ok') + + if (($ans['STATUS'] != 'ok') || !isset($ans['prefix_all'])) $pg = '

Shifts

'.$pg; else { + $pre = $ans['prefix_all']; + $count = $ans['rows']; $pg = '

Last '.($count+1).' Shifts

'.$pg; for ($i = 0; $i < $count; $i++) @@ -49,11 +52,11 @@ function doshifts($data, $user) $nd = $ans['end:'.$i]; $elapsed = $nd - $start; $pg .= ''.howmanyhrs($elapsed).''; - $diffacc = $ans['diffacc:'.$i]; + $diffacc = $ans[$pre.'diffacc:'.$i]; $pg .= ''.difffmt($diffacc).''; $hr = $diffacc * pow(2,32) / $elapsed; $pg .= ''.dsprate($hr).''; - $shareacc = $ans['shareacc:'.$i]; + $shareacc = $ans[$pre.'shareacc:'.$i]; $pg .= ''.difffmt($shareacc).''; if ($shareacc > 0) $avgsh = $diffacc / $shareacc; diff --git a/pool/page_usperf.php b/pool/page_usperf.php index ed903428..5edd947c 100644 --- a/pool/page_usperf.php +++ b/pool/page_usperf.php @@ -4,8 +4,8 @@ function uspg() { $g = "function gdrw(c,d,cbx){gc(c);ghrs(c);gopt(c,cbx); gfs(c,'white');gss(c,'#0000c0');glw(c,2);gbd(c); -var rows=d['rows'],ymin=-1,ymax=0,xmin=-1,xmax=0,tda=0; -for(var i=0;iths){ymin=ths}if(ths>ymax)ymax=ths;d['nx:'+i]=sn(i,d['shift:'+i]);if(xmin==-1||xmin>s){xmin=s}if(xmaxths){ymin=ths}if(ths>ymax)ymax=ths;d['nx:'+i]=sn(i,d['shift:'+i]);if(xmin==-1||xmin>s){xmin=s}if(xmax trg @@ -839,6 +845,16 @@ extern K_STORE *workers_store; #define IDLENOTIFICATIONTIME_DEF 0 #define IDLENOTIFICATIONTIME_DEF_STR STRINT(IDLENOTIFICATIONTIME_DEF) +#define WORKERS_SEL_SEP ',' +#define WORKERS_SEL_SEP_STR "," +/* There are 2 special select workernames + * A DB workername can't accidentally match them + * when including the WORKSEPx at the front of the workername, + * since these 2 don't start with WORKSEP1 or WORKSEP2 */ +#define WORKERS_ALL "all" +// Empty has a value rather than "", so that "" means nothing selected +#define WORKERS_EMPTY "noname" + // PAYMENTADDRESSES typedef struct paymentaddresses { int64_t paymentaddressid; diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index c171f4f3..1da701e3 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -4679,13 +4679,96 @@ static char *cmd_mpayouts(__maybe_unused PGconn *conn, char *cmd, char *id, return buf; } +/* Find the offset, in list, of the workername + * -1 means NULL list, empty list or not found */ +static int worker_offset(char **list, char *workername) +{ + char *c1, *c2; + int i; + + if (!list || !(*list)) + return -1; + + /* Find the start of the workername including the SEP */ + c1 = strchr(workername, WORKSEP1); + c2 = strchr(workername, WORKSEP2); + if (c1 || c2) { + if (!c1 || (c1 && c2 && (c2 < c1))) + c1 = c2; + } + // No workername after the username + if (!c1) + c1 = WORKERS_EMPTY; + for (i = 0; list[i]; i++) { + if (strcmp(c1, list[i]) == 0) + return i; + } + return -1; +} + +/* Some arbitrarily large limit, increase it if needed + (doesn't need to be very large) */ +#define SELECT_LIMIT 63 + +/* select is a string of workernames separated by WORKERS_SEL_SEP + * Return an array of strings of select broken up + * The array is terminated by NULL + * and will have 0 elements if select is NULL/empty + * The count of the first occurrence of WORKERS_ALL is returned in *all_count, + * or -1 if WORKERS_ALL isn't found */ +static char **select_list(char *select, int *all_count) +{ + size_t len, offset, siz; + char **list = NULL; + int count; + char *end; + + *all_count = -1; + + siz = sizeof(char *) * (SELECT_LIMIT + 1); + list = malloc(siz); + if (!list) + quithere(1, "malloc (%d) OOM", (int)siz); + list[0] = NULL; + + if (select == NULL || *select == '\0') + return list; + + len = strlen(select); + count = 0; + offset = 0; + while (offset < len) { + if (select[offset] == WORKERS_SEL_SEP) + offset++; + else { + list[count] = select + offset; + list[count+1] = NULL; + end = strchr(list[count], WORKERS_SEL_SEP); + if (end != NULL) { + offset = 1 + end - select; + *end = '\0'; + } + + if (*all_count == -1 && + strcasecmp(list[count], WORKERS_ALL) == 0) { + *all_count = count; + } + + if (end == NULL || ++count > SELECT_LIMIT) + break; + } + } + return list; +} + static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, __maybe_unused tv_t *now, __maybe_unused char *by, __maybe_unused char *code, __maybe_unused char *inet, __maybe_unused tv_t *notcd, __maybe_unused K_TREE *trf_root) { - K_ITEM *i_username, *u_item, *m_item, ms_look, *wm_item, *ms_item, *wi_item; + K_ITEM *i_username, *i_select; + K_ITEM *u_item, *m_item, ms_look, *wm_item, *ms_item, *wi_item; K_TREE_CTX wm_ctx[1], ms_ctx[1]; WORKMARKERS *wm; WORKINFO *wi; @@ -4695,10 +4778,13 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, char reply[1024] = ""; char tmp[1024]; size_t siz = sizeof(reply); + char *select = NULL; + char **selects = NULL; + bool used[SELECT_LIMIT]; char *buf; size_t len, off; tv_t marker_end = { 0L, 0L }; - int rows; + int rows, want, i, where_all; LOGDEBUG("%s(): cmd '%s'", __func__, cmd); @@ -4713,6 +4799,21 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, return strdup("bad"); DATA_USERS(users, u_item); + i_select = optional_name(trf_root, "select", 1, NULL, reply, siz); + if (i_select) + select = strdup(transfer_data(i_select)); + + selects = select_list(select, &where_all); + // Nothing selected = all + if (*selects == NULL) { + where_all = 0; + selects[0] = WORKERS_ALL; + selects[1] = NULL; + } + + if (where_all >= 0) + used[where_all] = true; + APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC(buf, off, len, "ok."); INIT_MARKERSUMMARY(&ms_look); @@ -4756,6 +4857,30 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, ms_add.shareacc += ms->shareacc; ms_add.sharerej += ms->sharerej; + want = worker_offset(selects, ms->workername); + if (want >= 0) { + used[want] = true; + double_to_buf(ms->diffacc, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_diffacc:%d=%s%c", + want, rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + double_to_buf(ms->diffrej, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_diffrej:%d=%s%c", + want, rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + double_to_buf(ms->shareacc, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_shareacc:%d=%s%c", + want, rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + double_to_buf(ms->sharerej, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_sharerej:%d=%s%c", + want, rows, reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } + ms_item = next_in_ktree(ms_ctx); DATA_MARKERSUMMARY_NULL(ms, ms_item); } @@ -4775,7 +4900,9 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, wm->description, wm->workinfoidend); snprintf(reply, siz, "data error 1"); - return strdup(reply); + free(buf); + free(selects); + return(strdup(reply)); } DATA_WORKINFO(wi, wi_item); copy_tv(&marker_end, &(wi->createdate)); @@ -4794,13 +4921,15 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, __func__, wm->markerid, wm->description, wm->workinfoidstart); snprintf(reply, siz, "data error 2"); - return strdup(reply); + free(buf); + free(selects); + return(strdup(reply)); } DATA_WORKINFO(wi, wi_item); bigint_to_buf(wm->markerid, reply, sizeof(reply)); snprintf(tmp, sizeof(tmp), "markerid:%d=%s%c", - rows, reply, FLDSEP); + rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); str_to_buf(wm->description, reply, sizeof(reply)); @@ -4824,27 +4953,33 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, rows, reply, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); - double_to_buf(ms_add.diffacc, reply, sizeof(reply)); - snprintf(tmp, sizeof(tmp), "diffacc:%d=%s%c", - rows, reply, FLDSEP); - APPEND_REALLOC(buf, off, len, tmp); + if (where_all >= 0) { + double_to_buf(ms_add.diffacc, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_diffacc:%d=%s%c", + where_all, rows, + reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); - double_to_buf(ms_add.diffrej, reply, sizeof(reply)); - snprintf(tmp, sizeof(tmp), "diffrej:%d=%s%c", - rows, reply, FLDSEP); - APPEND_REALLOC(buf, off, len, tmp); + double_to_buf(ms_add.diffrej, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_diffrej:%d=%s%c", + where_all, rows, + reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); - double_to_buf(ms_add.shareacc, reply, sizeof(reply)); - snprintf(tmp, sizeof(tmp), "shareacc:%d=%s%c", - rows, reply, FLDSEP); - APPEND_REALLOC(buf, off, len, tmp); + double_to_buf(ms_add.shareacc, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_shareacc:%d=%s%c", + where_all, rows, + reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); - double_to_buf(ms_add.sharerej, reply, sizeof(reply)); - snprintf(tmp, sizeof(tmp), "sharerej:%d=%s%c", - rows, reply, FLDSEP); - APPEND_REALLOC(buf, off, len, tmp); + double_to_buf(ms_add.sharerej, reply, sizeof(reply)); + snprintf(tmp, sizeof(tmp), "%d_sharerej:%d=%s%c", + where_all, rows, + reply, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); - rows++; + rows++; + } // Setup for next shift copy_tv(&marker_end, &(wi->createdate)); @@ -4856,17 +4991,55 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, } K_RUNLOCK(workmarkers_free); + for (i = 0; selects[i]; i++) { + if (used[i]) { + snprintf(tmp, sizeof(tmp), + "%d_worker=%s%c", + i, selects[i], FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), + "%d_flds=%s%c", i, + "diffacc,diffrej,shareacc,sharerej", FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } + } + + // Missing if all isn't selected + if (where_all >= 0) { + snprintf(tmp, sizeof(tmp), "prefix_all=%d_%c", + where_all, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + } + + /* rows is an upper limit of rows in each worker + * 'all' starts at 0 and finishes at rows-1 + * other workers start >= 0 and finish <= rows-1 */ snprintf(tmp, sizeof(tmp), "rows=%d%cflds=%s%c", - rows, FLDSEP, - "markerid,shift,start,end,diffacc,diffrej,shareacc,sharerej", - FLDSEP); + rows, FLDSEP, + "markerid,shift,start,end", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); - snprintf(tmp, sizeof(tmp), "arn=%s%carp=%s", "Shifts", FLDSEP, ""); + snprintf(tmp, sizeof(tmp), "arn=%s", "Shifts"); APPEND_REALLOC(buf, off, len, tmp); + for (i = 0; selects[i]; i++) { + if (used[i]) { + snprintf(tmp, sizeof(tmp), ",Worker_%d", i); + APPEND_REALLOC(buf, off, len, tmp); + } + } + + snprintf(tmp, sizeof(tmp), "%carp=", FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + for (i = 0; selects[i]; i++) { + if (used[i]) { + snprintf(tmp, sizeof(tmp), ",%d_", i); + APPEND_REALLOC(buf, off, len, tmp); + } + } LOGDEBUG("%s.ok.%s", id, transfer_data(i_username)); - return buf; + free(selects); + return(buf); } static char *cmd_dsp(__maybe_unused PGconn *conn, __maybe_unused char *cmd,