From c3cbef6eca51207ff08f461a1b5a25c2e6cfb157 Mon Sep 17 00:00:00 2001 From: kanoi Date: Mon, 14 Sep 2015 21:16:14 +1000 Subject: [PATCH 01/10] ckdb - make a separate object for a ktree vs the tree nodes --- src/ckdb.c | 120 +++++++------ src/ckdb.h | 2 +- src/ckdb_cmd.c | 35 ++-- src/ckdb_data.c | 140 +++++++-------- src/ckdb_dbio.c | 311 ++++++++++++++------------------- src/ktree.c | 453 ++++++++++++++++++++++++++---------------------- src/ktree.h | 65 ++++--- 7 files changed, 553 insertions(+), 573 deletions(-) diff --git a/src/ckdb.c b/src/ckdb.c index 935c8aa6..154916f5 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -999,43 +999,43 @@ static void alloc_storage() users_free = k_new_list("Users", sizeof(USERS), ALLOC_USERS, LIMIT_USERS, true); users_store = k_new_store(users_free); - users_root = new_ktree(); - userid_root = new_ktree(); + users_root = new_ktree(cmp_users); + userid_root = new_ktree(cmp_userid); useratts_free = k_new_list("Useratts", sizeof(USERATTS), ALLOC_USERATTS, LIMIT_USERATTS, true); useratts_store = k_new_store(useratts_free); - useratts_root = new_ktree(); + useratts_root = new_ktree(cmp_useratts); optioncontrol_free = k_new_list("OptionControl", sizeof(OPTIONCONTROL), ALLOC_OPTIONCONTROL, LIMIT_OPTIONCONTROL, true); optioncontrol_store = k_new_store(optioncontrol_free); - optioncontrol_root = new_ktree(); + optioncontrol_root = new_ktree(cmp_optioncontrol); workers_free = k_new_list("Workers", sizeof(WORKERS), ALLOC_WORKERS, LIMIT_WORKERS, true); workers_store = k_new_store(workers_free); - workers_root = new_ktree(); + workers_root = new_ktree(cmp_workers); paymentaddresses_free = k_new_list("PaymentAddresses", sizeof(PAYMENTADDRESSES), ALLOC_PAYMENTADDRESSES, LIMIT_PAYMENTADDRESSES, true); paymentaddresses_store = k_new_store(paymentaddresses_free); - paymentaddresses_root = new_ktree(); - paymentaddresses_create_root = new_ktree(); + paymentaddresses_root = new_ktree(cmp_paymentaddresses); + paymentaddresses_create_root = new_ktree(cmp_payaddr_create); paymentaddresses_free->dsp_func = dsp_paymentaddresses; payments_free = k_new_list("Payments", sizeof(PAYMENTS), ALLOC_PAYMENTS, LIMIT_PAYMENTS, true); payments_store = k_new_store(payments_free); - payments_root = new_ktree(); + payments_root = new_ktree(cmp_payments); accountbalance_free = k_new_list("AccountBalance", sizeof(ACCOUNTBALANCE), ALLOC_ACCOUNTBALANCE, LIMIT_ACCOUNTBALANCE, true); accountbalance_store = k_new_store(accountbalance_free); - accountbalance_root = new_ktree(); + accountbalance_root = new_ktree(cmp_accountbalance); idcontrol_free = k_new_list("IDControl", sizeof(IDCONTROL), ALLOC_IDCONTROL, LIMIT_IDCONTROL, true); @@ -1044,98 +1044,98 @@ static void alloc_storage() workinfo_free = k_new_list("WorkInfo", sizeof(WORKINFO), ALLOC_WORKINFO, LIMIT_WORKINFO, true); workinfo_store = k_new_store(workinfo_free); - workinfo_root = new_ktree(); + workinfo_root = new_ktree(cmp_workinfo); if (!confirm_sharesummary) - workinfo_height_root = new_ktree(); + workinfo_height_root = new_ktree(cmp_workinfo_height); shares_free = k_new_list("Shares", sizeof(SHARES), ALLOC_SHARES, LIMIT_SHARES, true); shares_store = k_new_store(shares_free); shares_early_store = k_new_store(shares_free); - shares_root = new_ktree(); - shares_early_root = new_ktree(); + shares_root = new_ktree(cmp_shares); + shares_early_root = new_ktree(cmp_shares); shareerrors_free = k_new_list("ShareErrors", sizeof(SHAREERRORS), ALLOC_SHAREERRORS, LIMIT_SHAREERRORS, true); shareerrors_store = k_new_store(shareerrors_free); shareerrors_early_store = k_new_store(shareerrors_free); - shareerrors_root = new_ktree(); - shareerrors_early_root = new_ktree(); + shareerrors_root = new_ktree(cmp_shareerrors); + shareerrors_early_root = new_ktree(cmp_shareerrors); sharesummary_free = k_new_list("ShareSummary", sizeof(SHARESUMMARY), ALLOC_SHARESUMMARY, LIMIT_SHARESUMMARY, true); sharesummary_store = k_new_store(sharesummary_free); - sharesummary_root = new_ktree(); - sharesummary_workinfoid_root = new_ktree(); + sharesummary_root = new_ktree(cmp_sharesummary); + sharesummary_workinfoid_root = new_ktree(cmp_sharesummary_workinfoid); sharesummary_free->dsp_func = dsp_sharesummary; sharesummary_pool_store = k_new_store(sharesummary_free); - sharesummary_pool_root = new_ktree(); + sharesummary_pool_root = new_ktree(cmp_sharesummary); blocks_free = k_new_list("Blocks", sizeof(BLOCKS), ALLOC_BLOCKS, LIMIT_BLOCKS, true); blocks_store = k_new_store(blocks_free); - blocks_root = new_ktree(); + blocks_root = new_ktree(cmp_blocks); blocks_free->dsp_func = dsp_blocks; miningpayouts_free = k_new_list("MiningPayouts", sizeof(MININGPAYOUTS), ALLOC_MININGPAYOUTS, LIMIT_MININGPAYOUTS, true); miningpayouts_store = k_new_store(miningpayouts_free); - miningpayouts_root = new_ktree(); + miningpayouts_root = new_ktree(cmp_miningpayouts); payouts_free = k_new_list("Payouts", sizeof(PAYOUTS), ALLOC_PAYOUTS, LIMIT_PAYOUTS, true); payouts_store = k_new_store(payouts_free); - payouts_root = new_ktree(); - payouts_id_root = new_ktree(); - payouts_wid_root = new_ktree(); + payouts_root = new_ktree(cmp_payouts); + payouts_id_root = new_ktree(cmp_payouts_id); + payouts_wid_root = new_ktree(cmp_payouts_wid); auths_free = k_new_list("Auths", sizeof(AUTHS), ALLOC_AUTHS, LIMIT_AUTHS, true); auths_store = k_new_store(auths_free); - auths_root = new_ktree(); + auths_root = new_ktree(cmp_auths); poolstats_free = k_new_list("PoolStats", sizeof(POOLSTATS), ALLOC_POOLSTATS, LIMIT_POOLSTATS, true); poolstats_store = k_new_store(poolstats_free); - poolstats_root = new_ktree(); + poolstats_root = new_ktree(cmp_poolstats); userstats_free = k_new_list("UserStats", sizeof(USERSTATS), ALLOC_USERSTATS, LIMIT_USERSTATS, true); userstats_store = k_new_store(userstats_free); userstats_eos_store = k_new_store(userstats_free); - userstats_root = new_ktree(); + userstats_root = new_ktree(cmp_userstats); userstats_free->dsp_func = dsp_userstats; workerstatus_free = k_new_list("WorkerStatus", sizeof(WORKERSTATUS), ALLOC_WORKERSTATUS, LIMIT_WORKERSTATUS, true); workerstatus_store = k_new_store(workerstatus_free); - workerstatus_root = new_ktree(); + workerstatus_root = new_ktree(cmp_workerstatus); markersummary_free = k_new_list("MarkerSummary", sizeof(MARKERSUMMARY), ALLOC_MARKERSUMMARY, LIMIT_MARKERSUMMARY, true); markersummary_store = k_new_store(markersummary_free); - markersummary_root = new_ktree(); - markersummary_userid_root = new_ktree(); + markersummary_root = new_ktree(cmp_markersummary); + markersummary_userid_root = new_ktree(cmp_markersummary_userid); markersummary_free->dsp_func = dsp_markersummary; markersummary_pool_store = k_new_store(markersummary_free); - markersummary_pool_root = new_ktree(); + markersummary_pool_root = new_ktree(cmp_markersummary); workmarkers_free = k_new_list("WorkMarkers", sizeof(WORKMARKERS), ALLOC_WORKMARKERS, LIMIT_WORKMARKERS, true); workmarkers_store = k_new_store(workmarkers_free); - workmarkers_root = new_ktree(); - workmarkers_workinfoid_root = new_ktree(); + workmarkers_root = new_ktree(cmp_workmarkers); + workmarkers_workinfoid_root = new_ktree(cmp_workmarkers_workinfoid); workmarkers_free->dsp_func = dsp_workmarkers; marks_free = k_new_list("Marks", sizeof(MARKS), ALLOC_MARKS, LIMIT_MARKS, true); marks_store = k_new_store(marks_free); - marks_root = new_ktree(); + marks_root = new_ktree(cmp_marks); userinfo_free = k_new_list("UserInfo", sizeof(USERINFO), ALLOC_USERINFO, LIMIT_USERINFO, true); userinfo_store = k_new_store(userinfo_free); - userinfo_root = new_ktree(); + userinfo_root = new_ktree(cmp_userinfo); } #define SEQSETMSG(_set, _seqset, _msgtxt, _endtxt) do { \ @@ -1179,7 +1179,7 @@ static void alloc_storage() #define FREE_TREE(_tree) \ if (_tree ## _root) \ - _tree ## _root = free_ktree(_tree ## _root, NULL) \ + free_ktree(_tree ## _root, NULL) \ #define FREE_STORE(_list) \ if (_list ## _store) \ @@ -1487,13 +1487,13 @@ static bool setup_data() INIT_WORKINFO(&look); look.data = (void *)(&wi); // Find the first workinfo for this height - found = find_after_in_ktree(workinfo_height_root, &look, cmp_workinfo_height, ctx); + found = find_after_in_ktree(workinfo_height_root, &look, ctx); if (found) { DATA_WORKINFO(wif, found); copy_tv(&last_bc, &(wif->createdate)); } // No longer needed - workinfo_height_root = free_ktree(workinfo_height_root, NULL); + free_ktree(workinfo_height_root, NULL); } return true; @@ -2536,7 +2536,7 @@ static enum cmd_values breakdown(K_ITEM **ml_item, char *buf, tv_t *now, goto nogood; } - msgline->trf_root = new_ktree(); + msgline->trf_root = new_ktree(cmp_transfer); msgline->trf_store = k_new_store(transfer_free); next = data; if (next && strncmp(next, JSON_TRANSFER, JSON_TRANSFER_LEN) == 0) { @@ -2688,8 +2688,7 @@ static enum cmd_values breakdown(K_ITEM **ml_item, char *buf, tv_t *now, STRNCPYSIZ(transfer->svalue, next, siz+1); transfer->mvalue = transfer->svalue; } - msgline->trf_root = add_to_ktree(msgline->trf_root, - t_item, cmp_transfer); + add_to_ktree(msgline->trf_root, t_item); k_add_head(msgline->trf_store, t_item); t_item = NULL; @@ -2732,15 +2731,12 @@ static enum cmd_values breakdown(K_ITEM **ml_item, char *buf, tv_t *now, transfer->mvalue = transfer->svalue; // Discard duplicates - if (find_in_ktree(msgline->trf_root, t_item, - cmp_transfer, ctx)) { + if (find_in_ktree(msgline->trf_root, t_item, ctx)) { if (transfer->mvalue != transfer->svalue) FREENULL(transfer->mvalue); k_add_head(transfer_free, t_item); } else { - msgline->trf_root = add_to_ktree(msgline->trf_root, - t_item, - cmp_transfer); + add_to_ktree(msgline->trf_root, t_item); k_add_head(msgline->trf_store, t_item); } } @@ -2935,7 +2931,7 @@ static void summarise_blocks() K_RLOCK(markersummary_free); ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, - cmp_sharesummary_workinfoid, ss_ctx); + ss_ctx); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); while (ss_item && sharesummary->workinfoid > wi_start) { if (sharesummary->complete[0] == SUMMARY_NEW) { @@ -2971,7 +2967,7 @@ static void summarise_blocks() INIT_WORKMARKERS(&wm_look); wm_look.data = (void *)(&lookworkmarkers); wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, - cmp_workmarkers_workinfoid, ctx); + ctx); DATA_WORKMARKERS_NULL(workmarkers, wm_item); while (wm_item && CURRENT(&(workmarkers->expirydate)) && @@ -2995,7 +2991,7 @@ static void summarise_blocks() INIT_MARKERSUMMARY(&ms_look); ms_look.data = (void *)(&lookmarkersummary); ms_item = find_before_in_ktree(markersummary_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_ctx); DATA_MARKERSUMMARY_NULL(markersummary, ms_item); while (ms_item && markersummary->markerid == workmarkers->markerid) { has_ms = true; @@ -3350,7 +3346,7 @@ static void make_a_shift_mark() lookworkinfo.expirydate.tv_usec = default_expiry.tv_usec; wi_look.data = (void *)(&lookworkinfo); K_RLOCK(workinfo_free); - wi_item = find_after_in_ktree(workinfo_root, &wi_look, cmp_workinfo, wi_ctx); + wi_item = find_after_in_ktree(workinfo_root, &wi_look, wi_ctx); K_RUNLOCK(workinfo_free); marks_wid = 0; used_wid = 0; @@ -3394,8 +3390,8 @@ static void make_a_shift_mark() looksharesummary.workername = EMPTY; ss_look.data = (void *)(&looksharesummary); K_RLOCK(sharesummary_free); - ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, - cmp_sharesummary_workinfoid, ss_ctx); + ss_item = find_before_in_ktree(sharesummary_workinfoid_root, + &ss_look, ss_ctx); K_RUNLOCK(sharesummary_free); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); if (ss_item && @@ -4815,7 +4811,7 @@ static void compare_summaries(K_TREE *leftsum, char *leftname, look.data = (void *)(&looksharesummary); total = ok = missing = diff = 0; - lss = find_after_in_ktree(leftsum, &look, cmp_sharesummary_workinfoid, ctxl); + lss = find_after_in_ktree(leftsum, &look, ctxl); while (lss) { DATA_SHARESUMMARY(l_ss, lss); if (l_ss->workinfoid > confirm_last_workinfoid) @@ -4827,7 +4823,7 @@ static void compare_summaries(K_TREE *leftsum, char *leftname, first_used = l_ss->workinfoid; last_used = l_ss->workinfoid; - rss = find_in_ktree(rightsum, lss, cmp_sharesummary_workinfoid, ctxr); + rss = find_in_ktree(rightsum, lss, ctxr); DATA_SHARESUMMARY_NULL(r_ss, rss); if (!rss) { missing++; @@ -5036,7 +5032,7 @@ static void confirm_reload() lookblocks.height = confirm_block; lookblocks.blockhash[0] = '\0'; b_look.data = (void *)(&lookblocks); - b_end_item = find_after_in_ktree(blocks_root, &b_look, cmp_blocks, ctx); + b_end_item = find_after_in_ktree(blocks_root, &b_look, ctx); if (!b_end_item) { LOGWARNING("%s(): no DB block height found matching or after %d", __func__, confirm_block); @@ -5049,7 +5045,7 @@ static void confirm_reload() lookblocks.height = e_blocks->height; lookblocks.blockhash[0] = '\0'; b_look.data = (void *)(&lookblocks); - b_begin_item = find_before_in_ktree(blocks_root, &b_look, cmp_blocks, ctx); + b_begin_item = find_before_in_ktree(blocks_root, &b_look, ctx); if (!b_begin_item) confirm_first_workinfoid = 0; else { @@ -5058,7 +5054,7 @@ static void confirm_reload() lookblocks.height = b_blocks->height; lookblocks.blockhash[0] = '\0'; b_look.data = (void *)(&lookblocks); - b_begin_item = find_after_in_ktree(blocks_root, &b_look, cmp_blocks, ctx); + b_begin_item = find_after_in_ktree(blocks_root, &b_look, ctx); // Not possible if (!b_begin_item) confirm_first_workinfoid = 0; @@ -5110,7 +5106,7 @@ static void confirm_reload() lookworkinfo.expirydate.tv_sec = date_begin.tv_sec; lookworkinfo.expirydate.tv_usec = date_begin.tv_usec; wi_look.data = (void *)(&lookworkinfo); - wi_item = find_before_in_ktree(workinfo_root, &wi_look, cmp_workinfo, ctx); + wi_item = find_before_in_ktree(workinfo_root, &wi_look, ctx); if (wi_item) { DATA_WORKINFO(workinfo, wi_item); copy_tv(&start, &(workinfo->createdate)); @@ -5138,7 +5134,7 @@ static void confirm_reload() lookworkinfo.expirydate.tv_sec = date_eot.tv_sec; lookworkinfo.expirydate.tv_usec = date_eot.tv_usec; wi_look.data = (void *)(&lookworkinfo); - wi_item = find_after_in_ktree(workinfo_root, &wi_look, cmp_workinfo, ctx); + wi_item = find_after_in_ktree(workinfo_root, &wi_look, ctx); if (wi_item) { DATA_WORKINFO(workinfo, wi_item); /* Now find the one after the one we found to determine the @@ -5147,7 +5143,7 @@ static void confirm_reload() lookworkinfo.expirydate.tv_sec = date_eot.tv_sec; lookworkinfo.expirydate.tv_usec = date_eot.tv_usec; wi_look.data = (void *)(&lookworkinfo); - wi_item = find_after_in_ktree(workinfo_root, &wi_look, cmp_workinfo, ctx); + wi_item = find_after_in_ktree(workinfo_root, &wi_look, ctx); if (wi_item) { DATA_WORKINFO(workinfo, wi_item); copy_tv(&confirm_finish, &(workinfo->createdate)); @@ -5178,9 +5174,9 @@ static void confirm_reload() sharesummary_save = sharesummary_root; workinfo_save = workinfo_root; - sharesummary_workinfoid_root = new_ktree(); - sharesummary_root = new_ktree(); - workinfo_root = new_ktree(); + sharesummary_workinfoid_root = new_ktree(cmp_sharesummary_workinfoid); + sharesummary_root = new_ktree(cmp_sharesummary); + workinfo_root = new_ktree(cmp_workinfo); if (start.tv_sec < DATE_BEGIN) { start.tv_sec = DATE_BEGIN; diff --git a/src/ckdb.h b/src/ckdb.h index af0ff79e..cefe3dbe 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.241" +#define CKDB_VERSION DB_VERSION"-1.300" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index f4911289..0e1c23e7 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -926,7 +926,7 @@ static char *cmd_poolstats_do(PGconn *conn, char *cmd, char *id, char *by, row.createdate.tv_usec = date_eot.tv_usec; INIT_POOLSTATS(&look); look.data = (void *)(&row); - ps = find_before_in_ktree(poolstats_root, &look, cmp_poolstats, ctx); + ps = find_before_in_ktree(poolstats_root, &look, ctx); if (!ps) store = true; else { @@ -1730,7 +1730,7 @@ static char *cmd_percent(char *cmd, char *id, tv_t *now, USERS *users) lookworkers.workername[0] = '\0'; DATE_ZERO(&(lookworkers.expirydate)); w_look.data = (void *)(&lookworkers); - w_item = find_after_in_ktree(workers_root, &w_look, cmp_workers, w_ctx); + w_item = find_after_in_ktree(workers_root, &w_look, w_ctx); DATA_WORKERS_NULL(workers, w_item); while (w_item && workers->userid == users->userid) { if (CURRENT(&(workers->expirydate))) { @@ -1991,7 +1991,7 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id, lookworkers.workername[0] = '\0'; DATE_ZERO(&(lookworkers.expirydate)); w_look.data = (void *)(&lookworkers); - w_item = find_after_in_ktree(workers_root, &w_look, cmp_workers, w_ctx); + w_item = find_after_in_ktree(workers_root, &w_look, w_ctx); DATA_WORKERS_NULL(workers, w_item); rows = 0; while (w_item && workers->userid == users->userid) { @@ -3285,7 +3285,7 @@ static char *cmd_homepage(__maybe_unused PGconn *conn, char *cmd, char *id, INIT_USERSTATS(&look); look.data = (void *)(&lookuserstats); K_RLOCK(userstats_free); - us_item = find_before_in_ktree(userstats_root, &look, cmp_userstats, ctx); + us_item = find_before_in_ktree(userstats_root, &look, ctx); DATA_USERSTATS_NULL(userstats, us_item); while (us_item && userstats->userid == users->userid) { if (tvdiff(now, &(userstats->statsdate)) < USERSTATS_PER_S) { @@ -4045,7 +4045,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, INIT_BLOCKS(&b_look); b_look.data = (void *)(&lookblocks); K_RLOCK(blocks_free); - b_item = find_before_in_ktree(blocks_root, &b_look, cmp_blocks, ctx); + b_item = find_before_in_ktree(blocks_root, &b_look, ctx); if (!b_item) { K_RUNLOCK(blocks_free); snprintf(reply, siz, "ERR.no block height %d", height); @@ -4120,7 +4120,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, ss_count = wm_count = ms_count = 0; mu_store = k_new_store(miningpayouts_free); - mu_root = new_ktree(); + mu_root = new_ktree(cmp_mu); looksharesummary.workinfoid = block_workinfoid; looksharesummary.userid = MAXID; @@ -4130,8 +4130,8 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, K_RLOCK(sharesummary_free); K_RLOCK(workmarkers_free); K_RLOCK(markersummary_free); - ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, - cmp_sharesummary_workinfoid, ctx); + ss_item = find_before_in_ktree(sharesummary_workinfoid_root, + &ss_look, ctx); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); if (ss_item) end_workinfoid = sharesummary->workinfoid; @@ -4204,8 +4204,8 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, lookworkmarkers.workinfoidend = block_workinfoid + 1; INIT_WORKMARKERS(&wm_look); wm_look.data = (void *)(&lookworkmarkers); - wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, - cmp_workmarkers_workinfoid, wm_ctx); + wm_item = find_before_in_ktree(workmarkers_workinfoid_root, + &wm_look, wm_ctx); DATA_WORKMARKERS_NULL(workmarkers, wm_item); LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend); while (total_diff < diff_want && wm_item && CURRENT(&(workmarkers->expirydate))) { @@ -4220,8 +4220,8 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, lookmarkersummary.workername = EMPTY; INIT_MARKERSUMMARY(&ms_look); ms_look.data = (void *)(&lookmarkersummary); - ms_item = find_before_in_ktree(markersummary_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_item = find_before_in_ktree(markersummary_root, + &ms_look, ms_ctx); DATA_MARKERSUMMARY_NULL(markersummary, ms_item); // add the whole markerid while (ms_item && markersummary->markerid == workmarkers->markerid) { @@ -4431,7 +4431,7 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, // So web can always verify it received all data APPEND_REALLOC(buf, off, len, "pplns_last=1"); - mu_root = free_ktree(mu_root, NULL); + free_ktree(mu_root, NULL); K_WLOCK(mu_store); k_list_transfer_to_head(mu_store, miningpayouts_free); K_WUNLOCK(mu_store); @@ -4441,7 +4441,8 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id, return buf; shazbot: - mu_root = free_ktree(mu_root, NULL); + + free_ktree(mu_root, NULL); K_WLOCK(mu_store); k_list_transfer_to_head(mu_store, miningpayouts_free); K_WUNLOCK(mu_store); @@ -4494,7 +4495,7 @@ static char *cmd_pplns2(__maybe_unused PGconn *conn, char *cmd, char *id, INIT_BLOCKS(&b_look); b_look.data = (void *)(&lookblocks); K_RLOCK(blocks_free); - b_item = find_after_in_ktree(blocks_root, &b_look, cmp_blocks, b_ctx); + b_item = find_after_in_ktree(blocks_root, &b_look, b_ctx); K_RUNLOCK(blocks_free); if (!b_item) { K_RUNLOCK(blocks_free); @@ -5257,8 +5258,8 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, markersummary.userid = users->userid; markersummary.workername = EMPTY; K_RLOCK(markersummary_free); - ms_item = find_after_in_ktree(markersummary_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_item = find_after_in_ktree(markersummary_root, + &ms_look, ms_ctx); DATA_MARKERSUMMARY_NULL(ms, ms_item); while (ms_item && ms->markerid == wm->markerid && ms->userid == users->userid) { diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 63a872c0..a7cc7eb3 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -20,7 +20,7 @@ void free_msgline_data(K_ITEM *item, bool t_lock, bool t_cull) DATA_MSGLINE(msgline, item); if (msgline->trf_root) - msgline->trf_root = free_ktree(msgline->trf_root, NULL); + free_ktree(msgline->trf_root, NULL); if (msgline->trf_store) { t_item = msgline->trf_store->head; while (t_item) { @@ -691,7 +691,7 @@ K_ITEM *find_transfer(K_TREE *trf_root, char *name) STRNCPY(transfer.name, name); INIT_TRANSFER(&look); look.data = (void *)(&transfer); - return find_in_ktree(trf_root, &look, cmp_transfer, ctx); + return find_in_ktree(trf_root, &look, ctx); } K_ITEM *_optional_name(K_TREE *trf_root, char *name, int len, char *patt, @@ -827,7 +827,7 @@ K_ITEM *get_workerstatus(int64_t userid, char *workername) INIT_WORKERSTATUS(&look); look.data = (void *)(&workerstatus); K_RLOCK(workerstatus_free); - find = find_in_ktree(workerstatus_root, &look, cmp_workerstatus, ctx); + find = find_in_ktree(workerstatus_root, &look, ctx); K_RUNLOCK(workerstatus_free); return find; } @@ -876,7 +876,7 @@ K_ITEM *_find_create_workerstatus(int64_t userid, char *workername, row->userid = userid; STRNCPY(row->workername, workername); - workerstatus_root = add_to_ktree(workerstatus_root, ws_item, cmp_workerstatus); + add_to_ktree(workerstatus_root, ws_item); k_add_head(workerstatus_store, ws_item); K_WUNLOCK(workerstatus_free); @@ -1115,7 +1115,7 @@ K_ITEM *find_users(char *username) INIT_USERS(&look); look.data = (void *)(&users); - return find_in_ktree(users_root, &look, cmp_users, ctx); + return find_in_ktree(users_root, &look, ctx); } // Must be R or W locked before call @@ -1131,7 +1131,7 @@ K_ITEM *find_userid(int64_t userid) INIT_USERS(&look); look.data = (void *)(&users); - return find_in_ktree(userid_root, &look, cmp_userid, ctx); + return find_in_ktree(userid_root, &look, ctx); } // TODO: endian? (to avoid being all zeros?) @@ -1428,7 +1428,7 @@ K_ITEM *find_useratts(int64_t userid, char *attname) INIT_USERATTS(&look); look.data = (void *)(&useratts); - return find_in_ktree(useratts_root, &look, cmp_useratts, ctx); + return find_in_ktree(useratts_root, &look, ctx); } // order by userid asc,workername asc,expirydate desc @@ -1459,7 +1459,7 @@ K_ITEM *find_workers(int64_t userid, char *workername) INIT_WORKERS(&look); look.data = (void *)(&workers); - return find_in_ktree(workers_root, &look, cmp_workers, ctx); + return find_in_ktree(workers_root, &look, ctx); } K_ITEM *first_workers(int64_t userid, K_TREE_CTX *ctx) @@ -1478,7 +1478,7 @@ K_ITEM *first_workers(int64_t userid, K_TREE_CTX *ctx) INIT_WORKERS(&look); look.data = (void *)(&workers); // Caller needs to check userid/expirydate if the result != NULL - return find_after_in_ktree(workers_root, &look, cmp_workers, ctx); + return find_after_in_ktree(workers_root, &look, ctx); } K_ITEM *new_worker(PGconn *conn, bool update, int64_t userid, char *workername, @@ -1607,7 +1607,7 @@ K_ITEM *find_paymentaddresses(int64_t userid, K_TREE_CTX *ctx) INIT_PAYMENTADDRESSES(&look); look.data = (void *)(&paymentaddresses); - item = find_before_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx); + item = find_before_in_ktree(paymentaddresses_root, &look, ctx); if (item) { DATA_PAYMENTADDRESSES(pa, item); if (pa->userid == userid && CURRENT(&(pa->expirydate))) @@ -1631,8 +1631,7 @@ K_ITEM *find_paymentaddresses_create(int64_t userid, K_TREE_CTX *ctx) INIT_PAYMENTADDRESSES(&look); look.data = (void *)(&paymentaddresses); - item = find_after_in_ktree(paymentaddresses_create_root, &look, - cmp_payaddr_create, ctx); + item = find_after_in_ktree(paymentaddresses_create_root, &look, ctx); if (item) { DATA_PAYMENTADDRESSES(pa, item); if (pa->userid == userid) @@ -1655,7 +1654,7 @@ K_ITEM *find_one_payaddress(int64_t userid, char *payaddress, K_TREE_CTX *ctx) INIT_PAYMENTADDRESSES(&look); look.data = (void *)(&paymentaddresses); - return find_in_ktree(paymentaddresses_root, &look, cmp_paymentaddresses, ctx); + return find_in_ktree(paymentaddresses_root, &look, ctx); } /* This will match any user that has the payaddress @@ -1715,7 +1714,7 @@ K_ITEM *find_payments(int64_t payoutid, int64_t userid, char *subname) INIT_PAYMENTS(&look); look.data = (void *)(&payments); - return find_in_ktree(payments_root, &look, cmp_payments, ctx); + return find_in_ktree(payments_root, &look, ctx); } K_ITEM *find_first_payments(int64_t userid, K_TREE_CTX *ctx) @@ -1733,7 +1732,7 @@ K_ITEM *find_first_payments(int64_t userid, K_TREE_CTX *ctx) INIT_PAYMENTS(&look); look.data = (void *)(&payments); // userid needs to be checked if item returned != NULL - item = find_after_in_ktree(payments_root, &look, cmp_payments, ctx); + item = find_after_in_ktree(payments_root, &look, ctx); return item; } @@ -1753,7 +1752,7 @@ K_ITEM *find_first_paypayid(int64_t userid, int64_t payoutid, K_TREE_CTX *ctx) INIT_PAYMENTS(&look); look.data = (void *)(&payments); // userid+payoutid needs to be checked if item returned != NULL - item = find_after_in_ktree(payments_root, &look, cmp_payments, ctx); + item = find_after_in_ktree(payments_root, &look, ctx); return item; } @@ -1777,7 +1776,7 @@ K_ITEM *find_accountbalance(int64_t userid) INIT_ACCOUNTBALANCE(&look); look.data = (void *)(&accountbalance); K_RLOCK(accountbalance_free); - item = find_in_ktree(accountbalance_root, &look, cmp_accountbalance, ctx); + item = find_in_ktree(accountbalance_root, &look, ctx); K_RUNLOCK(accountbalance_free); return item; } @@ -1853,7 +1852,7 @@ K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height) INIT_OPTIONCONTROL(&look); look.data = (void *)(&optioncontrol); - item = find_after_in_ktree(optioncontrol_root, &look, cmp_optioncontrol, ctx); + item = find_after_in_ktree(optioncontrol_root, &look, ctx); ocbest = NULL; best = NULL; while (item) { @@ -1989,7 +1988,7 @@ K_ITEM *find_workinfo(int64_t workinfoid, K_TREE_CTX *ctx) INIT_WORKINFO(&look); look.data = (void *)(&workinfo); K_RLOCK(workinfo_free); - item = find_in_ktree(workinfo_root, &look, cmp_workinfo, ctx); + item = find_in_ktree(workinfo_root, &look, ctx); K_RUNLOCK(workinfo_free); return item; } @@ -2010,7 +2009,7 @@ K_ITEM *next_workinfo(int64_t workinfoid, K_TREE_CTX *ctx) INIT_WORKINFO(&look); look.data = (void *)(&workinfo); K_RLOCK(workinfo_free); - item = find_after_in_ktree(workinfo_root, &look, cmp_workinfo, ctx); + item = find_after_in_ktree(workinfo_root, &look, ctx); if (item) { DATA_WORKINFO(wi, item); while (item && !CURRENT(&(wi->expirydate))) { @@ -2091,7 +2090,7 @@ bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code, diff_tot = 0; ss_look.data = (void *)(&looksharesummary); K_RLOCK(sharesummary_free); - ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &ss_look, cmp_sharesummary_workinfoid, ss_ctx); + ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_ctx); K_RUNLOCK(sharesummary_free); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); while (ss_item && sharesummary->workinfoid == workinfoid) { @@ -2142,7 +2141,7 @@ bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code, s_look.data = (void *)(&lookshares); K_WLOCK(shares_free); - s_item = find_after_in_ktree(shares_root, &s_look, cmp_shares, s_ctx); + s_item = find_after_in_ktree(shares_root, &s_look, s_ctx); while (s_item) { DATA_SHARES(shares, s_item); if (shares->workinfoid != workinfoid || @@ -2154,7 +2153,7 @@ bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code, if (shares->errn == SE_NONE) diff_tot += shares->diff; tmp_item = next_in_ktree(s_ctx); - shares_root = remove_from_ktree(shares_root, s_item, cmp_shares); + remove_from_ktree(shares_root, s_item); k_unlink_item(shares_store, s_item); if (reloading && skipupdate) shares_dumped++; @@ -2317,13 +2316,10 @@ K_ITEM *_find_sharesummary(int64_t userid, char *workername, int64_t workinfoid, INIT_SHARESUMMARY(&look); look.data = (void *)(&sharesummary); - if (pool) { - return find_in_ktree(sharesummary_pool_root, &look, - cmp_sharesummary, ctx); - } else { - return find_in_ktree(sharesummary_root, &look, - cmp_sharesummary, ctx); - } + if (pool) + return find_in_ktree(sharesummary_pool_root, &look, ctx); + else + return find_in_ktree(sharesummary_root, &look, ctx); } K_ITEM *find_last_sharesummary(int64_t userid, char *workername) @@ -2338,7 +2334,7 @@ K_ITEM *find_last_sharesummary(int64_t userid, char *workername) INIT_SHARESUMMARY(&look); look.data = (void *)(&look_sharesummary); - item = find_before_in_ktree(sharesummary_root, &look, cmp_sharesummary, ctx); + item = find_before_in_ktree(sharesummary_root, &look, ctx); if (item) { DATA_SHARESUMMARY(sharesummary, item); if (sharesummary->userid != userid || @@ -2381,8 +2377,7 @@ void auto_age_older(int64_t workinfoid, char *poolinstance, char *by, look.data = (void *)(&looksharesummary); K_RLOCK(sharesummary_free); - ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &look, - cmp_sharesummary_workinfoid, ctx); + ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &look, ctx); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATE_ZERO(&ss_first_min); @@ -2613,7 +2608,7 @@ K_ITEM *find_blocks(int32_t height, char *blockhash, K_TREE_CTX *ctx) INIT_BLOCKS(&look); look.data = (void *)(&blocks); - return find_in_ktree(blocks_root, &look, cmp_blocks, ctx); + return find_in_ktree(blocks_root, &look, ctx); } // Must be R or W locked before call @@ -2632,7 +2627,7 @@ K_ITEM *find_prev_blocks(int32_t height) INIT_BLOCKS(&look); look.data = (void *)(&lookblocks); - b_item = find_before_in_ktree(blocks_root, &look, cmp_blocks, ctx); + b_item = find_before_in_ktree(blocks_root, &look, ctx); while (b_item) { DATA_BLOCKS(blocks, b_item); if (blocks->confirmed[0] != BLOCKS_NEW && @@ -2716,8 +2711,8 @@ void set_block_share_counters() looksharesummary.workername = sharesummary->workername; looksharesummary.workinfoid = -1; ss_look.data = (void *)(&looksharesummary); - ss_item = find_before_in_ktree(sharesummary_root, &ss_look, - cmp_sharesummary, ctx); + ss_item = find_before_in_ktree(sharesummary_root, + &ss_look, ctx); continue; } @@ -2800,7 +2795,8 @@ void set_block_share_counters() lookmarkersummary.userid = MAXID; lookmarkersummary.workername = EMPTY; ms_look.data = (void *)(&lookmarkersummary); - ms_item = find_before_in_ktree(markersummary_root, &ms_look, cmp_markersummary, ctx_ms); + ms_item = find_before_in_ktree(markersummary_root, + &ms_look, ctx_ms); while (ms_item) { DATA_MARKERSUMMARY(markersummary, ms_item); if (markersummary->markerid != workmarkers->markerid) @@ -3067,7 +3063,7 @@ bool _set_prevcreatedate(int32_t oldest_height, WHERE_FFL_ARGS) INIT_BLOCKS(&look); look.data = (void *)(&lookblocks); - b_item = find_before_in_ktree(blocks_root, &look, cmp_blocks, b_ctx); + b_item = find_before_in_ktree(blocks_root, &look, b_ctx); while (b_item) { DATA_BLOCKS(blocks, b_item); if (CURRENT(&(blocks->expirydate)) && @@ -3194,7 +3190,7 @@ K_ITEM *find_miningpayouts(int64_t payoutid, int64_t userid) INIT_MININGPAYOUTS(&look); look.data = (void *)(&miningpayouts); - return find_in_ktree(miningpayouts_root, &look, cmp_miningpayouts, ctx); + return find_in_ktree(miningpayouts_root, &look, ctx); } K_ITEM *first_miningpayouts(int64_t payoutid, K_TREE_CTX *ctx) @@ -3212,7 +3208,7 @@ K_ITEM *first_miningpayouts(int64_t payoutid, K_TREE_CTX *ctx) INIT_MININGPAYOUTS(&look); look.data = (void *)(&miningpayouts); - return find_after_in_ktree(miningpayouts_root, &look, cmp_miningpayouts, ctx); + return find_after_in_ktree(miningpayouts_root, &look, ctx); } /* Processing payouts uses it's own tree of miningpayouts keyed only on userid @@ -3240,7 +3236,7 @@ K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid, INIT_MININGPAYOUTS(&look); look.data = (void *)(&lookminingpayouts); // No locking required since it's not a shared tree or store - mu_item = find_in_ktree(mu_root, &look, cmp_mu, ctx); + mu_item = find_in_ktree(mu_root, &look, ctx); if (mu_item) { DATA_MININGPAYOUTS(miningpayouts, mu_item); miningpayouts->diffacc += diffacc; @@ -3250,7 +3246,7 @@ K_TREE *upd_add_mu(K_TREE *mu_root, K_STORE *mu_store, int64_t userid, DATA_MININGPAYOUTS(miningpayouts, mu_item); miningpayouts->userid = userid; miningpayouts->diffacc = diffacc; - mu_root = add_to_ktree(mu_root, mu_item, cmp_mu); + add_to_ktree(mu_root, mu_item); k_add_head(mu_store, mu_item); K_WUNLOCK(mu_store); } @@ -3314,7 +3310,7 @@ K_ITEM *find_payouts(int32_t height, char *blockhash) INIT_PAYOUTS(&look); look.data = (void *)(&payouts); - return find_in_ktree(payouts_root, &look, cmp_payouts, ctx); + return find_in_ktree(payouts_root, &look, ctx); } // Last block payout calculated @@ -3346,7 +3342,7 @@ K_ITEM *find_payoutid(int64_t payoutid) INIT_PAYOUTS(&look); look.data = (void *)(&payouts); - return find_in_ktree(payouts_id_root, &look, cmp_payouts_id, ctx); + return find_in_ktree(payouts_id_root, &look, ctx); } // First payouts workinfoidend equal or before workinfoidend @@ -3364,7 +3360,7 @@ K_ITEM *find_payouts_wid(int64_t workinfoidend, K_TREE_CTX *ctx) INIT_PAYOUTS(&look); look.data = (void *)(&payouts); - return find_before_in_ktree(payouts_wid_root, &look, cmp_payouts_wid, ctx); + return find_before_in_ktree(payouts_wid_root, &look, ctx); } /* Values from payout stats, returns -1 if statname isn't found @@ -3603,7 +3599,7 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) ss_count = wm_count = ms_count = 0; mu_store = k_new_store(miningpayouts_free); - mu_root = new_ktree(); + mu_root = new_ktree(cmp_mu); looksharesummary.workinfoid = blocks->workinfoid; looksharesummary.userid = MAXID; @@ -3614,7 +3610,7 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) K_RLOCK(workmarkers_free); K_RLOCK(markersummary_free); ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, - cmp_sharesummary_workinfoid, ss_ctx); + ss_ctx); DATA_SHARESUMMARY_NULL(sharesummary, ss_item); if (ss_item) end_workinfoid = sharesummary->workinfoid; @@ -3713,8 +3709,8 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) lookworkmarkers.workinfoidend = blocks->workinfoid + 1; INIT_WORKMARKERS(&wm_look); wm_look.data = (void *)(&lookworkmarkers); - wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, - cmp_workmarkers_workinfoid, wm_ctx); + wm_item = find_before_in_ktree(workmarkers_workinfoid_root, + &wm_look, wm_ctx); DATA_WORKMARKERS_NULL(workmarkers, wm_item); LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend); while (total_diff < diff_want && wm_item && CURRENT(&(workmarkers->expirydate))) { @@ -3729,8 +3725,8 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) lookmarkersummary.workername = EMPTY; INIT_MARKERSUMMARY(&ms_look); ms_look.data = (void *)(&lookmarkersummary); - ms_item = find_before_in_ktree(markersummary_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_item = find_before_in_ktree(markersummary_root, + &ms_look, ms_ctx); DATA_MARKERSUMMARY_NULL(markersummary, ms_item); // add the whole markerid while (ms_item && markersummary->markerid == workmarkers->markerid) { @@ -4053,7 +4049,7 @@ bool process_pplns(int32_t height, char *blockhash, tv_t *addr_cd) payouts_add_ram(true, p_item, old_p_item, &now); - mu_root = free_ktree(mu_root, NULL); + free_ktree(mu_root, NULL); mu_item = k_unlink_head(mu_store); while (mu_item) { DATA_MININGPAYOUTS(miningpayouts, mu_item); @@ -4144,7 +4140,7 @@ oku: ; ck_wunlock(&process_pplns_lock); if (mu_root) - mu_root = free_ktree(mu_root, NULL); + free_ktree(mu_root, NULL); if (mu_store) { if (mu_store->count) { K_WLOCK(mu_store); @@ -4245,7 +4241,7 @@ K_ITEM *find_userstats(int64_t userid, char *workername) INIT_USERSTATS(&look); look.data = (void *)(&userstats); - return find_in_ktree(userstats_root, &look, cmp_userstats, ctx); + return find_in_ktree(userstats_root, &look, ctx); } void dsp_markersummary(K_ITEM *item, FILE *stream) @@ -4312,7 +4308,7 @@ K_ITEM *find_markersummary_userid(int64_t userid, char *workername, INIT_MARKERSUMMARY(&look); look.data = (void *)(&markersummary); - ms_item = find_before_in_ktree(markersummary_userid_root, &look, cmp_markersummary_userid, ctx); + ms_item = find_before_in_ktree(markersummary_userid_root, &look, ctx); if (ms_item) { DATA_MARKERSUMMARY(ms, ms_item); if (ms->userid != userid || strcmp(ms->workername, workername)) @@ -4349,11 +4345,11 @@ K_ITEM *_find_markersummary(int64_t markerid, int64_t workinfoid, INIT_MARKERSUMMARY(&look); look.data = (void *)(&markersummary); if (pool) { - ms_item = find_in_ktree(markersummary_pool_root, &look, - cmp_markersummary, ctx); + ms_item = find_in_ktree(markersummary_pool_root, + &look, ctx); } else { - ms_item = find_in_ktree(markersummary_root, &look, - cmp_markersummary, ctx); + ms_item = find_in_ktree(markersummary_root, + &look, ctx); } } @@ -4476,7 +4472,7 @@ K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status, K_TREE INIT_WORKMARKERS(&look); look.data = (void *)(&workmarkers); - wm_item = find_after_in_ktree(workmarkers_workinfoid_root, &look, cmp_workmarkers_workinfoid, ctx); + wm_item = find_after_in_ktree(workmarkers_workinfoid_root, &look, ctx); if (wm_item) { DATA_WORKMARKERS(wm, wm_item); if (!CURRENT(&(wm->expirydate)) || @@ -4500,7 +4496,7 @@ K_ITEM *find_workmarkerid(int64_t markerid, bool anystatus, char status) INIT_WORKMARKERS(&look); look.data = (void *)(&workmarkers); - wm_item = find_in_ktree(workmarkers_root, &look, cmp_workmarkers, ctx); + wm_item = find_in_ktree(workmarkers_root, &look, ctx); if (wm_item) { DATA_WORKMARKERS(wm, wm_item); if (!CURRENT(&(wm->expirydate)) || @@ -4530,8 +4526,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin, look.data = (void *)(&workinfo); K_RLOCK(workinfo_free); if (after) { - wi_stt_item = find_after_in_ktree(workinfo_root, &look, - cmp_workinfo, ctx); + wi_stt_item = find_after_in_ktree(workinfo_root, &look, ctx); while (wi_stt_item) { DATA_WORKINFO(wi_stt, wi_stt_item); if (CURRENT(&(wi_stt->expirydate))) @@ -4539,8 +4534,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin, wi_stt_item = next_in_ktree(ctx); } } else { - wi_stt_item = find_in_ktree(workinfo_root, &look, - cmp_workinfo, ctx); + wi_stt_item = find_in_ktree(workinfo_root, &look, ctx); DATA_WORKINFO_NULL(wi_stt, wi_stt_item); } K_RUNLOCK(workinfo_free); @@ -4556,8 +4550,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin, K_RLOCK(workinfo_free); if (before) { DATE_ZERO(&(workinfo.expirydate)); - wi_fin_item = find_before_in_ktree(workinfo_root, &look, - cmp_workinfo, ctx); + wi_fin_item = find_before_in_ktree(workinfo_root, &look, ctx); while (wi_fin_item) { DATA_WORKINFO(wi_fin, wi_fin_item); if (CURRENT(&(wi_fin->expirydate))) @@ -4567,8 +4560,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin, } else { workinfo.expirydate.tv_sec = default_expiry.tv_sec; workinfo.expirydate.tv_usec = default_expiry.tv_usec; - wi_fin_item = find_in_ktree(workinfo_root, &look, - cmp_workinfo, ctx); + wi_fin_item = find_in_ktree(workinfo_root, &look, ctx); DATA_WORKINFO_NULL(wi_fin, wi_fin_item); } K_RUNLOCK(workinfo_free); @@ -4647,7 +4639,7 @@ bool workmarkers_generate(PGconn *conn, char *err, size_t siz, char *by, INIT_MARKS(&look); look.data = (void *)(&marks); K_RLOCK(marks_free); - m_item = find_before_in_ktree(marks_root, &look, cmp_marks, ctx); + m_item = find_before_in_ktree(marks_root, &look, ctx); while (m_item) { DATA_MARKS(mused, m_item); if (CURRENT(&(mused->expirydate)) && MUSED(mused->status)) @@ -4854,7 +4846,7 @@ K_ITEM *find_marks(int64_t workinfoid) INIT_MARKS(&look); look.data = (void *)(&marks); - return find_in_ktree(marks_root, &look, cmp_marks, ctx); + return find_in_ktree(marks_root, &look, ctx); } const char *marks_marktype(char *marktype) @@ -5026,7 +5018,7 @@ K_ITEM *_get_userinfo(int64_t userid, bool lock) look.data = (void *)(&userinfo); if (lock) K_RLOCK(userinfo_free); - find = find_in_ktree(userinfo_root, &look, cmp_userinfo, ctx); + find = find_in_ktree(userinfo_root, &look, ctx); if (lock) K_RUNLOCK(userinfo_free); return find; @@ -5059,7 +5051,7 @@ K_ITEM *_find_create_userinfo(int64_t userid, bool lock, WHERE_FFL_ARGS) else bigint_to_buf(userid, row->username, sizeof(row->username)); - userinfo_root = add_to_ktree(userinfo_root, ui_item, cmp_userinfo); + add_to_ktree(userinfo_root, ui_item); k_add_head(userinfo_store, ui_item); if (lock) K_WUNLOCK(userinfo_free); diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index 7c6e4a6b..881f9b3f 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -513,14 +513,14 @@ unparam: free_users_data(item); k_add_head(users_free, item); } else { - users_root = remove_from_ktree(users_root, u_item, cmp_users); - userid_root = remove_from_ktree(userid_root, u_item, cmp_userid); + remove_from_ktree(users_root, u_item); + remove_from_ktree(userid_root, u_item); copy_tv(&(users->expirydate), cd); - users_root = add_to_ktree(users_root, u_item, cmp_users); - userid_root = add_to_ktree(userid_root, u_item, cmp_userid); + add_to_ktree(users_root, u_item); + add_to_ktree(userid_root, u_item); - users_root = add_to_ktree(users_root, item, cmp_users); - userid_root = add_to_ktree(userid_root, item, cmp_userid); + add_to_ktree(users_root, item); + add_to_ktree(userid_root, item); k_add_head(users_store, item); } K_WUNLOCK(users_free); @@ -648,8 +648,8 @@ unitem: free_users_data(item); k_add_head(users_free, item); } else { - users_root = add_to_ktree(users_root, item, cmp_users); - userid_root = add_to_ktree(userid_root, item, cmp_userid); + add_to_ktree(users_root, item); + add_to_ktree(userid_root, item); k_add_head(users_store, item); } K_WUNLOCK(users_free); @@ -760,14 +760,14 @@ unparam: free_users_data(u_item); k_add_head(users_free, u_item); } else { - users_root = remove_from_ktree(users_root, old_u_item, cmp_users); - userid_root = remove_from_ktree(userid_root, old_u_item, cmp_userid); + remove_from_ktree(users_root, old_u_item); + remove_from_ktree(userid_root, old_u_item); copy_tv(&(old_users->expirydate), cd); - users_root = add_to_ktree(users_root, old_u_item, cmp_users); - userid_root = add_to_ktree(userid_root, old_u_item, cmp_userid); + add_to_ktree(users_root, old_u_item); + add_to_ktree(userid_root, old_u_item); - users_root = add_to_ktree(users_root, u_item, cmp_users); - userid_root = add_to_ktree(userid_root, u_item, cmp_userid); + add_to_ktree(users_root, u_item); + add_to_ktree(userid_root, u_item); k_add_head(users_store, u_item); } K_WUNLOCK(users_free); @@ -883,8 +883,8 @@ bool users_fill(PGconn *conn) username_trim(row); - users_root = add_to_ktree(users_root, item, cmp_users); - userid_root = add_to_ktree(userid_root, item, cmp_userid); + add_to_ktree(users_root, item); + add_to_ktree(userid_root, item); k_add_head(users_store, item); } if (!ok) { @@ -1011,11 +1011,11 @@ unparam: if (ok) { // Update it if (old_item) { - useratts_root = remove_from_ktree(useratts_root, old_item, cmp_useratts); + remove_from_ktree(useratts_root, old_item); copy_tv(&(old_useratts->expirydate), cd); - useratts_root = add_to_ktree(useratts_root, old_item, cmp_useratts); + add_to_ktree(useratts_root, old_item); } - useratts_root = add_to_ktree(useratts_root, ua_item, cmp_useratts); + add_to_ktree(useratts_root, ua_item); k_add_head(useratts_store, ua_item); } K_WUNLOCK(useratts_free); @@ -1162,9 +1162,9 @@ unparam: K_WLOCK(useratts_free); if (ok && item) { - useratts_root = remove_from_ktree(useratts_root, item, cmp_useratts); + remove_from_ktree(useratts_root, item); copy_tv(&(useratts->expirydate), cd); - useratts_root = add_to_ktree(useratts_root, item, cmp_useratts); + add_to_ktree(useratts_root, item); } K_WUNLOCK(useratts_free); @@ -1269,7 +1269,7 @@ bool useratts_fill(PGconn *conn) if (!ok) break; - useratts_root = add_to_ktree(useratts_root, item, cmp_useratts); + add_to_ktree(useratts_root, item); k_add_head(useratts_store, item); } if (!ok) @@ -1400,7 +1400,7 @@ unitem: if (!ret) k_add_head(workers_free, item); else { - workers_root = add_to_ktree(workers_root, item, cmp_workers); + add_to_ktree(workers_root, item); k_add_head(workers_store, item); // Ensure there is a matching workerstatus find_create_workerstatus(userid, workername, @@ -1639,7 +1639,7 @@ bool workers_fill(PGconn *conn) break; TXT_TO_BIGINT("workerid", field, row->workerid); - workers_root = add_to_ktree(workers_root, item, cmp_workers); + add_to_ktree(workers_root, item); k_add_head(workers_store, item); /* Make sure a workerstatus exists for each worker @@ -1869,15 +1869,11 @@ unparam: else { // It wasn't a match, thus it was expired n++; - paymentaddresses_root = remove_from_ktree(paymentaddresses_root, item, - cmp_paymentaddresses); - paymentaddresses_create_root = remove_from_ktree(paymentaddresses_create_root, - item, cmp_payaddr_create); + remove_from_ktree(paymentaddresses_root, item); + remove_from_ktree(paymentaddresses_create_root, item); copy_tv(&(row->expirydate), cd); - paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, - cmp_paymentaddresses); - paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root, - item, cmp_payaddr_create); + add_to_ktree(paymentaddresses_root, item); + add_to_ktree(paymentaddresses_create_root, item); } item = prev; DATA_PAYMENTADDRESSES_NULL(row, item); @@ -1889,10 +1885,8 @@ unparam: next = match->next; DATA_PAYMENTADDRESSES(pa, match); if (!pa->match) { - paymentaddresses_root = add_to_ktree(paymentaddresses_root, match, - cmp_paymentaddresses); - paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root, - match, cmp_payaddr_create); + add_to_ktree(paymentaddresses_root, match); + add_to_ktree(paymentaddresses_create_root, match); k_unlink_item(pa_store, match); k_add_head(paymentaddresses_store, match); count++; @@ -1981,10 +1975,8 @@ bool paymentaddresses_fill(PGconn *conn) if (!ok) break; - paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, - cmp_paymentaddresses); - paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root, - item, cmp_payaddr_create); + add_to_ktree(paymentaddresses_root, item); + add_to_ktree(paymentaddresses_create_root, item); k_add_head(paymentaddresses_store, item); } if (!ok) @@ -2015,11 +2007,11 @@ void payments_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd) } else { if (old_p_item) { DATA_PAYMENTS(oldp, old_p_item); - payments_root = remove_from_ktree(payments_root, old_p_item, cmp_payments); + remove_from_ktree(payments_root, old_p_item); copy_tv(&(oldp->expirydate), cd); - payments_root = add_to_ktree(payments_root, old_p_item, cmp_payments); + add_to_ktree(payments_root, old_p_item); } - payments_root = add_to_ktree(payments_root, p_item, cmp_payments); + add_to_ktree(payments_root, p_item); k_add_head(payments_store, p_item); } K_WUNLOCK(payments_free); @@ -2252,7 +2244,7 @@ bool payments_fill(PGconn *conn) if (!ok) break; - payments_root = add_to_ktree(payments_root, item, cmp_payments); + add_to_ktree(payments_root, item); k_add_head(payments_store, item); } if (!ok) @@ -2358,7 +2350,7 @@ K_ITEM *optioncontrol_item_add(PGconn *conn, K_ITEM *oc_item, tv_t *cd, bool beg INIT_OPTIONCONTROL(&look); look.data = (void *)row; K_RLOCK(optioncontrol_free); - old_item = find_in_ktree(optioncontrol_root, &look, cmp_optioncontrol, ctx); + old_item = find_in_ktree(optioncontrol_root, &look, ctx); K_RUNLOCK(optioncontrol_free); if (!conn) { @@ -2446,13 +2438,12 @@ nostart: } else { // Discard old if (old_item) { - optioncontrol_root = remove_from_ktree(optioncontrol_root, old_item, - cmp_optioncontrol); + remove_from_ktree(optioncontrol_root, old_item); k_unlink_item(optioncontrol_store, old_item); free_optioncontrol_data(old_item); k_add_head(optioncontrol_free, old_item); } - optioncontrol_root = add_to_ktree(optioncontrol_root, oc_item, cmp_optioncontrol); + add_to_ktree(optioncontrol_root, oc_item); k_add_head(optioncontrol_store, oc_item); if (strcmp(row->optionname, SWITCH_STATE_NAME) == 0) { switch_state = atoi(row->optionvalue); @@ -2584,7 +2575,7 @@ bool optioncontrol_fill(PGconn *conn) if (!ok) break; - optioncontrol_root = add_to_ktree(optioncontrol_root, item, cmp_optioncontrol); + add_to_ktree(optioncontrol_root, item); k_add_head(optioncontrol_store, item); // There should only be one CURRENT version of switch_state @@ -2659,7 +2650,7 @@ int64_t workinfo_add(PGconn *conn, char *workinfoidstr, char *poolinstance, HISTORYDATETRANSFER(trf_root, row); K_WLOCK(workinfo_free); - if (find_in_ktree(workinfo_root, item, cmp_workinfo, ctx)) { + if (find_in_ktree(workinfo_root, item, ctx)) { workinfoid = row->workinfoid; free_workinfo_data(item); k_add_head(workinfo_free, item); @@ -2732,7 +2723,7 @@ unparam: hex2bin(ndiffbin, row->bits, 4); current_ndiff = diff_from_nbits(ndiffbin); - workinfo_root = add_to_ktree(workinfo_root, item, cmp_workinfo); + add_to_ktree(workinfo_root, item); k_add_head(workinfo_store, item); // Remember the bc = 'cd' when the height changes @@ -2900,9 +2891,9 @@ bool workinfo_fill(PGconn *conn) if (!ok) break; - workinfo_root = add_to_ktree(workinfo_root, item, cmp_workinfo); + add_to_ktree(workinfo_root, item); if (!confirm_sharesummary) - workinfo_height_root = add_to_ktree(workinfo_height_root, item, cmp_workinfo_height); + add_to_ktree(workinfo_height_root, item); k_add_head(workinfo_store, item); if (tv_newer(&(dbstatus.newest_createdate_workinfo), &(row->createdate))) { @@ -3027,9 +3018,7 @@ static void shares_process_early(PGconn *conn, int64_t good_wid, tv_t *good_cd, } es_item = last_in_ktree(shares_early_root, ctx); if (es_item) { - shares_early_root = remove_from_ktree(shares_early_root, - es_item, - cmp_shares); + remove_from_ktree(shares_early_root, es_item); k_unlink_item(shares_early_store, es_item); } K_WUNLOCK(shares_free); @@ -3078,7 +3067,7 @@ static void shares_process_early(PGconn *conn, int64_t good_wid, tv_t *good_cd, return; redo: K_WLOCK(shares_free); - shares_early_root = add_to_ktree(shares_early_root, es_item, cmp_shares); + add_to_ktree(shares_early_root, es_item); k_add_tail(shares_early_store, es_item); K_WUNLOCK(shares_free); return; @@ -3093,7 +3082,7 @@ keep: early_shares->oldcount, early_shares->redo); FREENULL(st); K_WLOCK(shares_free); - shares_root = add_to_ktree(shares_root, es_item, cmp_shares); + add_to_ktree(shares_root, es_item); k_add_head(shares_store, es_item); K_WUNLOCK(shares_free); return; @@ -3200,8 +3189,7 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername shares->oldcount = 0; K_WLOCK(shares_free); // They need to be sorted by workinfoid - shares_early_root = add_to_ktree(shares_early_root, s_item, - cmp_shares); + add_to_ktree(shares_early_root, s_item); k_add_head(shares_early_store, s_item); K_WUNLOCK(shares_free); /* It was all OK except the missing workinfoid @@ -3212,7 +3200,7 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername ok = shares_process(conn, shares, trf_root); if (ok) { K_WLOCK(shares_free); - shares_root = add_to_ktree(shares_root, s_item, cmp_shares); + add_to_ktree(shares_root, s_item); k_add_head(shares_store, s_item); K_WUNLOCK(shares_free); @@ -3327,9 +3315,7 @@ static void shareerrors_process_early(PGconn *conn, int64_t good_wid, } es_item = last_in_ktree(shareerrors_early_root, ctx); if (es_item) { - shareerrors_early_root = remove_from_ktree(shareerrors_early_root, - es_item, - cmp_shareerrors); + remove_from_ktree(shareerrors_early_root, es_item); k_unlink_item(shareerrors_early_store, es_item); } K_WUNLOCK(shareerrors_free); @@ -3381,8 +3367,7 @@ static void shareerrors_process_early(PGconn *conn, int64_t good_wid, return; redo: K_WLOCK(shareerrors_free); - shareerrors_early_root = add_to_ktree(shareerrors_early_root, es_item, - cmp_shareerrors); + add_to_ktree(shareerrors_early_root, es_item); k_add_tail(shareerrors_early_store, es_item); K_WUNLOCK(shareerrors_free); return; @@ -3397,7 +3382,7 @@ keep: early_shareerrors->oldcount, early_shareerrors->redo); FREENULL(st); K_WLOCK(shareerrors_free); - shareerrors_root = add_to_ktree(shareerrors_root, es_item, cmp_shareerrors); + add_to_ktree(shareerrors_root, es_item); k_add_head(shareerrors_store, es_item); K_WUNLOCK(shareerrors_free); return; @@ -3494,9 +3479,7 @@ bool shareerrors_add(PGconn *conn, char *workinfoid, char *username, shareerrors->oldcount = 0; K_WLOCK(shareerrors_free); // They need to be sorted by workinfoid - shareerrors_early_root = add_to_ktree(shareerrors_early_root, - s_item, - cmp_shareerrors); + add_to_ktree(shareerrors_early_root, s_item); k_add_head(shareerrors_early_store, s_item); K_WUNLOCK(shareerrors_free); /* It was all OK except the missing workinfoid @@ -3507,8 +3490,7 @@ bool shareerrors_add(PGconn *conn, char *workinfoid, char *username, ok = shareerrors_process(conn, shareerrors, trf_root); if (ok) { K_WLOCK(shareerrors_free); - shareerrors_root = add_to_ktree(shareerrors_root, s_item, - cmp_shareerrors); + add_to_ktree(shareerrors_root, s_item); k_add_head(shareerrors_store, s_item); K_WUNLOCK(shareerrors_free); @@ -3597,7 +3579,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers, K_STORE *old_sharesummary_store = k_new_store(sharesummary_free); K_STORE *new_markersummary_store = k_new_store(markersummary_free); - K_TREE *ms_root = new_ktree(); + K_TREE *ms_root = new_ktree(cmp_markersummary); if (!CURRENT(&(workmarkers->expirydate))) { reason = "unexpired"; @@ -3617,8 +3599,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers, INIT_MARKERSUMMARY(&ms_look); ms_look.data = (void *)(&lookmarkersummary); K_RLOCK(markersummary_free); - ms_item = find_after_in_ktree(markersummary_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_item = find_after_in_ktree(markersummary_root, &ms_look, ms_ctx); K_RUNLOCK(markersummary_free); DATA_MARKERSUMMARY_NULL(markersummary, ms_item); if (ms_item && markersummary->markerid == workmarkers->markerid) { @@ -3640,8 +3621,8 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers, * Those incoming shares will not be touching the sharesummaries * we are processing here */ K_RLOCK(sharesummary_free); - ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, - cmp_sharesummary_workinfoid, ss_ctx); + ss_item = find_before_in_ktree(sharesummary_workinfoid_root, + &ss_look, ss_ctx); K_RUNLOCK(sharesummary_free); while (ss_item) { DATA_SHARESUMMARY(sharesummary, ss_item); @@ -3659,8 +3640,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers, lookmarkersummary.workername = sharesummary->workername; ms_look.data = (void *)(&lookmarkersummary); - ms_item = find_in_ktree(ms_root, &ms_look, - cmp_markersummary, ms_ctx); + ms_item = find_in_ktree(ms_root, &ms_look, ms_ctx); if (!ms_item) { K_WLOCK(markersummary_free); ms_item = k_unlink_head(markersummary_free); @@ -3673,8 +3653,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers, DUP_POINTER(markersummary_free, markersummary->workername, sharesummary->workername); - ms_root = add_to_ktree(ms_root, ms_item, - cmp_markersummary); + add_to_ktree(ms_root, ms_item); LOGDEBUG("%s() new ms %"PRId64"/%"PRId64"/%s", shortname, markersummary->markerid, @@ -3796,12 +3775,8 @@ flail: ms_item = new_markersummary_store->head; while (ms_item) { // move the new markersummaries into the trees/stores - markersummary_root = add_to_ktree(markersummary_root, - ms_item, - cmp_markersummary); - markersummary_userid_root = add_to_ktree(markersummary_userid_root, - ms_item, - cmp_markersummary_userid); + add_to_ktree(markersummary_root, ms_item); + add_to_ktree(markersummary_userid_root, ms_item); // create/update the pool markersummaries DATA_MARKERSUMMARY(markersummary, ms_item); @@ -3812,9 +3787,7 @@ flail: bzero(p_markersummary, sizeof(*p_markersummary)); p_markersummary->markerid = markersummary->markerid; POOL_MS(p_markersummary); - markersummary_pool_root = add_to_ktree(markersummary_pool_root, - p_ms_item, - cmp_markersummary); + add_to_ktree(markersummary_pool_root, p_ms_item); k_add_head(markersummary_pool_store, p_ms_item); } markersummary_to_pool(p_markersummary, markersummary); @@ -3828,20 +3801,14 @@ flail: ss_item = old_sharesummary_store->head; while (ss_item) { // remove the old sharesummaries from the trees - sharesummary_root = remove_from_ktree(sharesummary_root, - ss_item, - cmp_sharesummary); - sharesummary_workinfoid_root = remove_from_ktree(sharesummary_workinfoid_root, - ss_item, - cmp_sharesummary_workinfoid); + remove_from_ktree(sharesummary_root, ss_item); + remove_from_ktree(sharesummary_workinfoid_root, ss_item); // remove the pool sharesummaries DATA_SHARESUMMARY(sharesummary, ss_item); p_ss_item = find_sharesummary_p(sharesummary->workinfoid); if (p_ss_item) { - sharesummary_pool_root = remove_from_ktree(sharesummary_pool_root, - p_ss_item, - cmp_sharesummary); + remove_from_ktree(sharesummary_pool_root, p_ss_item); k_unlink_item(sharesummary_pool_store, p_ss_item); free_sharesummary_data(p_ss_item); k_add_head(sharesummary_free, p_ss_item); @@ -3864,7 +3831,7 @@ flail: workmarkers->description, workmarkers->status); } - ms_root = free_ktree(ms_root, NULL); + free_ktree(ms_root, NULL); new_markersummary_store = k_free_store(new_markersummary_store); old_sharesummary_store = k_free_store(old_sharesummary_store); @@ -4140,16 +4107,12 @@ bool _sharesummary_update(SHARES *s_row, SHAREERRORS *e_row, K_ITEM *ss_item, if (new || p_new) { K_WLOCK(sharesummary_free); if (new) { - sharesummary_root = add_to_ktree(sharesummary_root, item, cmp_sharesummary); - sharesummary_workinfoid_root = add_to_ktree(sharesummary_workinfoid_root, - item, - cmp_sharesummary_workinfoid); + add_to_ktree(sharesummary_root, item); + add_to_ktree(sharesummary_workinfoid_root, item); k_add_head(sharesummary_store, item); } if (p_new) { - sharesummary_pool_root = add_to_ktree(sharesummary_pool_root, - p_item, - cmp_sharesummary); + add_to_ktree(sharesummary_pool_root, p_item); k_add_head(sharesummary_pool_store, p_item); } K_WUNLOCK(sharesummary_free); @@ -4290,14 +4253,14 @@ unparam: k_add_head(blocks_free, b_item); else { if (update_old) { - blocks_root = remove_from_ktree(blocks_root, old_b_item, cmp_blocks); + remove_from_ktree(blocks_root, old_b_item); copy_tv(&(oldblocks->expirydate), cd); - blocks_root = add_to_ktree(blocks_root, old_b_item, cmp_blocks); + add_to_ktree(blocks_root, old_b_item); // Copy it over to avoid having to recalculate it row->netdiff = oldblocks->netdiff; } else row->netdiff = 0; - blocks_root = add_to_ktree(blocks_root, b_item, cmp_blocks); + add_to_ktree(blocks_root, b_item); k_add_head(blocks_store, b_item); blocks_stats_rebuild = true; // 'confirmed' is unchanged so no need to recalc *createdate @@ -4670,14 +4633,14 @@ flail: k_add_head(blocks_free, b_item); else { if (update_old) { - blocks_root = remove_from_ktree(blocks_root, old_b_item, cmp_blocks); + remove_from_ktree(blocks_root, old_b_item); copy_tv(&(oldblocks->expirydate), cd); - blocks_root = add_to_ktree(blocks_root, old_b_item, cmp_blocks); + add_to_ktree(blocks_root, old_b_item); // Copy it over to avoid having to recalculate it row->netdiff = oldblocks->netdiff; } else row->netdiff = 0; - blocks_root = add_to_ktree(blocks_root, b_item, cmp_blocks); + add_to_ktree(blocks_root, b_item); k_add_head(blocks_store, b_item); blocks_stats_rebuild = true; // recalc the *createdate fields for possibly affected blocks @@ -4897,7 +4860,7 @@ bool blocks_fill(PGconn *conn) if (!ok) break; - blocks_root = add_to_ktree(blocks_root, item, cmp_blocks); + add_to_ktree(blocks_root, item); k_add_head(blocks_store, item); if (tv_newer(&(dbstatus.newest_createdate_blocks), &(row->createdate))) @@ -4958,11 +4921,11 @@ void miningpayouts_add_ram(bool ok, K_ITEM *mp_item, K_ITEM *old_mp_item, tv_t * } else { if (old_mp_item) { DATA_MININGPAYOUTS(oldmp, old_mp_item); - miningpayouts_root = remove_from_ktree(miningpayouts_root, old_mp_item, cmp_miningpayouts); + remove_from_ktree(miningpayouts_root, old_mp_item); copy_tv(&(oldmp->expirydate), cd); - miningpayouts_root = add_to_ktree(miningpayouts_root, old_mp_item, cmp_miningpayouts); + add_to_ktree(miningpayouts_root, old_mp_item); } - miningpayouts_root = add_to_ktree(miningpayouts_root, mp_item, cmp_miningpayouts); + add_to_ktree(miningpayouts_root, mp_item); k_add_head(miningpayouts_store, mp_item); } K_WUNLOCK(miningpayouts_free); @@ -5142,7 +5105,7 @@ bool miningpayouts_fill(PGconn *conn) if (!ok) break; - miningpayouts_root = add_to_ktree(miningpayouts_root, item, cmp_miningpayouts); + add_to_ktree(miningpayouts_root, item); k_add_head(miningpayouts_store, item); tick(); @@ -5176,17 +5139,17 @@ void payouts_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd) } else { if (old_p_item) { DATA_PAYOUTS(oldp, old_p_item); - payouts_root = remove_from_ktree(payouts_root, old_p_item, cmp_payouts); - payouts_id_root = remove_from_ktree(payouts_id_root, old_p_item, cmp_payouts_id); - payouts_wid_root = remove_from_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid); + remove_from_ktree(payouts_root, old_p_item); + remove_from_ktree(payouts_id_root, old_p_item); + remove_from_ktree(payouts_wid_root, old_p_item); copy_tv(&(oldp->expirydate), cd); - payouts_root = add_to_ktree(payouts_root, old_p_item, cmp_payouts); - payouts_id_root = add_to_ktree(payouts_id_root, old_p_item, cmp_payouts_id); - payouts_wid_root = add_to_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid); + add_to_ktree(payouts_root, old_p_item); + add_to_ktree(payouts_id_root, old_p_item); + add_to_ktree(payouts_wid_root, old_p_item); } - payouts_root = add_to_ktree(payouts_root, p_item, cmp_payouts); - payouts_id_root = add_to_ktree(payouts_id_root, p_item, cmp_payouts_id); - payouts_wid_root = add_to_ktree(payouts_wid_root, p_item, cmp_payouts_wid); + add_to_ktree(payouts_root, p_item); + add_to_ktree(payouts_id_root, p_item); + add_to_ktree(payouts_wid_root, p_item); k_add_head(payouts_store, p_item); } K_WUNLOCK(payouts_free); @@ -5491,22 +5454,22 @@ K_ITEM *payouts_full_expire(PGconn *conn, int64_t payoutid, tv_t *now, bool lock // No more possible errors, so update the ram tables DATA_PAYOUTS(payouts, po_item); - payouts_root = remove_from_ktree(payouts_root, po_item, cmp_payouts); - payouts_id_root = remove_from_ktree(payouts_id_root, po_item, cmp_payouts_id); - payouts_wid_root = remove_from_ktree(payouts_wid_root, po_item, cmp_payouts_wid); + remove_from_ktree(payouts_root, po_item); + remove_from_ktree(payouts_id_root, po_item); + remove_from_ktree(payouts_wid_root, po_item); copy_tv(&(payouts->expirydate), now); - payouts_root = add_to_ktree(payouts_root, po_item, cmp_payouts); - payouts_id_root = add_to_ktree(payouts_id_root, po_item, cmp_payouts_id); - payouts_wid_root = add_to_ktree(payouts_wid_root, po_item, cmp_payouts_wid); + add_to_ktree(payouts_root, po_item); + add_to_ktree(payouts_id_root, po_item); + add_to_ktree(payouts_wid_root, po_item); mp_item = first_miningpayouts(payoutid, mp_ctx); DATA_MININGPAYOUTS_NULL(mp, mp_item); while (mp_item && mp->payoutid == payoutid) { if (CURRENT(&(mp->expirydate))) { next_item = next_in_ktree(mp_ctx); - miningpayouts_root = remove_from_ktree(miningpayouts_root, mp_item, cmp_miningpayouts); + remove_from_ktree(miningpayouts_root, mp_item); copy_tv(&(mp->expirydate), now); - miningpayouts_root = add_to_ktree(miningpayouts_root, mp_item, cmp_miningpayouts); + add_to_ktree(miningpayouts_root, mp_item); mp_item = next_item; } else mp_item = next_in_ktree(mp_ctx); @@ -5520,9 +5483,9 @@ K_ITEM *payouts_full_expire(PGconn *conn, int64_t payoutid, tv_t *now, bool lock if (payments->payoutid == payoutid && CURRENT(&(payments->expirydate))) { next_item = next_in_ktree(pm_ctx); - payments_root = remove_from_ktree(payments_root, pm_item, cmp_payments); + remove_from_ktree(payments_root, pm_item); copy_tv(&(payments->expirydate), now); - payments_root = add_to_ktree(payments_root, pm_item, cmp_payments); + add_to_ktree(payments_root, pm_item); pm_item = next_item; } else pm_item = next_in_ktree(pm_ctx); @@ -5698,9 +5661,9 @@ bool payouts_fill(PGconn *conn) &(blocks->blockcreatedate)); } - payouts_root = add_to_ktree(payouts_root, item, cmp_payouts); - payouts_id_root = add_to_ktree(payouts_id_root, item, cmp_payouts_id); - payouts_wid_root = add_to_ktree(payouts_wid_root, item, cmp_payouts_wid); + add_to_ktree(payouts_root, item); + add_to_ktree(payouts_id_root, item); + add_to_ktree(payouts_wid_root, item); k_add_head(payouts_store, item); if (CURRENT(&(row->expirydate)) && PAYGENERATED(row->status)) @@ -5792,7 +5755,7 @@ bool auths_add(PGconn *conn, char *poolinstance, char *username, HISTORYDATETRANSFER(trf_root, row); K_WLOCK(auths_free); - if (find_in_ktree(auths_root, a_item, cmp_auths, ctx)) { + if (find_in_ktree(auths_root, a_item, ctx)) { k_add_head(auths_free, a_item); K_WUNLOCK(auths_free); @@ -5825,7 +5788,7 @@ unitem: if (!ok) k_add_head(auths_free, a_item); else { - auths_root = add_to_ktree(auths_root, a_item, cmp_auths); + add_to_ktree(auths_root, a_item); k_add_head(auths_store, a_item); } #endif @@ -5875,7 +5838,7 @@ bool poolstats_add(PGconn *conn, bool store, char *poolinstance, SIMPLEDATEINIT(row, cd, by, code, inet); SIMPLEDATETRANSFER(trf_root, row); - if (igndup && find_in_ktree(poolstats_root, p_item, cmp_poolstats, ctx)) { + if (igndup && find_in_ktree(poolstats_root, p_item, ctx)) { K_WLOCK(poolstats_free); k_add_head(poolstats_free, p_item); K_WUNLOCK(poolstats_free); @@ -5937,7 +5900,7 @@ unparam: if (!ok) k_add_head(poolstats_free, p_item); else { - poolstats_root = add_to_ktree(poolstats_root, p_item, cmp_poolstats); + add_to_ktree(poolstats_root, p_item); k_add_head(poolstats_store, p_item); } K_WUNLOCK(poolstats_free); @@ -6083,7 +6046,7 @@ bool poolstats_fill(PGconn *conn) if (!ok) break; - poolstats_root = add_to_ktree(poolstats_root, item, cmp_poolstats); + add_to_ktree(poolstats_root, item); k_add_head(poolstats_store, item); if (tv_newer(&(dbstatus.newest_createdate_poolstats), &(row->createdate))) @@ -6186,15 +6149,13 @@ bool userstats_add(char *poolinstance, char *elapsed, char *username, K_WLOCK(userstats_free); us_next = userstats_eos_store->head; while (us_next) { - us_item = find_in_ktree(userstats_root, us_next, - cmp_userstats, ctx); + us_item = find_in_ktree(userstats_root, us_next, ctx); if (!us_item) { // New user+worker - store it in RAM us_match = us_next; us_next = us_match->next; k_unlink_item(userstats_eos_store, us_match); - userstats_root = add_to_ktree(userstats_root, us_match, - cmp_userstats); + add_to_ktree(userstats_root, us_match); k_add_head(userstats_store, us_match); } else { DATA_USERSTATS(next, us_next); @@ -6270,12 +6231,10 @@ bool workerstats_add(char *poolinstance, char *elapsed, char *username, workerstatus_update(NULL, NULL, row); K_WLOCK(userstats_free); - us_match = find_in_ktree(userstats_root, us_item, - cmp_userstats, ctx); + us_match = find_in_ktree(userstats_root, us_item, ctx); if (!us_match) { // New user+worker - store it in RAM - userstats_root = add_to_ktree(userstats_root, us_item, - cmp_userstats); + add_to_ktree(userstats_root, us_item); k_add_head(userstats_store, us_item); } else { DATA_USERSTATS(match, us_match); @@ -6520,8 +6479,8 @@ bool markersummary_fill(PGconn *conn) if (!ok) break; - markersummary_root = add_to_ktree(markersummary_root, item, cmp_markersummary); - markersummary_userid_root = add_to_ktree(markersummary_userid_root, item, cmp_markersummary_userid); + add_to_ktree(markersummary_root, item); + add_to_ktree(markersummary_userid_root, item); k_add_head(markersummary_store, item); p_item = find_markersummary_p(row->markerid); @@ -6533,9 +6492,7 @@ bool markersummary_fill(PGconn *conn) bzero(p_row, sizeof(*p_row)); p_row->markerid = row->markerid; POOL_MS(p_row); - markersummary_pool_root = add_to_ktree(markersummary_pool_root, - p_item, - cmp_markersummary); + add_to_ktree(markersummary_pool_root, p_item); k_add_head(markersummary_pool_store, p_item); } else { DATA_MARKERSUMMARY(p_row, p_item); @@ -6769,29 +6726,18 @@ unparam: } else { if (old_wm_item) { - workmarkers_root = remove_from_ktree(workmarkers_root, - old_wm_item, - cmp_workmarkers); - workmarkers_workinfoid_root = remove_from_ktree(workmarkers_workinfoid_root, - old_wm_item, - cmp_workmarkers_workinfoid); + remove_from_ktree(workmarkers_root, old_wm_item); + remove_from_ktree(workmarkers_workinfoid_root, + old_wm_item); copy_tv(&(oldworkmarkers->expirydate), cd); - workmarkers_root = add_to_ktree(workmarkers_root, - old_wm_item, - cmp_workmarkers); - workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root, - old_wm_item, - cmp_workmarkers_workinfoid); + add_to_ktree(workmarkers_root, old_wm_item); + add_to_ktree(workmarkers_workinfoid_root, old_wm_item); } if (wm_item) { shift_rewards(wm_item); - workmarkers_root = add_to_ktree(workmarkers_root, - wm_item, - cmp_workmarkers); - workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root, - wm_item, - cmp_workmarkers_workinfoid); + add_to_ktree(workmarkers_root, wm_item); + add_to_ktree(workmarkers_workinfoid_root, wm_item); k_add_head(workmarkers_store, wm_item); } } @@ -6887,9 +6833,8 @@ bool workmarkers_fill(PGconn *conn) if (!ok) break; - workmarkers_root = add_to_ktree(workmarkers_root, item, cmp_workmarkers); - workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root, - item, cmp_workmarkers_workinfoid); + add_to_ktree(workmarkers_root, item); + add_to_ktree(workmarkers_workinfoid_root, item); k_add_head(workmarkers_store, item); if (dbstatus.newest_workmarker_workinfoid < row->workinfoidend) { @@ -7086,12 +7031,12 @@ unparam: } } else { if (old_m_item) { - marks_root = remove_from_ktree(marks_root, old_m_item, cmp_marks); + remove_from_ktree(marks_root, old_m_item); copy_tv(&(oldmarks->expirydate), cd); - marks_root = add_to_ktree(marks_root, old_m_item, cmp_marks); + add_to_ktree(marks_root, old_m_item); } if (m_item) { - marks_root = add_to_ktree(marks_root, m_item, cmp_marks); + add_to_ktree(marks_root, m_item); k_add_head(marks_store, m_item); } } @@ -7186,7 +7131,7 @@ bool marks_fill(PGconn *conn) if (!ok) break; - marks_root = add_to_ktree(marks_root, item, cmp_marks); + add_to_ktree(marks_root, item); k_add_head(marks_store, item); tick(); diff --git a/src/ktree.c b/src/ktree.c index 588683b0..1181d069 100644 --- a/src/ktree.c +++ b/src/ktree.c @@ -1,5 +1,5 @@ /* - * Copyright 1995-2014 Andrew Smith + * Copyright 1995-2015 Andrew Smith * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -23,42 +23,56 @@ static const int dbg = 0; #define Yo true #define No false -static K_TREE nil[1] = { { Yo, RED_BLACK, NULL, NULL, NULL, NULL, 0 } }; +static K_NODE nil[1] = { { Yo, RED_BLACK, NULL, NULL, NULL, NULL, 0 } }; -K_TREE *_new_ktree(KTREE_FFL_ARGS) +static K_NODE *_new_knode(KTREE_FFL_ARGS) { - K_TREE *ktree = (K_TREE *)malloc(sizeof(*ktree)); + K_NODE *node = (K_NODE *)malloc(sizeof(*node)); - if (ktree == NULL) - FAIL("%s", "OOM"); + if (node == NULL) + FAIL("%s", "node OOM"); + + node->isNil = Yo; + node->red = RED_BLACK; + node->parent = nil; + node->left = nil; + node->right = nil; + node->data = NULL; + node->test = 0; + + return node; +} + +K_TREE *_new_ktree(cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS) +{ + K_TREE *tree = (K_TREE *)malloc(sizeof(*tree)); + + if (tree == NULL) + FAIL("%s", "tree OOM"); + + tree->root = _new_knode(KTREE_FFL_PASS); - ktree->isNil = Yo; - ktree->red = RED_BLACK; - ktree->parent = nil; - ktree->left = nil; - ktree->right = nil; - ktree->data = NULL; - ktree->test = 0; + tree->cmp_funct = cmp_funct; - return ktree; + return tree; } -static K_TREE *new_data(K_ITEM *data, KTREE_FFL_ARGS) +static K_NODE *new_data(K_ITEM *data, KTREE_FFL_ARGS) { - K_TREE *ktree = (K_TREE *)malloc(sizeof(*ktree)); + K_NODE *knode = (K_NODE *)malloc(sizeof(*knode)); - if (ktree == NULL) + if (knode == NULL) FAIL("%s", "OOM"); - ktree->isNil = No; - ktree->red = RED_RED; - ktree->parent = nil; - ktree->left = nil; - ktree->right = nil; - ktree->data = data; - ktree->test = 0; + knode->isNil = No; + knode->red = RED_RED; + knode->parent = nil; + knode->left = nil; + knode->right = nil; + knode->data = data; + knode->test = 0; - return ktree; + return knode; } static int bCount = 0; @@ -73,54 +87,54 @@ static long getTestValue() return ++testValue; } -static void show_ktree(K_TREE *root, char *path, int pos, char *(*dsp_funct)(K_ITEM *)) +static void show_ktree(K_NODE *node, char *path, int pos, char *(*dsp_funct)(K_ITEM *)) { char col; - if (root->isNil == Yo) + if (node->isNil == Yo) return; - if (root->left->isNil == No) + if (node->left->isNil == No) { path[pos] = 'L'; path[pos+1] = '\0'; - show_ktree(root->left, path, pos+1, dsp_funct); + show_ktree(node->left, path, pos+1, dsp_funct); } path[pos] = '\0'; - if (root->red == RED_RED) + if (node->red == RED_RED) col = 'R'; else - // if (root->red == RED_BLACK) + // if (node->red == RED_BLACK) col = 'B'; - printf(" %c %s=%s\n", col, path, dsp_funct(root->data)); + printf(" %c %s=%s\n", col, path, dsp_funct(node->data)); - if (root->right->isNil == No) + if (node->right->isNil == No) { path[pos] = 'R'; path[pos+1] = '\0'; - show_ktree(root->right, path, pos+1, dsp_funct); + show_ktree(node->right, path, pos+1, dsp_funct); } } -void _dump_ktree(K_TREE *root, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS) +void _dump_ktree(K_TREE *tree, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS) { char buf[42424]; printf("dump:\n"); - if (root->isNil == No) + if (tree->root->isNil == No) { buf[0] = 'T'; buf[1] = '\0'; - show_ktree(root, buf, 1, dsp_funct); + show_ktree(tree->root, buf, 1, dsp_funct); } else - printf(" Empty ktree\n"); + printf(" Empty tree\n"); } -void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL_ARGS) +void _dsp_ktree(K_LIST *list, K_TREE *tree, char *filename, char *msg, KTREE_FFL_ARGS) { K_TREE_CTX ctx[1]; K_ITEM *item; @@ -154,11 +168,11 @@ void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL if (msg) fprintf(stream, "%s %s\n", stamp, msg); else - fprintf(stream, "%s Dump of ktree '%s':\n", stamp, list->name); + fprintf(stream, "%s Dump of tree '%s':\n", stamp, list->name); - if (root->isNil == No) + if (tree->root->isNil == No) { - item = first_in_ktree(root, ctx); + item = first_in_ktree(tree, ctx); while (item) { list->dsp_func(item, stream); @@ -172,7 +186,7 @@ void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL fclose(stream); } -static int nilTest(K_TREE *node, char *msg, int depth, int count, K_TREE *nil2, KTREE_FFL_ARGS) +static int nilTest(K_NODE *node, char *msg, int depth, int count, K_NODE *nil2, KTREE_FFL_ARGS) { if (node->isNil == Yo || node == nil2) { @@ -231,7 +245,7 @@ static int nilTest(K_TREE *node, char *msg, int depth, int count, K_TREE *nil2, return(count); } -static void bTest(K_TREE *root, K_TREE *cur, char *msg, int count, KTREE_FFL_ARGS) +static void bTest(K_NODE *cur, char *msg, int count, KTREE_FFL_ARGS) { if (cur->red != RED_RED) count++; @@ -259,108 +273,118 @@ static void bTest(K_TREE *root, K_TREE *cur, char *msg, int count, KTREE_FFL_ARG else FAIL("BTESTVALUE '%s' count=%d", msg, count); - bTest(root, cur->left, msg, count, KTREE_FFL_PASS); - bTest(root, cur->right, msg, count, KTREE_FFL_PASS); + bTest(cur->left, msg, count, KTREE_FFL_PASS); + bTest(cur->right, msg, count, KTREE_FFL_PASS); } } -static void bTestInit(K_TREE *root, char *msg, KTREE_FFL_ARGS) +static void bTestInit(K_TREE *tree, char *msg, KTREE_FFL_ARGS) { bCount = 0; bTestValue = getTestValue(); - bTest(root, root, msg, 0, KTREE_FFL_PASS); + bTest(tree->root, msg, 0, KTREE_FFL_PASS); } -static void lrpTest(K_TREE *top, char *msg, KTREE_FFL_ARGS) +static void lrpTest(K_NODE *node, char *msg, KTREE_FFL_ARGS) { - if (top->test != lrpTestValue) - top->test = lrpTestValue; + if (node->test != lrpTestValue) + node->test = lrpTestValue; else FAIL("LRPTESTVALUE '%s'", msg); - if (top->left->isNil == No) + if (node->left->isNil == No) { - if (top->left->parent != top) + if (node->left->parent != node) FAIL("LRPTESTL '%s'", msg); - lrpTest(top->left, msg, KTREE_FFL_PASS); + lrpTest(node->left, msg, KTREE_FFL_PASS); } - if (top->right->isNil == No) + if (node->right->isNil == No) { - if (top->right->parent != top) + if (node->right->parent != node) FAIL("LRPTESTR '%s'", msg); - lrpTest(top->right, msg, KTREE_FFL_PASS); + lrpTest(node->right, msg, KTREE_FFL_PASS); } } -static __maybe_unused void check_ktree(K_TREE *root, char *msg, K_TREE *nil2, int debugNil, int debugLRP, int debugColor, KTREE_FFL_ARGS) +static __maybe_unused void check_ktree(K_TREE *tree, char *msg, K_NODE *nil2, int debugNil, int debugLRP, int debugColor, KTREE_FFL_ARGS) { - if (root->isNil == Yo) + if (tree->root->isNil == Yo) return; if (debugNil) { nilTestValue = getTestValue(); - nilTest(root, msg, 1, 0, nil2, KTREE_FFL_PASS); + nilTest(tree->root, msg, 1, 0, nil2, KTREE_FFL_PASS); } - if (debugLRP && root->isNil == No) + if (debugLRP && tree->root->isNil == No) { lrpTestValue = getTestValue(); - lrpTest(root, msg, KTREE_FFL_PASS); + lrpTest(tree->root, msg, KTREE_FFL_PASS); } - if (debugColor && root->isNil == No) - bTestInit(root, msg, KTREE_FFL_PASS); + if (debugColor && tree->root->isNil == No) + bTestInit(tree, msg, KTREE_FFL_PASS); } -K_ITEM *_first_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS) +static K_ITEM *_first_in_knode(K_NODE *node, K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - if (root->isNil == No) + if (node->isNil == No) { - while (root->left->isNil == No) - root = root->left; + while (node->left->isNil == No) + node = node->left; - *ctx = root; - return(root->data); + *ctx = node; + return(node->data); } *ctx = NULL; return(NULL); } -K_ITEM *_last_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS) +K_ITEM *_first_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - if (root->isNil == No) + return _first_in_knode(tree->root, ctx, KTREE_FFL_PASS); +} + +static K_ITEM *_last_in_knode(K_NODE *node, K_TREE_CTX *ctx, KTREE_FFL_ARGS) +{ + if (node->isNil == No) { - while (root->right->isNil == No) - root = root->right; + while (node->right->isNil == No) + node = node->right; - *ctx = root; - return(root->data); + *ctx = node; + return(node->data); } *ctx = NULL; return(NULL); } +K_ITEM *_last_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS) +{ + return _last_in_knode(tree->root, ctx, KTREE_FFL_PASS); +} + K_ITEM *_next_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - K_TREE *parent; - K_TREE *ktree = (K_TREE *)(*ctx); + K_NODE *parent; + K_NODE *knode = (K_NODE *)(*ctx); - if (ktree->isNil == No) + if (knode->isNil == No) { - if (ktree->right->isNil == No) - return(first_in_ktree(ktree->right, ctx)); + if (knode->right->isNil == No) + return(_first_in_knode(knode->right, ctx, KTREE_FFL_PASS)); else { - parent = ktree->parent; - while (parent->isNil == No && ktree == parent->right) + parent = knode->parent; + while (parent->isNil == No && knode == parent->right) { - ktree = parent; + knode = parent; parent = parent->parent; } if (parent->isNil == No) @@ -377,19 +401,19 @@ K_ITEM *_next_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS) K_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - K_TREE *parent; - K_TREE *ktree = (K_TREE *)(*ctx); + K_NODE *parent; + K_NODE *knode = (K_NODE *)(*ctx); - if (ktree->isNil == No) + if (knode->isNil == No) { - if (ktree->left->isNil == No) - return(last_in_ktree(ktree->left, ctx)); + if (knode->left->isNil == No) + return(_last_in_knode(knode->left, ctx, KTREE_FFL_PASS)); else { - parent = ktree->parent; - while (parent->isNil == No && ktree == parent->left) + parent = knode->parent; + while (parent->isNil == No && knode == parent->left) { - ktree = parent; + knode = parent; parent = parent->parent; } if (parent->isNil == No) @@ -404,9 +428,9 @@ K_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS) return(NULL); } -static K_TREE *left_rotate(K_TREE *root, K_TREE *about) +static K_NODE *left_rotate(K_NODE *root, K_NODE *about) { - K_TREE *rotate; + K_NODE *rotate; rotate = about->right; about->right = rotate->left; @@ -432,9 +456,9 @@ static K_TREE *left_rotate(K_TREE *root, K_TREE *about) return(root); } -static K_TREE *right_rotate(K_TREE *root, K_TREE *about) +static K_NODE *right_rotate(K_NODE *root, K_NODE *about) { - K_TREE *rotate; + K_NODE *rotate; rotate = about->left; about->left = rotate->right; @@ -458,50 +482,50 @@ static K_TREE *right_rotate(K_TREE *root, K_TREE *about) return(root); } -K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS) +void _add_to_ktree(K_TREE *tree, K_ITEM *data, KTREE_FFL_ARGS) { - K_TREE *ktree; - K_TREE *x, *y; - K_TREE *pp; + K_NODE *knode; + K_NODE *x, *y; + K_NODE *pp; cmp_t cmp; - if (root == NULL) - FAIL("%s", "ADDNULL add ktree is NULL"); + if (tree == NULL) + FAIL("%s", "ADDNULL add tree is NULL"); -//check_ktree(root, ">add", NULL, 1, 1, 1, KTREE_FFL_PASS); +//check_ktree(tree, ">add", NULL, 1, 1, 1, KTREE_FFL_PASS); - if (root->parent != nil && root->parent != NULL) - FAIL("%s", "ADDROOT add root isn't the root"); + if (tree->root->parent != nil && tree->root->parent != NULL) + FAIL("%s", "ADDROOT add tree->root isn't the root"); - ktree = new_data(data, KTREE_FFL_PASS); + knode = new_data(data, KTREE_FFL_PASS); - if (root->isNil == Yo) + if (tree->root->isNil == Yo) { - if (root != nil) - free(root); + if (tree->root != nil) + free(tree->root); - root = ktree; + tree->root = knode; } else { - x = root; + x = tree->root; y = nil; while (x->isNil == No) { y = x; - if ((cmp = (*cmp_funct)(ktree->data, x->data)) < 0) + if ((cmp = tree->cmp_funct(knode->data, x->data)) < 0) x = x->left; else x = x->right; } - ktree->parent = y; + knode->parent = y; if (cmp < 0) - y->left = ktree; + y->left = knode; else - y->right = ktree; + y->right = knode; - x = ktree; - while (x != root && x->parent->red == RED_RED) + x = knode; + while (x != tree->root && x->parent->red == RED_RED) { pp = x->parent->parent; if (x->parent == pp->left) @@ -519,12 +543,12 @@ K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K if (x == x->parent->right) { x = x->parent; - root = left_rotate(root, x); + tree->root = left_rotate(tree->root, x); pp = x->parent->parent; } x->parent->red = RED_BLACK; pp->red = RED_RED; - root = right_rotate(root, pp); + tree->root = right_rotate(tree->root, pp); } } else @@ -542,45 +566,49 @@ K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K if (x == x->parent->left) { x = x->parent; - root = right_rotate(root, x); + tree->root = right_rotate(tree->root, x); pp = x->parent->parent; } x->parent->red = RED_BLACK; pp->red = RED_RED; - root = left_rotate(root, pp); + tree->root = left_rotate(tree->root, pp); } } } } - root->red = RED_BLACK; - -//check_ktree(root, "root->red = RED_BLACK; - return(root); +//check_ktree(tree, "root == NULL) + FAIL("%s", "FINDNULL find tree->root is NULL"); - while (ktree->isNil == No && cmp != 0) + knode = tree->root; + + while (knode->isNil == No && cmp != 0) { - if ((cmp = (*cmp_funct)(ktree->data, data))) + if ((cmp = tree->cmp_funct(knode->data, data))) { if (cmp > 0) - ktree = ktree->left; + knode = knode->left; else - ktree = ktree->right; + knode = knode->right; } } - if (ktree->isNil == No) + if (knode->isNil == No) { - *ctx = ktree; - return(ktree->data); + *ctx = knode; + return(knode->data); } else { @@ -589,30 +617,35 @@ K_ITEM *_find_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, } } -K_ITEM *_find_after_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS) +K_ITEM *_find_after_in_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - K_TREE *old = NULL; + K_NODE *knode, *old = NULL; cmp_t cmp = -1, oldcmp = -1; - if (ktree == NULL) - FAIL("%s", "FINDNULL find_after ktree is NULL"); + if (tree == NULL) + FAIL("%s", "FINDNULL find_after tree is NULL"); + + if (tree->root == NULL) + FAIL("%s", "FINDNULL find_after tree->root is NULL"); - while (ktree->isNil == No && cmp != 0) + knode = tree->root; + + while (knode->isNil == No && cmp != 0) { - if ((cmp = (*cmp_funct)(ktree->data, data))) + if ((cmp = tree->cmp_funct(knode->data, data))) { - old = ktree; + old = knode; oldcmp = cmp; if (cmp > 0) - ktree = ktree->left; + knode = knode->left; else - ktree = ktree->right; + knode = knode->right; } } - if (ktree->isNil == No) + if (knode->isNil == No) { - *ctx = ktree; + *ctx = knode; return next_in_ktree(ctx); } else @@ -634,30 +667,35 @@ K_ITEM *_find_after_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_I } } -K_ITEM *_find_before_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS) +K_ITEM *_find_before_in_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS) { - K_TREE *old = NULL; + K_NODE *knode, *old = NULL; cmp_t cmp = 1, oldcmp = 1; - if (ktree == NULL) - FAIL("%s", "FINDNULL find_before ktree is NULL"); + if (tree == NULL) + FAIL("%s", "FINDNULL find_before tree is NULL"); + + if (tree->root == NULL) + FAIL("%s", "FINDNULL find_before tree->root is NULL"); + + knode = tree->root; - while (ktree->isNil == No && cmp != 0) + while (knode->isNil == No && cmp != 0) { - if ((cmp = (*cmp_funct)(ktree->data, data))) + if ((cmp = tree->cmp_funct(knode->data, data))) { - old = ktree; + old = knode; oldcmp = cmp; if (cmp > 0) - ktree = ktree->left; + knode = knode->left; else - ktree = ktree->right; + knode = knode->right; } } - if (ktree->isNil == No) + if (knode->isNil == No) { - *ctx = ktree; + *ctx = knode; return prev_in_ktree(ctx); } else @@ -679,9 +717,9 @@ K_ITEM *_find_before_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ } } -static K_TREE *removeFixup(K_TREE *root, K_TREE *fix) +static K_NODE *removeFixup(K_NODE *root, K_NODE *fix) { - K_TREE *w = NULL; + K_NODE *w = NULL; while (fix != root && fix->red != RED_RED) { @@ -758,37 +796,40 @@ static K_TREE *removeFixup(K_TREE *root, K_TREE *fix) return root; } -// Does this work OK when you remove the last element in the ktree? +// Does this work OK when you remove the last element in the tree? // It should return the root as 'nil' -K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS) +void _remove_from_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS) { K_TREE_CTX tmpctx[1]; - K_TREE *found; + K_NODE *found; K_ITEM *fdata; - K_TREE *x, *y, *nil2; + K_NODE *x, *y, *nil2; // cmp_t cmp; int yred; -//check_ktree(root, ">remove", NULL, 1, 1, 1, KTREE_FFL_PASS); +//check_ktree(tree, ">remove", NULL, 1, 1, 1, KTREE_FFL_PASS); - if (root == NULL) - FAIL("%s", "REMNULL remove ktree is NULL"); + if (tree == NULL) + FAIL("%s", "REMNULL remove tree is NULL"); - if (root->isNil == Yo) + if (tree->root == NULL) + FAIL("%s", "REMNULL remove tree->root is NULL"); + + if (tree->root->isNil == Yo) { *ctx = NULL; - return(root); + return; } - if (root->parent->isNil == No) - FAIL("%s", "REMROOT remove root isn't the root"); + if (tree->root->parent->isNil == No) + FAIL("%s", "REMROOT remove tree->root isn't the root"); - fdata = find_in_ktree(root, data, cmp_funct, ctx); + fdata = find_in_ktree(tree, data, ctx); if (fdata == NULL) - return(root); + return; - if (cmp_funct(fdata, data) != 0) + if (tree->cmp_funct(fdata, data) != 0) FAIL("%s", "BADFIND cmp(found, remove) != 0"); found = *ctx; @@ -819,14 +860,14 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM nil2 = NULL; else { - nil2 = new_ktree(); + nil2 = _new_knode(KTREE_FFL_PASS); x = nil2; } x->parent = y->parent; if (x->parent->isNil == Yo) - root = x; + tree->root = x; else { if (x->parent->left == y) @@ -837,8 +878,8 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM if (y != found) { - if (root == found) - root = y; + if (tree->root == found) + tree->root = y; if (x == found) x = y; @@ -864,7 +905,7 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM } if (yred != RED_RED) - root = removeFixup(root, x); + tree->root = removeFixup(tree->root, x); if (nil2 != NULL) { @@ -874,8 +915,8 @@ K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM if (nil2->parent->isNil == No && nil2->parent->right == nil2) nil2->parent->right = nil; - if (root == nil2) - root = nil; + if (tree->root == nil2) + tree->root = nil; /* if (dbg != 0) @@ -889,24 +930,24 @@ DBG("@remove nil2->left wasn't nil!!!\n"); DBG("@remove nil2->right wasn't nil!!!\n"); } cmp = 0; - fdata = first_in_ktree(root, tmpctx);; + fdata = first_in_ktree(tree, tmpctx);; while (fdata != NULL) { cmp++; x = *tmpctx; if (x == nil2) { -DBG("@remove found nil2 in ktree %f!!!\n", cmp); +DBG("@remove found nil2 in ktree %d!!!\n", (int)cmp); } else if (x->left == nil2) { -DBG("@remove found nil2 in ktree(left) %f!!!\n", cmp); +DBG("@remove found nil2 in ktree(left) %d!!!\n", (int)cmp); } else if (x->right == nil2) { -DBG("@remove found nil2 in ktree(right) %f!!!\n", cmp); +DBG("@remove found nil2 in ktree(right) %d!!!\n", (int)cmp); } fdata = next_in_ktree(tmpctx);; @@ -920,10 +961,10 @@ DBG("@remove found nil2 in ktree(right) %f!!!\n", cmp); if (dbg != 0) { cmp = 0; - fdata = first_in_ktree(root, tmpctx);; + fdata = first_in_ktree(tree, tmpctx);; while (fdata != NULL) { - if (cmp_funct(fdata, root->data) < 0) + if (tree->cmp_funct(fdata, tree->root->data) < 0) cmp--; else cmp++; @@ -932,52 +973,48 @@ if (dbg != 0) } if (cmp < -10 || cmp > 10) { -DBG("@remove after balance=%f :(\n", cmp); +DBG("@remove after balance=%d :(\n", (int)cmp); } } */ -//check_ktree(root, "data != NULL && free_funct) - (*free_funct)(ktree->data); + if (knode->data != NULL && free_funct) + free_funct(knode->data); - free_ktree_sub(ktree->left, free_funct); - free_ktree_sub(ktree->right, free_funct); + free_ktree_sub(knode->left, free_funct); + free_ktree_sub(knode->right, free_funct); - free(ktree); + free(knode); } } -K_TREE *_free_ktree(K_TREE *ktree, void (*free_funct)(void *), KTREE_FFL_ARGS) +void _free_ktree(K_TREE *tree, void (*free_funct)(void *), KTREE_FFL_ARGS) { - if (ktree == NULL) - FAIL("%s", "FREENULL free NULL ktree"); - - if (ktree->parent != NULL && ktree->parent != nil) - FAIL("%s", "FREENOTROOT free ktree not root"); + if (tree == NULL) + FAIL("%s", "FREENULL free NULL tree"); - free_ktree_sub(ktree, free_funct); + if (tree->root->parent != NULL && tree->root->parent != nil) + FAIL("%s", "FREENOTROOT free tree->root not root"); - return(nil); + free_ktree_sub(tree->root, free_funct); } diff --git a/src/ktree.h b/src/ktree.h index 0721610a..bf388c92 100644 --- a/src/ktree.h +++ b/src/ktree.h @@ -1,5 +1,5 @@ /* - * Copyright 1995-2014 Andrew Smith + * Copyright 1995-2015 Andrew Smith * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free @@ -34,45 +34,54 @@ #define CMP_BIGINT CMP_BIG #define CMP_DOUBLE CMP_BIG -typedef struct ktree +typedef struct knode { bool isNil; bool red; - struct ktree *parent; - struct ktree *left; - struct ktree *right; + struct knode *parent; + struct knode *left; + struct knode *right; K_ITEM *data; long test; +} K_NODE; + +typedef struct ktree +{ + K_NODE *root; + cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *); } K_TREE; typedef void *K_TREE_CTX; -extern K_TREE *_new_ktree(KTREE_FFL_ARGS); -#define new_ktree() _new_ktree(KLIST_FFL_HERE) -extern void _dump_ktree(K_TREE *root, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS); -#define dump_ktree(_root, _dsp_funct) _dump_ktree(_root, _dsp_funct, KLIST_FFL_HERE) -extern void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL_ARGS); -#define dsp_ktree(_list, _root, _filename, _msg) _dsp_ktree(_list, _root, _filename, _msg, KLIST_FFL_HERE) -extern K_ITEM *_first_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS); -#define first_in_ktree(_root, _ctx) _first_in_ktree(_root, _ctx, KLIST_FFL_HERE) -extern K_ITEM *_last_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS); -#define last_in_ktree(_root, _ctx) _last_in_ktree(_root, _ctx, KLIST_FFL_HERE) +extern K_TREE *_new_ktree(cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS); +#define new_ktree(_cmp_funct) _new_ktree(_cmp_funct, KLIST_FFL_HERE) +extern void _dump_ktree(K_TREE *tree, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS); +#define dump_ktree(_tree, _dsp_funct) _dump_ktree(_tree, _dsp_funct, KLIST_FFL_HERE) +extern void _dsp_ktree(K_LIST *list, K_TREE *tree, char *filename, char *msg, KTREE_FFL_ARGS); +#define dsp_ktree(_list, _tree, _filename, _msg) _dsp_ktree(_list, _tree, _filename, _msg, KLIST_FFL_HERE) +extern K_ITEM *_first_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +#define first_in_ktree(_tree, _ctx) _first_in_ktree(_tree, _ctx, KLIST_FFL_HERE) +extern K_ITEM *_last_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +#define last_in_ktree(_tree, _ctx) _last_in_ktree(_tree, _ctx, KLIST_FFL_HERE) extern K_ITEM *_next_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS); #define next_in_ktree(_ctx) _next_in_ktree(_ctx, KLIST_FFL_HERE) extern K_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS); #define prev_in_ktree(_ctx) _prev_in_ktree(_ctx, KLIST_FFL_HERE) -extern K_TREE *_add_to_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_func)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS); -#define add_to_ktree(_root, _data, _cmp_func) _add_to_ktree(_root, _data, _cmp_func, KLIST_FFL_HERE) -extern K_ITEM *_find_in_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); -#define find_in_ktree(_root, _data, _cmp_funct, _ctx) _find_in_ktree(_root, _data, _cmp_funct, _ctx, KLIST_FFL_HERE) -extern K_ITEM *_find_after_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); -#define find_after_in_ktree(_ktree, _data, _cmp_funct, _ctx) _find_after_in_ktree(_ktree, _data, _cmp_funct, _ctx, KLIST_FFL_HERE) -extern K_ITEM *_find_before_in_ktree(K_TREE *ktree, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); -#define find_before_in_ktree(_ktree, _data, _cmp_funct, _ctx) _find_before_in_ktree(_ktree, _data, _cmp_funct, _ctx, KLIST_FFL_HERE) -extern K_TREE *_remove_from_ktree(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); -extern K_TREE *_remove_from_ktree_free(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS); -#define remove_from_ktree(_root, _data, _cmp_funct) _remove_from_ktree_free(_root, _data, _cmp_funct, KLIST_FFL_HERE) -extern K_TREE *_free_ktree(K_TREE *root, void (*free_funct)(void *), KTREE_FFL_ARGS); -#define free_ktree(_root, _free_funct) _free_ktree(_root, _free_funct, KLIST_FFL_HERE) +extern void _add_to_ktree(K_TREE *tree, K_ITEM *data, KTREE_FFL_ARGS); +#define add_to_ktree(_tree, _data) _add_to_ktree(_tree, _data, KLIST_FFL_HERE) +extern K_ITEM *_find_in_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +#define find_in_ktree(_tree, _data, _ctx) _find_in_ktree(_tree, _data, _ctx, KLIST_FFL_HERE) +extern K_ITEM *_find_after_in_ktree(K_TREE *ktree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +#define find_after_in_ktree(_ktree, _data, _ctx) _find_after_in_ktree(_ktree, _data, _ctx, KLIST_FFL_HERE) +extern K_ITEM *_find_before_in_ktree(K_TREE *ktree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +#define find_before_in_ktree(_ktree, _data, _ctx) _find_before_in_ktree(_ktree, _data, _ctx, KLIST_FFL_HERE) +extern void _remove_from_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS); +extern void _remove_from_ktree_free(K_TREE *tree, K_ITEM *data, KTREE_FFL_ARGS); +#define remove_from_ktree(_tree, _data) _remove_from_ktree_free(_tree, _data, KLIST_FFL_HERE) +extern void _free_ktree(K_TREE *tree, void (*free_funct)(void *), KTREE_FFL_ARGS); +#define free_ktree(_tree, _free_funct) do { \ + _free_ktree(_tree, _free_funct, KLIST_FFL_HERE); \ + _tree = NULL; \ + } while (0) #endif From 885be5d715b30bda134fcacefbd721852be26a42 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 15 Sep 2015 12:42:30 +1000 Subject: [PATCH 02/10] ckdb/php - add PPS calculations for shifts --- pool/base.php | 7 +++-- pool/page_shifts.php | 28 ++++++++++++++--- src/ckdb.h | 15 +++++++-- src/ckdb_cmd.c | 13 +++++++- src/ckdb_data.c | 73 ++++++++++++++++++++++++++++++++++++++++++-- src/ckdb_dbio.c | 17 +++++++++-- 6 files changed, 139 insertions(+), 14 deletions(-) diff --git a/pool/base.php b/pool/base.php index 828454a3..3e4c7c02 100644 --- a/pool/base.php +++ b/pool/base.php @@ -126,9 +126,12 @@ function btcfmt($amt) return number_format($amt, 8); } # -function utcd($when) +function utcd($when, $brief = false) { - return gmdate('Y-m-d H:i:s+00', round($when)); + if ($brief) + return gmdate('M-d H:i:s', round($when)); + else + return gmdate('Y-m-d H:i:s+00', round($when)); } # global $sipre; diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 1be0d587..63ae6087 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -4,10 +4,11 @@ function doshifts($data, $user) { $ans = getShifts($user); - $pg = "\n"; + $pg = "Click here to jump to the start of the last payout

"; + $pg .= "
\n"; $pg .= ""; $pg .= ""; - $pg .= ""; + $pg .= ""; $pg .= ""; $pg .= ""; $pg .= ""; @@ -15,6 +16,8 @@ function doshifts($data, $user) $pg .= ""; $pg .= ""; $pg .= ""; + $pg .= ""; + $pg .= ""; $pg .= "\n"; if (($ans['STATUS'] != 'ok') || !isset($ans['prefix_all'])) @@ -28,9 +31,13 @@ function doshifts($data, $user) for ($i = 0; $i < $count; $i++) { $u = ''; + $mark = ''; if (isset($ans['lastpayoutstart:'.$i]) && $ans['lastpayoutstart:'.$i] != '') + { $u = 'u'; + $mark = ''; + } if (($i % 2) == 0) $row = "even$u"; else @@ -52,9 +59,9 @@ function doshifts($data, $user) $btc = ' '; else $btc = ''; - $pg .= ""; + $pg .= ""; $start = $ans['start:'.$i]; - $pg .= ''; + $pg .= ''; $nd = $ans['end:'.$i]; $elapsed = $nd - $start; $pg .= ''; @@ -72,10 +79,23 @@ function doshifts($data, $user) $avgsh = 0; $pg .= ''; $pg .= ''; + $ppsr = (float)$ans['ppsrewarded:'.$i]; + if ($ppsr > 0) + $ppsd = sprintf('%.3e', $ppsr); + else + $ppsd = '0'; + $pg .= ""; + $ppsv = (float)$ans['ppsvalue:'.$i]; + if ($ppsv > 0) + $pgot = number_format(100.0 * $ppsr / $ppsv, 2).'%'; + else + $pgot = '?'; + $pg .= ""; $pg .= "\n"; } } $pg .= "
ShiftStartStart UTCLengthYour DiffInv DiffSharesAvg ShareRewardsPPS*PPS%
$shif$btc$shif$btc$mark'.utcd($start).''.utcd($start, true).''.howmanyhrs($elapsed).''.number_format($avgsh, 2).''.$ans['rewards:'.$i].'$ppsd$pgot
\n"; + $pg .= "* The PPS value unit is satoshis
"; return $pg; } diff --git a/src/ckdb.h b/src/ckdb.h index cefe3dbe..4bb19b5b 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.300" +#define CKDB_VERSION DB_VERSION"-1.301" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -1294,6 +1294,7 @@ typedef struct optioncontrol { // Value it must default to (to work properly) #define OPTIONCONTROL_HEIGHT 1 +#define MAX_HEIGHT 999999999 // Test it here rather than obscuring the #define elsewhere #if ((OPTIONCONTROL_HEIGHT+1) != START_POOL_HEIGHT) @@ -1346,6 +1347,13 @@ extern tv_t last_bc; // current network diff extern double current_ndiff; +// Offset in binary coinbase1 of the block number +#define BLOCKNUM_OFFSET 42 +// Initial block reward (satoshi) +#define REWARD_BASE 5000000000.0 +// How many blocks per halving +#define REWARD_HALVE 210000.0 + // SHARES shares.id.json={...} typedef struct shares { int64_t workinfoid; @@ -2090,6 +2098,8 @@ extern void sequence_report(bool lock); #define REWARDOVERRIDE "MinerReward" +#define PPSOVERRIDE "PPSValue" + // Data free functions (first) #define FREE_ITEM(item) do { } while(0) // TODO: make a macro for all other to use above macro @@ -2264,7 +2274,7 @@ extern K_ITEM *find_first_paypayid(int64_t userid, int64_t payoutid, K_TREE_CTX extern cmp_t cmp_accountbalance(K_ITEM *a, K_ITEM *b); extern K_ITEM *find_accountbalance(int64_t userid); extern cmp_t cmp_optioncontrol(K_ITEM *a, K_ITEM *b); -extern K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height); +extern K_ITEM *find_optioncontrol(char *optionname, const tv_t *now, int32_t height); extern int64_t user_sys_setting(int64_t userid, char *setting_name, int64_t setting_default, tv_t *now); extern cmp_t cmp_workinfo(K_ITEM *a, K_ITEM *b); @@ -2279,6 +2289,7 @@ extern bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code, char *inet, tv_t *cd, tv_t *ss_first, tv_t *ss_last, int64_t *ss_count, int64_t *s_count, int64_t *s_diff); +extern double workinfo_pps(K_ITEM *w_item, int64_t workinfoid, bool lock); extern cmp_t cmp_shares(K_ITEM *a, K_ITEM *b); extern cmp_t cmp_shareerrors(K_ITEM *a, K_ITEM *b); extern void dsp_sharesummary(K_ITEM *item, FILE *stream); diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 0e1c23e7..935adca5 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -5383,6 +5383,16 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, rows, wm->rewards, FLDSEP); APPEND_REALLOC(buf, off, len, tmp); + // Use %.15e -> 16 non-leading-zero decimal places + snprintf(tmp, sizeof(tmp), "ppsvalue:%d=%.15f%c", + rows, wm->pps_value, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + + // Use %.15e -> 16 non-leading-zero decimal places + snprintf(tmp, sizeof(tmp), "ppsrewarded:%d=%.15e%c", + rows, wm->rewarded, FLDSEP); + APPEND_REALLOC(buf, off, len, tmp); + snprintf(tmp, sizeof(tmp), "lastpayoutstart:%d=%s%c", rows, (wm->workinfoidstart == @@ -5431,7 +5441,8 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, snprintf(tmp, sizeof(tmp), "rows=%d%cflds=%s%c", rows, FLDSEP, "markerid,shift,start,end,rewards," - "lastpayoutstart", FLDSEP); + "ppsvalue,ppsrewarded,lastpayoutstart", + FLDSEP); APPEND_REALLOC(buf, off, len, tmp); snprintf(tmp, sizeof(tmp), "arn=%s", "Shifts"); diff --git a/src/ckdb_data.c b/src/ckdb_data.c index a7cc7eb3..720f3a8e 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -1822,7 +1822,7 @@ static bool _reward_override_name(int32_t height, char *buf, size_t siz, } // Must be R or W locked before call -K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height) +K_ITEM *find_optioncontrol(char *optionname, const tv_t *now, int32_t height) { OPTIONCONTROL optioncontrol, *oc, *ocbest; K_TREE_CTX ctx[1]; @@ -1832,6 +1832,9 @@ K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height) * 1) activationdate is <= now * and * 2) height <= specified height (pool.height = current) + * The logic being: if 'now' is after the record activation date + * and 'height' is after the record activation height then + * the record is active * Remember the active record with the newest activationdate * If two records have the same activation date, then * remember the active record with the highest height @@ -2197,6 +2200,61 @@ bye: return ok; } + +// The PPS value of a 1diff share for the given workinfoid +double workinfo_pps(K_ITEM *w_item, int64_t workinfoid, bool lock) +{ + OPTIONCONTROL *optioncontrol; + K_ITEM *oc_item; + char oc_name[TXT_SML+1]; + char coinbase1bin[TXT_SML+1]; + char ndiffbin[TXT_SML+1]; + WORKINFO *workinfo; + double w_diff; + int w_blocknum; + size_t len; + + // Allow optioncontrol override for a given workinfoid + snprintf(oc_name, sizeof(oc_name), PPSOVERRIDE"_%"PRId64, workinfoid); + if (lock) + K_RLOCK(optioncontrol_free); + // No time/height control is used, just find the latest record + oc_item = find_optioncontrol(oc_name, &date_eot, MAX_HEIGHT); + if (lock) + K_RUNLOCK(optioncontrol_free); + + // Value is a floating point double of satoshi + if (oc_item) { + DATA_OPTIONCONTROL(optioncontrol, oc_item); + return atof(optioncontrol->optionvalue); + } + + if (!w_item) { + LOGERR("%s(): missing workinfo %"PRId64, + __func__, workinfoid); + return 0.0; + } + + DATA_WORKINFO(workinfo, w_item); + len = strlen(workinfo->coinbase1); + if (len < (BLOCKNUM_OFFSET * 2 + 4) || (len & 1)) { + LOGERR("%s(): Invalid coinbase1 len %d - " + "should be >= %d and even - for wid %"PRId64, + __func__, (int)len, (BLOCKNUM_OFFSET * 2 + 4), + workinfoid); + return 0.0; + } + + hex2bin(ndiffbin, workinfo->bits, 4); + w_diff = diff_from_nbits(ndiffbin); + hex2bin(coinbase1bin, workinfo->coinbase1 + (BLOCKNUM_OFFSET * 2), + (len - (BLOCKNUM_OFFSET * 2)) >> 1); + w_blocknum = get_sernumber((uchar *)coinbase1bin); + + // BASE halving to determine coinbase reward then divided by difficulty + return(REWARD_BASE * pow(0.5, floor((double)w_blocknum / REWARD_HALVE)) / w_diff); +} + // order by workinfoid asc,userid asc,workername asc,createdate asc,nonce asc,expirydate desc cmp_t cmp_shares(K_ITEM *a, K_ITEM *b) { @@ -4767,6 +4825,10 @@ bool reward_shifts(PAYOUTS *payouts, bool lock, int delta) K_ITEM *wm_item; WORKMARKERS *wm; bool did_one = false; + double payout_pps; + + payout_pps = (double)delta * (double)(payouts->minerreward) / + payouts->diffused; if (lock) K_WLOCK(workmarkers_free); @@ -4781,6 +4843,7 @@ bool reward_shifts(PAYOUTS *payouts, bool lock, int delta) * onto the PROCESSED status if it isn't already processed */ if (CURRENT(&(wm->expirydate))) { wm->rewards += delta; + wm->rewarded += payout_pps; did_one = true; } wm_item = next_in_ktree(ctx); @@ -4792,7 +4855,13 @@ bool reward_shifts(PAYOUTS *payouts, bool lock, int delta) return did_one; } -// (re)calculate rewards for a shift +/* (re)calculate rewards for a shift + * N.B. we don't need to zero/undo a workmarkers rewards directly + * since this is just a counter of how many times it's been rewarded + * and thus if the shift is expired the counter is ignored + * We only need to (re)calculate it when the workmarker is created + * Payouts code processing will increment/decrement all current rewards as + * needed with reward_shifts() when payouts are added/changed/removed */ bool shift_rewards(K_ITEM *wm_item) { PAYOUTS *payouts = NULL; diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index 881f9b3f..db2ed64f 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -6628,12 +6628,13 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add, WHERE_FFL_PASS); goto rollback; } - w_item = find_workinfo(workinfoidend, NULL); + w_item = find_workinfo(workinfoidstart, NULL); if (!w_item) goto rollback; - w_item = find_workinfo(workinfoidstart, NULL); + w_item = find_workinfo(workinfoidend, NULL); if (!w_item) goto rollback; + K_WLOCK(workmarkers_free); wm_item = k_unlink_head(workmarkers_free); K_WUNLOCK(workmarkers_free); @@ -6698,6 +6699,7 @@ bool _workmarkers_process(PGconn *conn, bool already, bool add, PGLOGERR("Insert", rescode, conn); goto rollback; } + row->pps_value = workinfo_pps(w_item, workinfoidend, true); } ok = true; @@ -6837,9 +6839,18 @@ bool workmarkers_fill(PGconn *conn) add_to_ktree(workmarkers_workinfoid_root, item); k_add_head(workmarkers_store, item); + wi_item = find_workinfo(row->workinfoidend, NULL); + if (!wi_item) { + LOGERR("%s(): ERROR workmarkerid %"PRId64 + " wid end %"PRId64" doesn't exist! " + "PPS value will be zero", + __func__, row->markerid, + row->workinfoidend); + } + row->pps_value = workinfo_pps(wi_item, row->workinfoidend, false); + if (dbstatus.newest_workmarker_workinfoid < row->workinfoidend) { dbstatus.newest_workmarker_workinfoid = row->workinfoidend; - wi_item = find_workinfo(row->workinfoidend, NULL); if (!wi_item) { LOGEMERG("%s(): FAILURE workmarkerid %"PRId64 " wid end %"PRId64" doesn't exist! " From ee6f208812ae93b8cbfac5be669b868aa6bc55d2 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 15 Sep 2015 14:07:00 +1000 Subject: [PATCH 03/10] php - shift PPS is 'Rewarded' --- pool/page_shifts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 63ae6087..1753cce9 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -16,7 +16,7 @@ function doshifts($data, $user) $pg .= "Shares"; $pg .= "Avg Share"; $pg .= "Rewards"; - $pg .= "PPS*"; + $pg .= "Rewarded*"; $pg .= "PPS%"; $pg .= "\n"; From 78f17117c0aa50b0edc95e4b6fa3d305e984edd6 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 15 Sep 2015 14:36:56 +1000 Subject: [PATCH 04/10] php - update shift Rewarded unit text --- pool/page_shifts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 1753cce9..598a71a4 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -95,7 +95,7 @@ function doshifts($data, $user) } } $pg .= "\n"; - $pg .= "* The PPS value unit is satoshis
"; + $pg .= "* The Rewarded value unit is satoshis per 1diff share
"; return $pg; } From 8b8eb5dc62dbc59220f45b9be5fe366e355f0772 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 15 Sep 2015 20:27:21 +1000 Subject: [PATCH 05/10] ckdb - shift wasn't flagging workers used if not in the last shift --- src/ckdb.h | 2 +- src/ckdb_cmd.c | 30 ++++++++++++++++++++++++++---- src/ckdb_crypt.c | 6 +++--- 3 files changed, 30 insertions(+), 8 deletions(-) diff --git a/src/ckdb.h b/src/ckdb.h index 4bb19b5b..c34666c5 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.301" +#define CKDB_VERSION DB_VERSION"-1.302" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 935adca5..1f501c2d 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -269,6 +269,7 @@ static char *cmd_2fa(__maybe_unused PGconn *conn, char *cmd, char *id, __func__, st = safe_text_nonull(users->username), users->databits); + FREENULL(st); goto dame; } @@ -5073,6 +5074,7 @@ typedef struct worker_match { bool match; size_t len; bool used; + bool everused; } WM; static char *worker_offset(char *workername) @@ -5158,7 +5160,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, size_t siz = sizeof(reply); char *select = NULL; WM workm[SELECT_LIMIT+1]; - char *buf, *work; + char *buf = NULL, *work, *st = NULL; size_t len, off; tv_t marker_end = { 0L, 0L }; int rows, want, i, where_all; @@ -5198,12 +5200,19 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, if (i_select) select = strdup(transfer_data(i_select)); + APPEND_REALLOC_INIT(buf, off, len); + snprintf(tmp, sizeof(tmp), " select='%s'", + select ? st = safe_text_nonull(select) : "null"); + FREENULL(st); + APPEND_REALLOC(buf, off, len, tmp); + bzero(workm, sizeof(workm)); where_all = select_list(&(workm[0]), select); // Nothing selected = all if (workm[0].worker == NULL) { where_all = 0; workm[0].worker = WORKERS_ALL; + APPEND_REALLOC(buf, off, len, " no workers"); } else { for (i = 0; workm[i].worker; i++) { // N.B. len is only used if match is true @@ -5214,12 +5223,24 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, workm[i].match = true; workm[i].len--; } + snprintf(tmp, sizeof(tmp), " workm[%d]=%s,%s,%d", + i, st = safe_text_nonull(workm[i].worker), + workm[i].match ? "Y" : "N", + (int)(workm[i].len)); + FREENULL(st); + APPEND_REALLOC(buf, off, len, tmp); } } if (where_all >= 0) workm[where_all].used = true; + snprintf(tmp, sizeof(tmp), " where_all=%d", where_all); + APPEND_REALLOC(buf, off, len, tmp); + LOGDEBUG("%s() user=%"PRId64"/%s' %s", + __func__, users->userid, users->username, buf+1); + FREENULL(buf); + APPEND_REALLOC_INIT(buf, off, len); APPEND_REALLOC(buf, off, len, "ok."); INIT_MARKERSUMMARY(&ms_look); @@ -5269,6 +5290,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, (workm[want].match && strncmp(work, workm[want].worker, workm[want].len) == 0) || (!(workm[want].match) && strcmp(workm[want].worker, work) == 0)) { workm[want].used = true; + workm[want].everused = true; ms_add[want].diffacc += ms->diffacc; ms_add[want].diffsta += ms->diffsta; ms_add[want].diffdup += ms->diffdup; @@ -5414,7 +5436,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, K_RUNLOCK(workmarkers_free); for (i = 0; workm[i].worker; i++) { - if (workm[i].used) { + if (workm[i].everused) { snprintf(tmp, sizeof(tmp), "%d_worker=%s%s%c", i, workm[i].worker, @@ -5448,7 +5470,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, snprintf(tmp, sizeof(tmp), "arn=%s", "Shifts"); APPEND_REALLOC(buf, off, len, tmp); for (i = 0; workm[i].worker; i++) { - if (workm[i].used) { + if (workm[i].everused) { snprintf(tmp, sizeof(tmp), ",Worker_%d", i); APPEND_REALLOC(buf, off, len, tmp); } @@ -5457,7 +5479,7 @@ static char *cmd_shifts(__maybe_unused PGconn *conn, char *cmd, char *id, snprintf(tmp, sizeof(tmp), "%carp=", FLDSEP); APPEND_REALLOC(buf, off, len, tmp); for (i = 0; workm[i].worker; i++) { - if (workm[i].used) { + if (workm[i].everused) { snprintf(tmp, sizeof(tmp), ",%d_", i); APPEND_REALLOC(buf, off, len, tmp); } diff --git a/src/ckdb_crypt.c b/src/ckdb_crypt.c index 7ad0109f..e21cddf4 100644 --- a/src/ckdb_crypt.c +++ b/src/ckdb_crypt.c @@ -36,7 +36,7 @@ char *_tob32(USERS *users, unsigned char *bin, size_t len, char *name, if (osiz != olen) { LOGEMERG("%s() of '%s' data for '%s' invalid olen=%d != osiz=%d" WHERE_FFL, - __func__, name, safe_text_nonull(users->username), + __func__, name, st = safe_text_nonull(users->username), (int)olen, (int)osiz, WHERE_FFL_PASS); FREENULL(st); olen = osiz; @@ -59,8 +59,8 @@ char *_tob32(USERS *users, unsigned char *bin, size_t len, char *name, "ch=%d, i=%d j=%d bits=%d bin=0x%s len=%d " "olen=%d" WHERE_FFL, __func__, name, - safe_text_nonull(users->username), ch, i, j, - bits, binstr, (int)len, (int)olen, + st = safe_text_nonull(users->username), + ch, i, j, bits, binstr, (int)len, (int)olen, WHERE_FFL_PASS); FREENULL(st); FREENULL(binstr); From ea1a2c6edfbb7d75c4a836411350ef8920ed2da5 Mon Sep 17 00:00:00 2001 From: kanoi Date: Tue, 15 Sep 2015 22:28:00 +1000 Subject: [PATCH 06/10] ckdb - shifts created after a payout they are in, need rewarded set --- src/ckdb.h | 2 +- src/ckdb_data.c | 12 ++++++++++-- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/src/ckdb.h b/src/ckdb.h index c34666c5..a0963ae9 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.302" +#define CKDB_VERSION DB_VERSION"-1.303" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 720f3a8e..34f29848 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -4861,7 +4861,9 @@ bool reward_shifts(PAYOUTS *payouts, bool lock, int delta) * and thus if the shift is expired the counter is ignored * We only need to (re)calculate it when the workmarker is created * Payouts code processing will increment/decrement all current rewards as - * needed with reward_shifts() when payouts are added/changed/removed */ + * needed with reward_shifts() when payouts are added/changed/removed, + * however, the last shift in a payout can be created after the payout + * is generated so we need to update all from the payouts */ bool shift_rewards(K_ITEM *wm_item) { PAYOUTS *payouts = NULL; @@ -4869,6 +4871,7 @@ bool shift_rewards(K_ITEM *wm_item) WORKMARKERS *wm; K_ITEM *p_item; int rewards = 0; + double pps = 0.0; DATA_WORKMARKERS(wm, wm_item); @@ -4879,14 +4882,19 @@ bool shift_rewards(K_ITEM *wm_item) // a workmarker should not cross a payout boundary while (p_item && payouts->workinfoidstart <= wm->workinfoidstart && wm->workinfoidend <= payouts->workinfoidend) { - if (CURRENT(&(payouts->expirydate))) + if (CURRENT(&(payouts->expirydate))) { rewards++; + pps += (double)(payouts->minerreward) / + payouts->diffused; + } p_item = prev_in_ktree(ctx); DATA_PAYOUTS_NULL(payouts, p_item); } K_RUNLOCK(payouts_free); wm->rewards = rewards; + wm->rewarded = pps; + return (rewards > 0); } From 48eb9a9ee909fbb6889d3fa585b64c5116e5c917 Mon Sep 17 00:00:00 2001 From: kanoi Date: Thu, 17 Sep 2015 02:20:45 +1000 Subject: [PATCH 07/10] php - set shift rewarded format to %.5f --- pool/page_shifts.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pool/page_shifts.php b/pool/page_shifts.php index 598a71a4..2b330647 100644 --- a/pool/page_shifts.php +++ b/pool/page_shifts.php @@ -81,7 +81,7 @@ function doshifts($data, $user) $pg .= ''.$ans['rewards:'.$i].''; $ppsr = (float)$ans['ppsrewarded:'.$i]; if ($ppsr > 0) - $ppsd = sprintf('%.3e', $ppsr); + $ppsd = sprintf('%.5f', $ppsr); else $ppsd = '0'; $pg .= "$ppsd"; From 07d4e9512a1b299ebad7eff66fd77d16daf058f8 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 20 Sep 2015 01:24:32 +1000 Subject: [PATCH 08/10] ckdb/php - separate logging of ckpool msgs vs other, add a web timestamp --- pool/db.php | 6 +++-- src/ckdb.c | 69 ++++++++++++++++++++++++++++---------------------- src/ckdb.h | 16 +++++++++--- src/ckdb_cmd.c | 25 +++++++----------- 4 files changed, 64 insertions(+), 52 deletions(-) diff --git a/pool/db.php b/pool/db.php index a72591be..2b9d4c5e 100644 --- a/pool/db.php +++ b/pool/db.php @@ -139,13 +139,15 @@ function msgEncode($cmd, $id, $fields, $user) { global $send_sep, $fld_sep, $val_sep; - $t = time() % 10000; + $now = time(); + $t = $now % 10000; $msg = $cmd . $send_sep . $id.$t . $send_sep; foreach ($fields as $name => $value) $msg .= $name . $val_sep . $value . $fld_sep; $msg .= 'createcode' . $val_sep . 'php' . $fld_sep; $msg .= 'createby' . $val_sep . $user . $fld_sep; - $msg .= 'createinet' . $val_sep . zeip(); + $msg .= 'createinet' . $val_sep . zeip(). $fld_sep; + $msg .= 'webtime' . $val_sep . $now; adm($user, $msg); return $msg; } diff --git a/src/ckdb.c b/src/ckdb.c index 154916f5..6e4e03a7 100644 --- a/src/ckdb.c +++ b/src/ckdb.c @@ -497,17 +497,18 @@ K_TREE *userinfo_root; K_LIST *userinfo_free; K_STORE *userinfo_store; -static char logname[512]; +static char logname_db[512]; +static char logname_io[512]; static char *dbcode; // low spec version of rotating_log() - no locking -static bool rotating_log_nolock(char *msg) +static bool rotating_log_nolock(char *msg, char *prefix) { char *filename; FILE *fp; bool ok = false; - filename = rotating_filename(logname, time(NULL)); + filename = rotating_filename(prefix, time(NULL)); fp = fopen(filename, "a+e"); if (unlikely(!fp)) { LOGERR("Failed to fopen %s in rotating_log!", filename); @@ -523,7 +524,7 @@ stageleft: return ok; } -static void log_queue_message(char *msg) +static void log_queue_message(char *msg, bool db) { K_ITEM *lq_item; LOGQUEUE *lq; @@ -534,6 +535,7 @@ static void log_queue_message(char *msg) lq->msg = strdup(msg); if (!(lq->msg)) quithere(1, "malloc (%d) OOM", (int)strlen(msg)); + lq->db = db; k_add_tail(logqueue_store, lq_item); K_WUNLOCK(logqueue_free); } @@ -2518,12 +2520,18 @@ static enum cmd_values breakdown(K_ITEM **ml_item, char *buf, tv_t *now, } if (ckdb_cmds[msgline->which_cmds].cmd_val == CMD_END) { + LOGQUE(buf, false); LOGERR("Listener received unknown command: '%.42s...", st2 = safe_text(buf)); FREENULL(st2); goto nogood; } + if (ckdb_cmds[msgline->which_cmds].access & ACCESS_POOL) + LOGQUE(buf, true); + else + LOGQUE(buf, false); + if (noid) { if (ckdb_cmds[msgline->which_cmds].noid) { free(cmdptr); @@ -3614,7 +3622,8 @@ static void *logger(__maybe_unused void *arg) setnow(&now); snprintf(buf, sizeof(buf), "logstart.%ld,%ld", now.tv_sec, now.tv_usec); - LOGFILE(buf); + LOGFILE(buf, logname_db); + LOGFILE(buf, logname_io); while (!everyone_die) { K_WLOCK(logqueue_free); @@ -3622,7 +3631,10 @@ static void *logger(__maybe_unused void *arg) K_WUNLOCK(logqueue_free); while (lq_item) { DATA_LOGQUEUE(lq, lq_item); - LOGFILE(lq->msg); + if (lq->db) + LOGFILE(lq->msg, logname_db); + else + LOGFILE(lq->msg, logname_io); FREENULL(lq->msg); K_WLOCK(logqueue_free); @@ -3641,14 +3653,18 @@ static void *logger(__maybe_unused void *arg) setnow(&now); snprintf(buf, sizeof(buf), "logstopping.%d.%ld,%ld", count, now.tv_sec, now.tv_usec); - LOGFILE(buf); + LOGFILE(buf, logname_db); + LOGFILE(buf, logname_io); if (count) LOGERR("%s", buf); lq_item = logqueue_store->head; copy_tv(&then, &now); while (lq_item) { DATA_LOGQUEUE(lq, lq_item); - LOGFILE(lq->msg); + if (lq->db) + LOGFILE(lq->msg, logname_db); + else + LOGFILE(lq->msg, logname_io); FREENULL(lq->msg); count--; setnow(&now); @@ -3666,7 +3682,8 @@ static void *logger(__maybe_unused void *arg) setnow(&now); snprintf(buf, sizeof(buf), "logstop.%ld,%ld", now.tv_sec, now.tv_usec); - LOGFILE(buf); + LOGFILE(buf, logname_db); + LOGFILE(buf, logname_io); LOGWARNING("%s", buf); return NULL; @@ -3687,8 +3704,7 @@ static void *socketer(__maybe_unused void *arg) proc_instance_t *pi = (proc_instance_t *)arg; unixsock_t *us = &pi->us; char *end, *ans = NULL, *rep = NULL, *buf = NULL, *dot; - char *last_auth = NULL, *reply_auth = NULL; - char *last_addrauth = NULL, *reply_addrauth = NULL; + // No dup check for pool stats, the SEQ code will handle that char *last_chkpass = NULL, *reply_chkpass = NULL; char *last_adduser = NULL, *reply_adduser = NULL; char *last_newpass = NULL, *reply_newpass = NULL; @@ -3768,10 +3784,7 @@ static void *socketer(__maybe_unused void *arg) dup = false; show_dup = true; // These are ordered approximately most likely first - if (last_auth && strcmp(last_auth, buf) == 0) { - reply_last = reply_auth; - dup = true; - } else if (last_chkpass && strcmp(last_chkpass, buf) == 0) { + if (last_chkpass && strcmp(last_chkpass, buf) == 0) { reply_last = reply_chkpass; dup = true; } else if (last_adduser && strcmp(last_adduser, buf) == 0) { @@ -3783,9 +3796,6 @@ static void *socketer(__maybe_unused void *arg) } else if (last_newid && strcmp(last_newid, buf) == 0) { reply_last = reply_newid; dup = true; - } else if (last_addrauth && strcmp(last_addrauth, buf) == 0) { - reply_last = reply_addrauth; - dup = true; } else if (last_userset && strcmp(last_userset, buf) == 0) { reply_last = reply_userset; dup = true; @@ -3814,7 +3824,8 @@ static void *socketer(__maybe_unused void *arg) *dot = '\0'; snprintf(reply, sizeof(reply), "%s%ld,%ld.%s", LOGDUP, now.tv_sec, now.tv_usec, duptype); - LOGQUE(reply); + // dup cant be pool + LOGQUE(reply, false); if (show_dup) LOGWARNING("Duplicate '%s' message received", duptype); else @@ -3823,7 +3834,6 @@ static void *socketer(__maybe_unused void *arg) int seqentryflags = SE_SOCKET; if (!reload_queue_complete) seqentryflags = SE_EARLYSOCK; - LOGQUE(buf); cmdnum = breakdown(&ml_item, buf, &now, seqentryflags); DATA_MSGLINE(msgline, ml_item); replied = false; @@ -3956,12 +3966,6 @@ static void *socketer(__maybe_unused void *arg) send_unix_msg(sockd, rep); FREENULL(ans); switch (cmdnum) { - case CMD_AUTH: - STORELASTREPLY(auth); - break; - case CMD_ADDRAUTH: - STORELASTREPLY(addrauth); - break; case CMD_CHKPASS: STORELASTREPLY(chkpass); break; @@ -4233,7 +4237,6 @@ static void reload_line(PGconn *conn, char *filename, uint64_t count, char *buf) __func__, count); } - LOGQUE(buf); // ml_item is set for all but CMD_REPLY cmdnum = breakdown(&ml_item, buf, &now, SE_RELOAD); DATA_MSGLINE(msgline, ml_item); @@ -4444,7 +4447,8 @@ static bool reload_from(tv_t *start) copy_tv(&begin, &now); tvs_to_buf(&now, run, sizeof(run)); snprintf(reload_buf, MAX_READ, "reload.%s.s0", run); - LOGQUE(reload_buf); + LOGQUE(reload_buf, true); + LOGQUE(reload_buf, false); conn = dbconnect(); @@ -4537,7 +4541,8 @@ static bool reload_from(tv_t *start) diff = 1; snprintf(reload_buf, MAX_READ, "reload.%s.%"PRIu64, run, total); - LOGQUE(reload_buf); + LOGQUE(reload_buf, true); + LOGQUE(reload_buf, false); LOGWARNING("%s(): read %d file%s, total %"PRIu64" line%s %.2f/s", __func__, processing, processing == 1 ? "" : "s", @@ -5582,7 +5587,11 @@ int main(int argc, char **argv) quit(1, "Failed to open log file %s", buf); ckp.logfd = fileno(ckp.logfp); - snprintf(logname, sizeof(logname), "%s%s-db%s-", + // -db is ckpool messages + snprintf(logname_db, sizeof(logname_db), "%s%s-db%s-", + ckp.logdir, ckp.name, dbcode); + // -io is everything else + snprintf(logname_io, sizeof(logname_io), "%s%s-io%s-", ckp.logdir, ckp.name, dbcode); setnow(&now); diff --git a/src/ckdb.h b/src/ckdb.h index a0963ae9..85930c7b 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.303" +#define CKDB_VERSION DB_VERSION"-1.310" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -438,8 +438,8 @@ enum cmd_values { // CCLs are every ... #define ROLL_S 3600 -#define LOGQUE(_msg) log_queue_message(_msg) -#define LOGFILE(_msg) rotating_log_nolock(_msg) +#define LOGQUE(_msg, _db) log_queue_message(_msg, _db) +#define LOGFILE(_msg, _prefix) rotating_log_nolock(_msg, _prefix) #define LOGDUP "dup." // *** @@ -711,6 +711,7 @@ enum cmd_values { // LOGQUEUE typedef struct logqueue { char *msg; + bool db; } LOGQUEUE; #define ALLOC_LOGQUEUE 1024 @@ -2608,6 +2609,13 @@ extern bool check_db_version(PGconn *conn); // *** ckdb_cmd.c // *** +// TODO: limit access by having seperate sockets for each +#define ACCESS_POOL (1 << 0) +#define ACCESS_SYSTEM (1 << 1) +#define ACCESS_WEB (1 << 2) +#define ACCESS_PROXY (1 << 3) +#define ACCESS_CKDB (1 << 4) + struct CMDS { enum cmd_values cmd_val; char *cmd_str; @@ -2616,7 +2624,7 @@ struct CMDS { char *(*func)(PGconn *, char *, char *, tv_t *, char *, char *, char *, tv_t *, K_TREE *); enum seq_num seq; - char *access; + int access; }; extern struct CMDS ckdb_cmds[]; diff --git a/src/ckdb_cmd.c b/src/ckdb_cmd.c index 1f501c2d..45ac8393 100644 --- a/src/ckdb_cmd.c +++ b/src/ckdb_cmd.c @@ -6413,13 +6413,6 @@ static char *cmd_btcset(__maybe_unused PGconn *conn, char *cmd, char *id, return strdup(buf); } -// TODO: limit access by having seperate sockets for each -#define ACCESS_POOL "p" -#define ACCESS_SYSTEM "s" -#define ACCESS_WEB "w" -#define ACCESS_PROXY "x" -#define ACCESS_CKDB "c" - /* The socket command format is as follows: * Basic structure: * cmd.ID.fld1=value1 FLDSEP fld2=value2 FLDSEP fld3=... @@ -6482,8 +6475,8 @@ static char *cmd_btcset(__maybe_unused PGconn *conn, char *cmd, char *id, // cmd_val cmd_str noid createdate func seq access struct CMDS ckdb_cmds[] = { { CMD_TERMINATE, "terminate", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM }, - { CMD_PING, "ping", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM ACCESS_POOL ACCESS_WEB }, - { CMD_VERSION, "version", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM ACCESS_POOL ACCESS_WEB }, + { CMD_PING, "ping", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, + { CMD_VERSION, "version", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, { CMD_LOGLEVEL, "loglevel", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM }, { CMD_FLUSH, "flush", true, false, NULL, SEQ_NONE, ACCESS_SYSTEM }, { CMD_SHARELOG, STR_WORKINFO, false, true, cmd_sharelog, SEQ_WORKINFO, ACCESS_POOL }, @@ -6516,15 +6509,15 @@ struct CMDS ckdb_cmds[] = { { CMD_GETOPTS, "getopts", false, false, cmd_getopts, SEQ_NONE, ACCESS_WEB }, { CMD_SETOPTS, "setopts", false, false, cmd_setopts, SEQ_NONE, ACCESS_WEB }, { CMD_DSP, "dsp", false, false, cmd_dsp, SEQ_NONE, ACCESS_SYSTEM }, - { CMD_STATS, "stats", true, false, cmd_stats, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, - { CMD_PPLNS, "pplns", false, false, cmd_pplns, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, - { CMD_PPLNS2, "pplns2", false, false, cmd_pplns2, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, + { CMD_STATS, "stats", true, false, cmd_stats, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, + { CMD_PPLNS, "pplns", false, false, cmd_pplns, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, + { CMD_PPLNS2, "pplns2", false, false, cmd_pplns2, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, { CMD_PAYOUTS, "payouts", false, false, cmd_payouts, SEQ_NONE, ACCESS_SYSTEM }, - { CMD_MPAYOUTS, "mpayouts", false, false, cmd_mpayouts, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, - { CMD_SHIFTS, "shifts", false, false, cmd_shifts, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, - { CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, + { CMD_MPAYOUTS, "mpayouts", false, false, cmd_mpayouts, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, + { CMD_SHIFTS, "shifts", false, false, cmd_shifts, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, + { CMD_USERSTATUS,"userstatus", false, false, cmd_userstatus, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, { CMD_MARKS, "marks", false, false, cmd_marks, SEQ_NONE, ACCESS_SYSTEM }, - { CMD_PSHIFT, "pshift", false, false, cmd_pshift, SEQ_NONE, ACCESS_SYSTEM ACCESS_WEB }, + { CMD_PSHIFT, "pshift", false, false, cmd_pshift, SEQ_NONE, ACCESS_SYSTEM | ACCESS_WEB }, { CMD_SHSTA, "shsta", true, false, cmd_shsta, SEQ_NONE, ACCESS_SYSTEM }, { CMD_USERINFO, "userinfo", false, false, cmd_userinfo, SEQ_NONE, ACCESS_WEB }, { CMD_BTCSET, "btcset", false, false, cmd_btcset, SEQ_NONE, ACCESS_SYSTEM }, From e4f244eee6b7d22ae4f6a9a230df5ade02bafe97 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 20 Sep 2015 14:37:45 +1000 Subject: [PATCH 09/10] php - display the elapsed time of the worker share rate --- pool/page_workers.php | 20 +++++++++++++------- 1 file changed, 13 insertions(+), 7 deletions(-) diff --git a/pool/page_workers.php b/pool/page_workers.php index 07987311..adf5ebf0 100644 --- a/pool/page_workers.php +++ b/pool/page_workers.php @@ -11,9 +11,10 @@ function worktitle($data, $user) $pg .= 'Shares'; $pg .= "<$r id=srtdiff data-sf=r4>:Diff"; $pg .= "<$r id=srtshrate data-sf=r5>:Share Rate"; - $pg .= "<$r id=srtinv data-sf=r6>:Invalid"; + $pg .= '«Elapsed'; + $pg .= "<$r id=srtinv data-sf=r7>:Invalid"; $pg .= 'Block %'; - $pg .= "<$r id=srtrate data-sf=r8>:Hash Rate"; + $pg .= "<$r id=srtrate data-sf=r9>:Hash Rate"; $pg .= "\n"; return $pg; } @@ -46,9 +47,10 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, } $all = array(); $count = $ans['rows']; + $now = $ans['STAMP']; for ($i = 0; $i < $count; $i++) { - $lst = $ans['STAMP'] - $ans['w_lastshare:'.$i]; + $lst = $now - $ans['w_lastshare:'.$i]; if ($old !== false && $lst > $old) continue; @@ -74,7 +76,7 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, for ($i = 0; $i < $count; $i++) { - $lst = $ans['STAMP'] - $all[$i]['w_lastshare']; + $lst = $now - $all[$i]['w_lastshare']; if ($old !== false && $lst > $old) continue; @@ -105,9 +107,12 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, $acthr = '0'; $acthrv = 0; $actstt = $all[$i]['w_active_start']; - if ($actstt > 0) + if ($actstt <= 0 || ($now - $actstt) < 0) + $actsin = ' '; + else { - $elapsed = $ans['STAMP'] - $actstt; + $actsin = howmanyhrs($now - $actstt); + $elapsed = $now - $actstt; if ($elapsed > 0) { $acthrv = $all[$i]['w_active_diffacc'] * @@ -117,6 +122,7 @@ function workuser($data, $user, &$offset, &$totshare, &$totdiff, } } $pg .= "$acthr"; + $pg .= "$actsin"; $dinv = $all[$i]['w_diffinv']; $dtot = $dacc + $dinv; @@ -178,7 +184,7 @@ function worktotal($offset, $totshare, $totdiff, $totshrate, $totinvalid, $pg .= "$shareacc"; $diffacc = number_format($totdiff, 0); $pg .= "$diffacc"; - $pg .= "$totshrate"; + $pg .= "$totshrate "; $dtot = $totdiff + $totinvalid; if ($dtot > 0) $rej = number_format(100.0 * $totinvalid / $dtot, 3); From be18ff41a9da8f30840aa4826cf48350ab6c20f7 Mon Sep 17 00:00:00 2001 From: kanoi Date: Sun, 20 Sep 2015 16:53:55 +1000 Subject: [PATCH 10/10] ckdb - reset worker share rate every network block change --- src/ckdb.h | 3 ++- src/ckdb_data.c | 17 +++++++++++++++++ src/ckdb_dbio.c | 8 +++++++- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/src/ckdb.h b/src/ckdb.h index 85930c7b..6eadecff 100644 --- a/src/ckdb.h +++ b/src/ckdb.h @@ -55,7 +55,7 @@ #define DB_VLOCK "1" #define DB_VERSION "1.0.2" -#define CKDB_VERSION DB_VERSION"-1.310" +#define CKDB_VERSION DB_VERSION"-1.311" #define WHERE_FFL " - from %s %s() line %d" #define WHERE_FFL_HERE __FILE__, __func__, __LINE__ @@ -2211,6 +2211,7 @@ extern K_ITEM *_find_create_workerstatus(int64_t userid, char *workername, bool create, const char *file2, const char *func2, const int line2, WHERE_FFL_ARGS); +extern void zero_all_active(tv_t *when); extern void workerstatus_ready(); #define workerstatus_update(_auths, _shares, _userstats) \ _workerstatus_update(_auths, _shares, _userstats, WHERE_FFL_HERE) diff --git a/src/ckdb_data.c b/src/ckdb_data.c index 34f29848..3393b99f 100644 --- a/src/ckdb_data.c +++ b/src/ckdb_data.c @@ -913,6 +913,23 @@ static void zero_on_idle(tv_t *when, WORKERSTATUS *workerstatus) workerstatus->active_sharehi = workerstatus->active_sharerej = 0.0; } +void zero_all_active(tv_t *when) +{ + WORKERSTATUS *workerstatus; + K_TREE_CTX ws_ctx[1]; + K_ITEM *ws_item; + + K_WLOCK(workerstatus_free); + ws_item = first_in_ktree(workerstatus_root, ws_ctx); + while (ws_item) { + DATA_WORKERSTATUS(workerstatus, ws_item); + zero_on_idle(when, workerstatus); + ws_item = next_in_ktree(ws_ctx); + } + + K_WUNLOCK(workerstatus_free); +} + /* All data is loaded, now update workerstatus fields TODO: combine set_block_share_counters() with this? */ void workerstatus_ready() diff --git a/src/ckdb_dbio.c b/src/ckdb_dbio.c index db2ed64f..d4a91555 100644 --- a/src/ckdb_dbio.c +++ b/src/ckdb_dbio.c @@ -2623,6 +2623,7 @@ int64_t workinfo_add(PGconn *conn, char *workinfoidstr, char *poolinstance, char *ins; char *params[11 + HISTORYDATECOUNT]; int n, par = 0; + bool zero_active = false; LOGDEBUG("%s(): add", __func__); @@ -2730,14 +2731,19 @@ unparam: if (workinfo_current) { WORKINFO *wic; DATA_WORKINFO(wic, workinfo_current); - if (cmp_height(wic->coinbase1, row->coinbase1) != 0) + if (cmp_height(wic->coinbase1, row->coinbase1) != 0) { copy_tv(&last_bc, cd); + zero_active = true; + } } workinfo_current = item; } K_WUNLOCK(workinfo_free); + if (zero_active) + zero_all_active(cd); + return workinfoid; }