Browse Source

ckdb - make a separate object for a ktree vs the tree nodes

master
kanoi 10 years ago
parent
commit
c3cbef6eca
  1. 120
      src/ckdb.c
  2. 2
      src/ckdb.h
  3. 35
      src/ckdb_cmd.c
  4. 140
      src/ckdb_data.c
  5. 311
      src/ckdb_dbio.c
  6. 453
      src/ktree.c
  7. 65
      src/ktree.h

120
src/ckdb.c

@ -999,43 +999,43 @@ static void alloc_storage()
users_free = k_new_list("Users", sizeof(USERS), users_free = k_new_list("Users", sizeof(USERS),
ALLOC_USERS, LIMIT_USERS, true); ALLOC_USERS, LIMIT_USERS, true);
users_store = k_new_store(users_free); users_store = k_new_store(users_free);
users_root = new_ktree(); users_root = new_ktree(cmp_users);
userid_root = new_ktree(); userid_root = new_ktree(cmp_userid);
useratts_free = k_new_list("Useratts", sizeof(USERATTS), useratts_free = k_new_list("Useratts", sizeof(USERATTS),
ALLOC_USERATTS, LIMIT_USERATTS, true); ALLOC_USERATTS, LIMIT_USERATTS, true);
useratts_store = k_new_store(useratts_free); 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), optioncontrol_free = k_new_list("OptionControl", sizeof(OPTIONCONTROL),
ALLOC_OPTIONCONTROL, ALLOC_OPTIONCONTROL,
LIMIT_OPTIONCONTROL, true); LIMIT_OPTIONCONTROL, true);
optioncontrol_store = k_new_store(optioncontrol_free); 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), workers_free = k_new_list("Workers", sizeof(WORKERS),
ALLOC_WORKERS, LIMIT_WORKERS, true); ALLOC_WORKERS, LIMIT_WORKERS, true);
workers_store = k_new_store(workers_free); workers_store = k_new_store(workers_free);
workers_root = new_ktree(); workers_root = new_ktree(cmp_workers);
paymentaddresses_free = k_new_list("PaymentAddresses", paymentaddresses_free = k_new_list("PaymentAddresses",
sizeof(PAYMENTADDRESSES), sizeof(PAYMENTADDRESSES),
ALLOC_PAYMENTADDRESSES, ALLOC_PAYMENTADDRESSES,
LIMIT_PAYMENTADDRESSES, true); LIMIT_PAYMENTADDRESSES, true);
paymentaddresses_store = k_new_store(paymentaddresses_free); paymentaddresses_store = k_new_store(paymentaddresses_free);
paymentaddresses_root = new_ktree(); paymentaddresses_root = new_ktree(cmp_paymentaddresses);
paymentaddresses_create_root = new_ktree(); paymentaddresses_create_root = new_ktree(cmp_payaddr_create);
paymentaddresses_free->dsp_func = dsp_paymentaddresses; paymentaddresses_free->dsp_func = dsp_paymentaddresses;
payments_free = k_new_list("Payments", sizeof(PAYMENTS), payments_free = k_new_list("Payments", sizeof(PAYMENTS),
ALLOC_PAYMENTS, LIMIT_PAYMENTS, true); ALLOC_PAYMENTS, LIMIT_PAYMENTS, true);
payments_store = k_new_store(payments_free); 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), accountbalance_free = k_new_list("AccountBalance", sizeof(ACCOUNTBALANCE),
ALLOC_ACCOUNTBALANCE, LIMIT_ACCOUNTBALANCE, true); ALLOC_ACCOUNTBALANCE, LIMIT_ACCOUNTBALANCE, true);
accountbalance_store = k_new_store(accountbalance_free); 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), idcontrol_free = k_new_list("IDControl", sizeof(IDCONTROL),
ALLOC_IDCONTROL, LIMIT_IDCONTROL, true); ALLOC_IDCONTROL, LIMIT_IDCONTROL, true);
@ -1044,98 +1044,98 @@ static void alloc_storage()
workinfo_free = k_new_list("WorkInfo", sizeof(WORKINFO), workinfo_free = k_new_list("WorkInfo", sizeof(WORKINFO),
ALLOC_WORKINFO, LIMIT_WORKINFO, true); ALLOC_WORKINFO, LIMIT_WORKINFO, true);
workinfo_store = k_new_store(workinfo_free); workinfo_store = k_new_store(workinfo_free);
workinfo_root = new_ktree(); workinfo_root = new_ktree(cmp_workinfo);
if (!confirm_sharesummary) if (!confirm_sharesummary)
workinfo_height_root = new_ktree(); workinfo_height_root = new_ktree(cmp_workinfo_height);
shares_free = k_new_list("Shares", sizeof(SHARES), shares_free = k_new_list("Shares", sizeof(SHARES),
ALLOC_SHARES, LIMIT_SHARES, true); ALLOC_SHARES, LIMIT_SHARES, true);
shares_store = k_new_store(shares_free); shares_store = k_new_store(shares_free);
shares_early_store = k_new_store(shares_free); shares_early_store = k_new_store(shares_free);
shares_root = new_ktree(); shares_root = new_ktree(cmp_shares);
shares_early_root = new_ktree(); shares_early_root = new_ktree(cmp_shares);
shareerrors_free = k_new_list("ShareErrors", sizeof(SHAREERRORS), shareerrors_free = k_new_list("ShareErrors", sizeof(SHAREERRORS),
ALLOC_SHAREERRORS, LIMIT_SHAREERRORS, true); ALLOC_SHAREERRORS, LIMIT_SHAREERRORS, true);
shareerrors_store = k_new_store(shareerrors_free); shareerrors_store = k_new_store(shareerrors_free);
shareerrors_early_store = k_new_store(shareerrors_free); shareerrors_early_store = k_new_store(shareerrors_free);
shareerrors_root = new_ktree(); shareerrors_root = new_ktree(cmp_shareerrors);
shareerrors_early_root = new_ktree(); shareerrors_early_root = new_ktree(cmp_shareerrors);
sharesummary_free = k_new_list("ShareSummary", sizeof(SHARESUMMARY), sharesummary_free = k_new_list("ShareSummary", sizeof(SHARESUMMARY),
ALLOC_SHARESUMMARY, LIMIT_SHARESUMMARY, true); ALLOC_SHARESUMMARY, LIMIT_SHARESUMMARY, true);
sharesummary_store = k_new_store(sharesummary_free); sharesummary_store = k_new_store(sharesummary_free);
sharesummary_root = new_ktree(); sharesummary_root = new_ktree(cmp_sharesummary);
sharesummary_workinfoid_root = new_ktree(); sharesummary_workinfoid_root = new_ktree(cmp_sharesummary_workinfoid);
sharesummary_free->dsp_func = dsp_sharesummary; sharesummary_free->dsp_func = dsp_sharesummary;
sharesummary_pool_store = k_new_store(sharesummary_free); 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), blocks_free = k_new_list("Blocks", sizeof(BLOCKS),
ALLOC_BLOCKS, LIMIT_BLOCKS, true); ALLOC_BLOCKS, LIMIT_BLOCKS, true);
blocks_store = k_new_store(blocks_free); blocks_store = k_new_store(blocks_free);
blocks_root = new_ktree(); blocks_root = new_ktree(cmp_blocks);
blocks_free->dsp_func = dsp_blocks; blocks_free->dsp_func = dsp_blocks;
miningpayouts_free = k_new_list("MiningPayouts", sizeof(MININGPAYOUTS), miningpayouts_free = k_new_list("MiningPayouts", sizeof(MININGPAYOUTS),
ALLOC_MININGPAYOUTS, LIMIT_MININGPAYOUTS, true); ALLOC_MININGPAYOUTS, LIMIT_MININGPAYOUTS, true);
miningpayouts_store = k_new_store(miningpayouts_free); 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), payouts_free = k_new_list("Payouts", sizeof(PAYOUTS),
ALLOC_PAYOUTS, LIMIT_PAYOUTS, true); ALLOC_PAYOUTS, LIMIT_PAYOUTS, true);
payouts_store = k_new_store(payouts_free); payouts_store = k_new_store(payouts_free);
payouts_root = new_ktree(); payouts_root = new_ktree(cmp_payouts);
payouts_id_root = new_ktree(); payouts_id_root = new_ktree(cmp_payouts_id);
payouts_wid_root = new_ktree(); payouts_wid_root = new_ktree(cmp_payouts_wid);
auths_free = k_new_list("Auths", sizeof(AUTHS), auths_free = k_new_list("Auths", sizeof(AUTHS),
ALLOC_AUTHS, LIMIT_AUTHS, true); ALLOC_AUTHS, LIMIT_AUTHS, true);
auths_store = k_new_store(auths_free); 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), poolstats_free = k_new_list("PoolStats", sizeof(POOLSTATS),
ALLOC_POOLSTATS, LIMIT_POOLSTATS, true); ALLOC_POOLSTATS, LIMIT_POOLSTATS, true);
poolstats_store = k_new_store(poolstats_free); 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), userstats_free = k_new_list("UserStats", sizeof(USERSTATS),
ALLOC_USERSTATS, LIMIT_USERSTATS, true); ALLOC_USERSTATS, LIMIT_USERSTATS, true);
userstats_store = k_new_store(userstats_free); userstats_store = k_new_store(userstats_free);
userstats_eos_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; userstats_free->dsp_func = dsp_userstats;
workerstatus_free = k_new_list("WorkerStatus", sizeof(WORKERSTATUS), workerstatus_free = k_new_list("WorkerStatus", sizeof(WORKERSTATUS),
ALLOC_WORKERSTATUS, LIMIT_WORKERSTATUS, true); ALLOC_WORKERSTATUS, LIMIT_WORKERSTATUS, true);
workerstatus_store = k_new_store(workerstatus_free); 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), markersummary_free = k_new_list("MarkerSummary", sizeof(MARKERSUMMARY),
ALLOC_MARKERSUMMARY, LIMIT_MARKERSUMMARY, true); ALLOC_MARKERSUMMARY, LIMIT_MARKERSUMMARY, true);
markersummary_store = k_new_store(markersummary_free); markersummary_store = k_new_store(markersummary_free);
markersummary_root = new_ktree(); markersummary_root = new_ktree(cmp_markersummary);
markersummary_userid_root = new_ktree(); markersummary_userid_root = new_ktree(cmp_markersummary_userid);
markersummary_free->dsp_func = dsp_markersummary; markersummary_free->dsp_func = dsp_markersummary;
markersummary_pool_store = k_new_store(markersummary_free); 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), workmarkers_free = k_new_list("WorkMarkers", sizeof(WORKMARKERS),
ALLOC_WORKMARKERS, LIMIT_WORKMARKERS, true); ALLOC_WORKMARKERS, LIMIT_WORKMARKERS, true);
workmarkers_store = k_new_store(workmarkers_free); workmarkers_store = k_new_store(workmarkers_free);
workmarkers_root = new_ktree(); workmarkers_root = new_ktree(cmp_workmarkers);
workmarkers_workinfoid_root = new_ktree(); workmarkers_workinfoid_root = new_ktree(cmp_workmarkers_workinfoid);
workmarkers_free->dsp_func = dsp_workmarkers; workmarkers_free->dsp_func = dsp_workmarkers;
marks_free = k_new_list("Marks", sizeof(MARKS), marks_free = k_new_list("Marks", sizeof(MARKS),
ALLOC_MARKS, LIMIT_MARKS, true); ALLOC_MARKS, LIMIT_MARKS, true);
marks_store = k_new_store(marks_free); 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), userinfo_free = k_new_list("UserInfo", sizeof(USERINFO),
ALLOC_USERINFO, LIMIT_USERINFO, true); ALLOC_USERINFO, LIMIT_USERINFO, true);
userinfo_store = k_new_store(userinfo_free); userinfo_store = k_new_store(userinfo_free);
userinfo_root = new_ktree(); userinfo_root = new_ktree(cmp_userinfo);
} }
#define SEQSETMSG(_set, _seqset, _msgtxt, _endtxt) do { \ #define SEQSETMSG(_set, _seqset, _msgtxt, _endtxt) do { \
@ -1179,7 +1179,7 @@ static void alloc_storage()
#define FREE_TREE(_tree) \ #define FREE_TREE(_tree) \
if (_tree ## _root) \ if (_tree ## _root) \
_tree ## _root = free_ktree(_tree ## _root, NULL) \ free_ktree(_tree ## _root, NULL) \
#define FREE_STORE(_list) \ #define FREE_STORE(_list) \
if (_list ## _store) \ if (_list ## _store) \
@ -1487,13 +1487,13 @@ static bool setup_data()
INIT_WORKINFO(&look); INIT_WORKINFO(&look);
look.data = (void *)(&wi); look.data = (void *)(&wi);
// Find the first workinfo for this height // 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) { if (found) {
DATA_WORKINFO(wif, found); DATA_WORKINFO(wif, found);
copy_tv(&last_bc, &(wif->createdate)); copy_tv(&last_bc, &(wif->createdate));
} }
// No longer needed // No longer needed
workinfo_height_root = free_ktree(workinfo_height_root, NULL); free_ktree(workinfo_height_root, NULL);
} }
return true; return true;
@ -2536,7 +2536,7 @@ static enum cmd_values breakdown(K_ITEM **ml_item, char *buf, tv_t *now,
goto nogood; goto nogood;
} }
msgline->trf_root = new_ktree(); msgline->trf_root = new_ktree(cmp_transfer);
msgline->trf_store = k_new_store(transfer_free); msgline->trf_store = k_new_store(transfer_free);
next = data; next = data;
if (next && strncmp(next, JSON_TRANSFER, JSON_TRANSFER_LEN) == 0) { 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); STRNCPYSIZ(transfer->svalue, next, siz+1);
transfer->mvalue = transfer->svalue; transfer->mvalue = transfer->svalue;
} }
msgline->trf_root = add_to_ktree(msgline->trf_root, add_to_ktree(msgline->trf_root, t_item);
t_item, cmp_transfer);
k_add_head(msgline->trf_store, t_item); k_add_head(msgline->trf_store, t_item);
t_item = NULL; 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; transfer->mvalue = transfer->svalue;
// Discard duplicates // Discard duplicates
if (find_in_ktree(msgline->trf_root, t_item, if (find_in_ktree(msgline->trf_root, t_item, ctx)) {
cmp_transfer, ctx)) {
if (transfer->mvalue != transfer->svalue) if (transfer->mvalue != transfer->svalue)
FREENULL(transfer->mvalue); FREENULL(transfer->mvalue);
k_add_head(transfer_free, t_item); k_add_head(transfer_free, t_item);
} else { } else {
msgline->trf_root = add_to_ktree(msgline->trf_root, add_to_ktree(msgline->trf_root, t_item);
t_item,
cmp_transfer);
k_add_head(msgline->trf_store, t_item); k_add_head(msgline->trf_store, t_item);
} }
} }
@ -2935,7 +2931,7 @@ static void summarise_blocks()
K_RLOCK(markersummary_free); K_RLOCK(markersummary_free);
ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look,
cmp_sharesummary_workinfoid, ss_ctx); ss_ctx);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
while (ss_item && sharesummary->workinfoid > wi_start) { while (ss_item && sharesummary->workinfoid > wi_start) {
if (sharesummary->complete[0] == SUMMARY_NEW) { if (sharesummary->complete[0] == SUMMARY_NEW) {
@ -2971,7 +2967,7 @@ static void summarise_blocks()
INIT_WORKMARKERS(&wm_look); INIT_WORKMARKERS(&wm_look);
wm_look.data = (void *)(&lookworkmarkers); wm_look.data = (void *)(&lookworkmarkers);
wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look,
cmp_workmarkers_workinfoid, ctx); ctx);
DATA_WORKMARKERS_NULL(workmarkers, wm_item); DATA_WORKMARKERS_NULL(workmarkers, wm_item);
while (wm_item && while (wm_item &&
CURRENT(&(workmarkers->expirydate)) && CURRENT(&(workmarkers->expirydate)) &&
@ -2995,7 +2991,7 @@ static void summarise_blocks()
INIT_MARKERSUMMARY(&ms_look); INIT_MARKERSUMMARY(&ms_look);
ms_look.data = (void *)(&lookmarkersummary); ms_look.data = (void *)(&lookmarkersummary);
ms_item = find_before_in_ktree(markersummary_root, &ms_look, ms_item = find_before_in_ktree(markersummary_root, &ms_look,
cmp_markersummary, ms_ctx); ms_ctx);
DATA_MARKERSUMMARY_NULL(markersummary, ms_item); DATA_MARKERSUMMARY_NULL(markersummary, ms_item);
while (ms_item && markersummary->markerid == workmarkers->markerid) { while (ms_item && markersummary->markerid == workmarkers->markerid) {
has_ms = true; has_ms = true;
@ -3350,7 +3346,7 @@ static void make_a_shift_mark()
lookworkinfo.expirydate.tv_usec = default_expiry.tv_usec; lookworkinfo.expirydate.tv_usec = default_expiry.tv_usec;
wi_look.data = (void *)(&lookworkinfo); wi_look.data = (void *)(&lookworkinfo);
K_RLOCK(workinfo_free); 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); K_RUNLOCK(workinfo_free);
marks_wid = 0; marks_wid = 0;
used_wid = 0; used_wid = 0;
@ -3394,8 +3390,8 @@ static void make_a_shift_mark()
looksharesummary.workername = EMPTY; looksharesummary.workername = EMPTY;
ss_look.data = (void *)(&looksharesummary); ss_look.data = (void *)(&looksharesummary);
K_RLOCK(sharesummary_free); K_RLOCK(sharesummary_free);
ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_workinfoid_root,
cmp_sharesummary_workinfoid, ss_ctx); &ss_look, ss_ctx);
K_RUNLOCK(sharesummary_free); K_RUNLOCK(sharesummary_free);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
if (ss_item && if (ss_item &&
@ -4815,7 +4811,7 @@ static void compare_summaries(K_TREE *leftsum, char *leftname,
look.data = (void *)(&looksharesummary); look.data = (void *)(&looksharesummary);
total = ok = missing = diff = 0; 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) { while (lss) {
DATA_SHARESUMMARY(l_ss, lss); DATA_SHARESUMMARY(l_ss, lss);
if (l_ss->workinfoid > confirm_last_workinfoid) 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; first_used = l_ss->workinfoid;
last_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); DATA_SHARESUMMARY_NULL(r_ss, rss);
if (!rss) { if (!rss) {
missing++; missing++;
@ -5036,7 +5032,7 @@ static void confirm_reload()
lookblocks.height = confirm_block; lookblocks.height = confirm_block;
lookblocks.blockhash[0] = '\0'; lookblocks.blockhash[0] = '\0';
b_look.data = (void *)(&lookblocks); 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) { if (!b_end_item) {
LOGWARNING("%s(): no DB block height found matching or after %d", LOGWARNING("%s(): no DB block height found matching or after %d",
__func__, confirm_block); __func__, confirm_block);
@ -5049,7 +5045,7 @@ static void confirm_reload()
lookblocks.height = e_blocks->height; lookblocks.height = e_blocks->height;
lookblocks.blockhash[0] = '\0'; lookblocks.blockhash[0] = '\0';
b_look.data = (void *)(&lookblocks); 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) if (!b_begin_item)
confirm_first_workinfoid = 0; confirm_first_workinfoid = 0;
else { else {
@ -5058,7 +5054,7 @@ static void confirm_reload()
lookblocks.height = b_blocks->height; lookblocks.height = b_blocks->height;
lookblocks.blockhash[0] = '\0'; lookblocks.blockhash[0] = '\0';
b_look.data = (void *)(&lookblocks); 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 // Not possible
if (!b_begin_item) if (!b_begin_item)
confirm_first_workinfoid = 0; confirm_first_workinfoid = 0;
@ -5110,7 +5106,7 @@ static void confirm_reload()
lookworkinfo.expirydate.tv_sec = date_begin.tv_sec; lookworkinfo.expirydate.tv_sec = date_begin.tv_sec;
lookworkinfo.expirydate.tv_usec = date_begin.tv_usec; lookworkinfo.expirydate.tv_usec = date_begin.tv_usec;
wi_look.data = (void *)(&lookworkinfo); 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) { if (wi_item) {
DATA_WORKINFO(workinfo, wi_item); DATA_WORKINFO(workinfo, wi_item);
copy_tv(&start, &(workinfo->createdate)); copy_tv(&start, &(workinfo->createdate));
@ -5138,7 +5134,7 @@ static void confirm_reload()
lookworkinfo.expirydate.tv_sec = date_eot.tv_sec; lookworkinfo.expirydate.tv_sec = date_eot.tv_sec;
lookworkinfo.expirydate.tv_usec = date_eot.tv_usec; lookworkinfo.expirydate.tv_usec = date_eot.tv_usec;
wi_look.data = (void *)(&lookworkinfo); 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) { if (wi_item) {
DATA_WORKINFO(workinfo, wi_item); DATA_WORKINFO(workinfo, wi_item);
/* Now find the one after the one we found to determine the /* 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_sec = date_eot.tv_sec;
lookworkinfo.expirydate.tv_usec = date_eot.tv_usec; lookworkinfo.expirydate.tv_usec = date_eot.tv_usec;
wi_look.data = (void *)(&lookworkinfo); 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) { if (wi_item) {
DATA_WORKINFO(workinfo, wi_item); DATA_WORKINFO(workinfo, wi_item);
copy_tv(&confirm_finish, &(workinfo->createdate)); copy_tv(&confirm_finish, &(workinfo->createdate));
@ -5178,9 +5174,9 @@ static void confirm_reload()
sharesummary_save = sharesummary_root; sharesummary_save = sharesummary_root;
workinfo_save = workinfo_root; workinfo_save = workinfo_root;
sharesummary_workinfoid_root = new_ktree(); sharesummary_workinfoid_root = new_ktree(cmp_sharesummary_workinfoid);
sharesummary_root = new_ktree(); sharesummary_root = new_ktree(cmp_sharesummary);
workinfo_root = new_ktree(); workinfo_root = new_ktree(cmp_workinfo);
if (start.tv_sec < DATE_BEGIN) { if (start.tv_sec < DATE_BEGIN) {
start.tv_sec = DATE_BEGIN; start.tv_sec = DATE_BEGIN;

2
src/ckdb.h

@ -55,7 +55,7 @@
#define DB_VLOCK "1" #define DB_VLOCK "1"
#define DB_VERSION "1.0.2" #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 " - from %s %s() line %d"
#define WHERE_FFL_HERE __FILE__, __func__, __LINE__ #define WHERE_FFL_HERE __FILE__, __func__, __LINE__

35
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; row.createdate.tv_usec = date_eot.tv_usec;
INIT_POOLSTATS(&look); INIT_POOLSTATS(&look);
look.data = (void *)(&row); 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) if (!ps)
store = true; store = true;
else { else {
@ -1730,7 +1730,7 @@ static char *cmd_percent(char *cmd, char *id, tv_t *now, USERS *users)
lookworkers.workername[0] = '\0'; lookworkers.workername[0] = '\0';
DATE_ZERO(&(lookworkers.expirydate)); DATE_ZERO(&(lookworkers.expirydate));
w_look.data = (void *)(&lookworkers); 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); DATA_WORKERS_NULL(workers, w_item);
while (w_item && workers->userid == users->userid) { while (w_item && workers->userid == users->userid) {
if (CURRENT(&(workers->expirydate))) { if (CURRENT(&(workers->expirydate))) {
@ -1991,7 +1991,7 @@ static char *cmd_workers(__maybe_unused PGconn *conn, char *cmd, char *id,
lookworkers.workername[0] = '\0'; lookworkers.workername[0] = '\0';
DATE_ZERO(&(lookworkers.expirydate)); DATE_ZERO(&(lookworkers.expirydate));
w_look.data = (void *)(&lookworkers); 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); DATA_WORKERS_NULL(workers, w_item);
rows = 0; rows = 0;
while (w_item && workers->userid == users->userid) { 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); INIT_USERSTATS(&look);
look.data = (void *)(&lookuserstats); look.data = (void *)(&lookuserstats);
K_RLOCK(userstats_free); 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); DATA_USERSTATS_NULL(userstats, us_item);
while (us_item && userstats->userid == users->userid) { while (us_item && userstats->userid == users->userid) {
if (tvdiff(now, &(userstats->statsdate)) < USERSTATS_PER_S) { 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); INIT_BLOCKS(&b_look);
b_look.data = (void *)(&lookblocks); b_look.data = (void *)(&lookblocks);
K_RLOCK(blocks_free); 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) { if (!b_item) {
K_RUNLOCK(blocks_free); K_RUNLOCK(blocks_free);
snprintf(reply, siz, "ERR.no block height %d", height); 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; ss_count = wm_count = ms_count = 0;
mu_store = k_new_store(miningpayouts_free); mu_store = k_new_store(miningpayouts_free);
mu_root = new_ktree(); mu_root = new_ktree(cmp_mu);
looksharesummary.workinfoid = block_workinfoid; looksharesummary.workinfoid = block_workinfoid;
looksharesummary.userid = MAXID; 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(sharesummary_free);
K_RLOCK(workmarkers_free); K_RLOCK(workmarkers_free);
K_RLOCK(markersummary_free); K_RLOCK(markersummary_free);
ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_workinfoid_root,
cmp_sharesummary_workinfoid, ctx); &ss_look, ctx);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
if (ss_item) if (ss_item)
end_workinfoid = sharesummary->workinfoid; 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; lookworkmarkers.workinfoidend = block_workinfoid + 1;
INIT_WORKMARKERS(&wm_look); INIT_WORKMARKERS(&wm_look);
wm_look.data = (void *)(&lookworkmarkers); wm_look.data = (void *)(&lookworkmarkers);
wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, wm_item = find_before_in_ktree(workmarkers_workinfoid_root,
cmp_workmarkers_workinfoid, wm_ctx); &wm_look, wm_ctx);
DATA_WORKMARKERS_NULL(workmarkers, wm_item); DATA_WORKMARKERS_NULL(workmarkers, wm_item);
LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend); LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend);
while (total_diff < diff_want && wm_item && CURRENT(&(workmarkers->expirydate))) { 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; lookmarkersummary.workername = EMPTY;
INIT_MARKERSUMMARY(&ms_look); INIT_MARKERSUMMARY(&ms_look);
ms_look.data = (void *)(&lookmarkersummary); ms_look.data = (void *)(&lookmarkersummary);
ms_item = find_before_in_ktree(markersummary_root, &ms_look, ms_item = find_before_in_ktree(markersummary_root,
cmp_markersummary, ms_ctx); &ms_look, ms_ctx);
DATA_MARKERSUMMARY_NULL(markersummary, ms_item); DATA_MARKERSUMMARY_NULL(markersummary, ms_item);
// add the whole markerid // add the whole markerid
while (ms_item && markersummary->markerid == workmarkers->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 // So web can always verify it received all data
APPEND_REALLOC(buf, off, len, "pplns_last=1"); 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_WLOCK(mu_store);
k_list_transfer_to_head(mu_store, miningpayouts_free); k_list_transfer_to_head(mu_store, miningpayouts_free);
K_WUNLOCK(mu_store); K_WUNLOCK(mu_store);
@ -4441,7 +4441,8 @@ static char *cmd_pplns(__maybe_unused PGconn *conn, char *cmd, char *id,
return buf; return buf;
shazbot: shazbot:
mu_root = free_ktree(mu_root, NULL);
free_ktree(mu_root, NULL);
K_WLOCK(mu_store); K_WLOCK(mu_store);
k_list_transfer_to_head(mu_store, miningpayouts_free); k_list_transfer_to_head(mu_store, miningpayouts_free);
K_WUNLOCK(mu_store); K_WUNLOCK(mu_store);
@ -4494,7 +4495,7 @@ static char *cmd_pplns2(__maybe_unused PGconn *conn, char *cmd, char *id,
INIT_BLOCKS(&b_look); INIT_BLOCKS(&b_look);
b_look.data = (void *)(&lookblocks); b_look.data = (void *)(&lookblocks);
K_RLOCK(blocks_free); 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); K_RUNLOCK(blocks_free);
if (!b_item) { if (!b_item) {
K_RUNLOCK(blocks_free); 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.userid = users->userid;
markersummary.workername = EMPTY; markersummary.workername = EMPTY;
K_RLOCK(markersummary_free); K_RLOCK(markersummary_free);
ms_item = find_after_in_ktree(markersummary_root, &ms_look, ms_item = find_after_in_ktree(markersummary_root,
cmp_markersummary, ms_ctx); &ms_look, ms_ctx);
DATA_MARKERSUMMARY_NULL(ms, ms_item); DATA_MARKERSUMMARY_NULL(ms, ms_item);
while (ms_item && ms->markerid == wm->markerid && while (ms_item && ms->markerid == wm->markerid &&
ms->userid == users->userid) { ms->userid == users->userid) {

140
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); DATA_MSGLINE(msgline, item);
if (msgline->trf_root) if (msgline->trf_root)
msgline->trf_root = free_ktree(msgline->trf_root, NULL); free_ktree(msgline->trf_root, NULL);
if (msgline->trf_store) { if (msgline->trf_store) {
t_item = msgline->trf_store->head; t_item = msgline->trf_store->head;
while (t_item) { while (t_item) {
@ -691,7 +691,7 @@ K_ITEM *find_transfer(K_TREE *trf_root, char *name)
STRNCPY(transfer.name, name); STRNCPY(transfer.name, name);
INIT_TRANSFER(&look); INIT_TRANSFER(&look);
look.data = (void *)(&transfer); 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, 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); INIT_WORKERSTATUS(&look);
look.data = (void *)(&workerstatus); look.data = (void *)(&workerstatus);
K_RLOCK(workerstatus_free); 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); K_RUNLOCK(workerstatus_free);
return find; return find;
} }
@ -876,7 +876,7 @@ K_ITEM *_find_create_workerstatus(int64_t userid, char *workername,
row->userid = userid; row->userid = userid;
STRNCPY(row->workername, workername); 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_add_head(workerstatus_store, ws_item);
K_WUNLOCK(workerstatus_free); K_WUNLOCK(workerstatus_free);
@ -1115,7 +1115,7 @@ K_ITEM *find_users(char *username)
INIT_USERS(&look); INIT_USERS(&look);
look.data = (void *)(&users); 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 // Must be R or W locked before call
@ -1131,7 +1131,7 @@ K_ITEM *find_userid(int64_t userid)
INIT_USERS(&look); INIT_USERS(&look);
look.data = (void *)(&users); 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?) // TODO: endian? (to avoid being all zeros?)
@ -1428,7 +1428,7 @@ K_ITEM *find_useratts(int64_t userid, char *attname)
INIT_USERATTS(&look); INIT_USERATTS(&look);
look.data = (void *)(&useratts); 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 // order by userid asc,workername asc,expirydate desc
@ -1459,7 +1459,7 @@ K_ITEM *find_workers(int64_t userid, char *workername)
INIT_WORKERS(&look); INIT_WORKERS(&look);
look.data = (void *)(&workers); 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) 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); INIT_WORKERS(&look);
look.data = (void *)(&workers); look.data = (void *)(&workers);
// Caller needs to check userid/expirydate if the result != NULL // 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, 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); INIT_PAYMENTADDRESSES(&look);
look.data = (void *)(&paymentaddresses); 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) { if (item) {
DATA_PAYMENTADDRESSES(pa, item); DATA_PAYMENTADDRESSES(pa, item);
if (pa->userid == userid && CURRENT(&(pa->expirydate))) 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); INIT_PAYMENTADDRESSES(&look);
look.data = (void *)(&paymentaddresses); look.data = (void *)(&paymentaddresses);
item = find_after_in_ktree(paymentaddresses_create_root, &look, item = find_after_in_ktree(paymentaddresses_create_root, &look, ctx);
cmp_payaddr_create, ctx);
if (item) { if (item) {
DATA_PAYMENTADDRESSES(pa, item); DATA_PAYMENTADDRESSES(pa, item);
if (pa->userid == userid) 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); INIT_PAYMENTADDRESSES(&look);
look.data = (void *)(&paymentaddresses); 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 /* 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); INIT_PAYMENTS(&look);
look.data = (void *)(&payments); 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) 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); INIT_PAYMENTS(&look);
look.data = (void *)(&payments); look.data = (void *)(&payments);
// userid needs to be checked if item returned != NULL // 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; return item;
} }
@ -1753,7 +1752,7 @@ K_ITEM *find_first_paypayid(int64_t userid, int64_t payoutid, K_TREE_CTX *ctx)
INIT_PAYMENTS(&look); INIT_PAYMENTS(&look);
look.data = (void *)(&payments); look.data = (void *)(&payments);
// userid+payoutid needs to be checked if item returned != NULL // 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; return item;
} }
@ -1777,7 +1776,7 @@ K_ITEM *find_accountbalance(int64_t userid)
INIT_ACCOUNTBALANCE(&look); INIT_ACCOUNTBALANCE(&look);
look.data = (void *)(&accountbalance); look.data = (void *)(&accountbalance);
K_RLOCK(accountbalance_free); 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); K_RUNLOCK(accountbalance_free);
return item; return item;
} }
@ -1853,7 +1852,7 @@ K_ITEM *find_optioncontrol(char *optionname, tv_t *now, int32_t height)
INIT_OPTIONCONTROL(&look); INIT_OPTIONCONTROL(&look);
look.data = (void *)(&optioncontrol); 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; ocbest = NULL;
best = NULL; best = NULL;
while (item) { while (item) {
@ -1989,7 +1988,7 @@ K_ITEM *find_workinfo(int64_t workinfoid, K_TREE_CTX *ctx)
INIT_WORKINFO(&look); INIT_WORKINFO(&look);
look.data = (void *)(&workinfo); look.data = (void *)(&workinfo);
K_RLOCK(workinfo_free); 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); K_RUNLOCK(workinfo_free);
return item; return item;
} }
@ -2010,7 +2009,7 @@ K_ITEM *next_workinfo(int64_t workinfoid, K_TREE_CTX *ctx)
INIT_WORKINFO(&look); INIT_WORKINFO(&look);
look.data = (void *)(&workinfo); look.data = (void *)(&workinfo);
K_RLOCK(workinfo_free); 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) { if (item) {
DATA_WORKINFO(wi, item); DATA_WORKINFO(wi, item);
while (item && !CURRENT(&(wi->expirydate))) { while (item && !CURRENT(&(wi->expirydate))) {
@ -2091,7 +2090,7 @@ bool workinfo_age(int64_t workinfoid, char *poolinstance, char *by, char *code,
diff_tot = 0; diff_tot = 0;
ss_look.data = (void *)(&looksharesummary); ss_look.data = (void *)(&looksharesummary);
K_RLOCK(sharesummary_free); 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); K_RUNLOCK(sharesummary_free);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
while (ss_item && sharesummary->workinfoid == workinfoid) { 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); s_look.data = (void *)(&lookshares);
K_WLOCK(shares_free); 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) { while (s_item) {
DATA_SHARES(shares, s_item); DATA_SHARES(shares, s_item);
if (shares->workinfoid != workinfoid || 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) if (shares->errn == SE_NONE)
diff_tot += shares->diff; diff_tot += shares->diff;
tmp_item = next_in_ktree(s_ctx); 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); k_unlink_item(shares_store, s_item);
if (reloading && skipupdate) if (reloading && skipupdate)
shares_dumped++; shares_dumped++;
@ -2317,13 +2316,10 @@ K_ITEM *_find_sharesummary(int64_t userid, char *workername, int64_t workinfoid,
INIT_SHARESUMMARY(&look); INIT_SHARESUMMARY(&look);
look.data = (void *)(&sharesummary); look.data = (void *)(&sharesummary);
if (pool) { if (pool)
return find_in_ktree(sharesummary_pool_root, &look, return find_in_ktree(sharesummary_pool_root, &look, ctx);
cmp_sharesummary, ctx); else
} else { return find_in_ktree(sharesummary_root, &look, ctx);
return find_in_ktree(sharesummary_root, &look,
cmp_sharesummary, ctx);
}
} }
K_ITEM *find_last_sharesummary(int64_t userid, char *workername) 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); INIT_SHARESUMMARY(&look);
look.data = (void *)(&look_sharesummary); 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) { if (item) {
DATA_SHARESUMMARY(sharesummary, item); DATA_SHARESUMMARY(sharesummary, item);
if (sharesummary->userid != userid || if (sharesummary->userid != userid ||
@ -2381,8 +2377,7 @@ void auto_age_older(int64_t workinfoid, char *poolinstance, char *by,
look.data = (void *)(&looksharesummary); look.data = (void *)(&looksharesummary);
K_RLOCK(sharesummary_free); K_RLOCK(sharesummary_free);
ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &look, ss_item = find_after_in_ktree(sharesummary_workinfoid_root, &look, ctx);
cmp_sharesummary_workinfoid, ctx);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
DATE_ZERO(&ss_first_min); 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); INIT_BLOCKS(&look);
look.data = (void *)(&blocks); 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 // Must be R or W locked before call
@ -2632,7 +2627,7 @@ K_ITEM *find_prev_blocks(int32_t height)
INIT_BLOCKS(&look); INIT_BLOCKS(&look);
look.data = (void *)(&lookblocks); 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) { while (b_item) {
DATA_BLOCKS(blocks, b_item); DATA_BLOCKS(blocks, b_item);
if (blocks->confirmed[0] != BLOCKS_NEW && if (blocks->confirmed[0] != BLOCKS_NEW &&
@ -2716,8 +2711,8 @@ void set_block_share_counters()
looksharesummary.workername = sharesummary->workername; looksharesummary.workername = sharesummary->workername;
looksharesummary.workinfoid = -1; looksharesummary.workinfoid = -1;
ss_look.data = (void *)(&looksharesummary); ss_look.data = (void *)(&looksharesummary);
ss_item = find_before_in_ktree(sharesummary_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_root,
cmp_sharesummary, ctx); &ss_look, ctx);
continue; continue;
} }
@ -2800,7 +2795,8 @@ void set_block_share_counters()
lookmarkersummary.userid = MAXID; lookmarkersummary.userid = MAXID;
lookmarkersummary.workername = EMPTY; lookmarkersummary.workername = EMPTY;
ms_look.data = (void *)(&lookmarkersummary); 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) { while (ms_item) {
DATA_MARKERSUMMARY(markersummary, ms_item); DATA_MARKERSUMMARY(markersummary, ms_item);
if (markersummary->markerid != workmarkers->markerid) if (markersummary->markerid != workmarkers->markerid)
@ -3067,7 +3063,7 @@ bool _set_prevcreatedate(int32_t oldest_height, WHERE_FFL_ARGS)
INIT_BLOCKS(&look); INIT_BLOCKS(&look);
look.data = (void *)(&lookblocks); 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) { while (b_item) {
DATA_BLOCKS(blocks, b_item); DATA_BLOCKS(blocks, b_item);
if (CURRENT(&(blocks->expirydate)) && if (CURRENT(&(blocks->expirydate)) &&
@ -3194,7 +3190,7 @@ K_ITEM *find_miningpayouts(int64_t payoutid, int64_t userid)
INIT_MININGPAYOUTS(&look); INIT_MININGPAYOUTS(&look);
look.data = (void *)(&miningpayouts); 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) 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); INIT_MININGPAYOUTS(&look);
look.data = (void *)(&miningpayouts); 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 /* 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); INIT_MININGPAYOUTS(&look);
look.data = (void *)(&lookminingpayouts); look.data = (void *)(&lookminingpayouts);
// No locking required since it's not a shared tree or store // 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) { if (mu_item) {
DATA_MININGPAYOUTS(miningpayouts, mu_item); DATA_MININGPAYOUTS(miningpayouts, mu_item);
miningpayouts->diffacc += diffacc; 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); DATA_MININGPAYOUTS(miningpayouts, mu_item);
miningpayouts->userid = userid; miningpayouts->userid = userid;
miningpayouts->diffacc = diffacc; 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_add_head(mu_store, mu_item);
K_WUNLOCK(mu_store); K_WUNLOCK(mu_store);
} }
@ -3314,7 +3310,7 @@ K_ITEM *find_payouts(int32_t height, char *blockhash)
INIT_PAYOUTS(&look); INIT_PAYOUTS(&look);
look.data = (void *)(&payouts); 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 // Last block payout calculated
@ -3346,7 +3342,7 @@ K_ITEM *find_payoutid(int64_t payoutid)
INIT_PAYOUTS(&look); INIT_PAYOUTS(&look);
look.data = (void *)(&payouts); 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 // 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); INIT_PAYOUTS(&look);
look.data = (void *)(&payouts); 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 /* 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; ss_count = wm_count = ms_count = 0;
mu_store = k_new_store(miningpayouts_free); mu_store = k_new_store(miningpayouts_free);
mu_root = new_ktree(); mu_root = new_ktree(cmp_mu);
looksharesummary.workinfoid = blocks->workinfoid; looksharesummary.workinfoid = blocks->workinfoid;
looksharesummary.userid = MAXID; 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(workmarkers_free);
K_RLOCK(markersummary_free); K_RLOCK(markersummary_free);
ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look,
cmp_sharesummary_workinfoid, ss_ctx); ss_ctx);
DATA_SHARESUMMARY_NULL(sharesummary, ss_item); DATA_SHARESUMMARY_NULL(sharesummary, ss_item);
if (ss_item) if (ss_item)
end_workinfoid = sharesummary->workinfoid; 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; lookworkmarkers.workinfoidend = blocks->workinfoid + 1;
INIT_WORKMARKERS(&wm_look); INIT_WORKMARKERS(&wm_look);
wm_look.data = (void *)(&lookworkmarkers); wm_look.data = (void *)(&lookworkmarkers);
wm_item = find_before_in_ktree(workmarkers_workinfoid_root, &wm_look, wm_item = find_before_in_ktree(workmarkers_workinfoid_root,
cmp_workmarkers_workinfoid, wm_ctx); &wm_look, wm_ctx);
DATA_WORKMARKERS_NULL(workmarkers, wm_item); DATA_WORKMARKERS_NULL(workmarkers, wm_item);
LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend); LOGDEBUG("%s(): workmarkers < %"PRId64, __func__, lookworkmarkers.workinfoidend);
while (total_diff < diff_want && wm_item && CURRENT(&(workmarkers->expirydate))) { 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; lookmarkersummary.workername = EMPTY;
INIT_MARKERSUMMARY(&ms_look); INIT_MARKERSUMMARY(&ms_look);
ms_look.data = (void *)(&lookmarkersummary); ms_look.data = (void *)(&lookmarkersummary);
ms_item = find_before_in_ktree(markersummary_root, &ms_look, ms_item = find_before_in_ktree(markersummary_root,
cmp_markersummary, ms_ctx); &ms_look, ms_ctx);
DATA_MARKERSUMMARY_NULL(markersummary, ms_item); DATA_MARKERSUMMARY_NULL(markersummary, ms_item);
// add the whole markerid // add the whole markerid
while (ms_item && markersummary->markerid == workmarkers->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); 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); mu_item = k_unlink_head(mu_store);
while (mu_item) { while (mu_item) {
DATA_MININGPAYOUTS(miningpayouts, mu_item); DATA_MININGPAYOUTS(miningpayouts, mu_item);
@ -4144,7 +4140,7 @@ oku:
; ;
ck_wunlock(&process_pplns_lock); ck_wunlock(&process_pplns_lock);
if (mu_root) if (mu_root)
mu_root = free_ktree(mu_root, NULL); free_ktree(mu_root, NULL);
if (mu_store) { if (mu_store) {
if (mu_store->count) { if (mu_store->count) {
K_WLOCK(mu_store); K_WLOCK(mu_store);
@ -4245,7 +4241,7 @@ K_ITEM *find_userstats(int64_t userid, char *workername)
INIT_USERSTATS(&look); INIT_USERSTATS(&look);
look.data = (void *)(&userstats); 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) 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); INIT_MARKERSUMMARY(&look);
look.data = (void *)(&markersummary); 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) { if (ms_item) {
DATA_MARKERSUMMARY(ms, ms_item); DATA_MARKERSUMMARY(ms, ms_item);
if (ms->userid != userid || strcmp(ms->workername, workername)) 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); INIT_MARKERSUMMARY(&look);
look.data = (void *)(&markersummary); look.data = (void *)(&markersummary);
if (pool) { if (pool) {
ms_item = find_in_ktree(markersummary_pool_root, &look, ms_item = find_in_ktree(markersummary_pool_root,
cmp_markersummary, ctx); &look, ctx);
} else { } else {
ms_item = find_in_ktree(markersummary_root, &look, ms_item = find_in_ktree(markersummary_root,
cmp_markersummary, ctx); &look, ctx);
} }
} }
@ -4476,7 +4472,7 @@ K_ITEM *find_workmarkers(int64_t workinfoid, bool anystatus, char status, K_TREE
INIT_WORKMARKERS(&look); INIT_WORKMARKERS(&look);
look.data = (void *)(&workmarkers); 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) { if (wm_item) {
DATA_WORKMARKERS(wm, wm_item); DATA_WORKMARKERS(wm, wm_item);
if (!CURRENT(&(wm->expirydate)) || if (!CURRENT(&(wm->expirydate)) ||
@ -4500,7 +4496,7 @@ K_ITEM *find_workmarkerid(int64_t markerid, bool anystatus, char status)
INIT_WORKMARKERS(&look); INIT_WORKMARKERS(&look);
look.data = (void *)(&workmarkers); 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) { if (wm_item) {
DATA_WORKMARKERS(wm, wm_item); DATA_WORKMARKERS(wm, wm_item);
if (!CURRENT(&(wm->expirydate)) || if (!CURRENT(&(wm->expirydate)) ||
@ -4530,8 +4526,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin,
look.data = (void *)(&workinfo); look.data = (void *)(&workinfo);
K_RLOCK(workinfo_free); K_RLOCK(workinfo_free);
if (after) { if (after) {
wi_stt_item = find_after_in_ktree(workinfo_root, &look, wi_stt_item = find_after_in_ktree(workinfo_root, &look, ctx);
cmp_workinfo, ctx);
while (wi_stt_item) { while (wi_stt_item) {
DATA_WORKINFO(wi_stt, wi_stt_item); DATA_WORKINFO(wi_stt, wi_stt_item);
if (CURRENT(&(wi_stt->expirydate))) 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); wi_stt_item = next_in_ktree(ctx);
} }
} else { } else {
wi_stt_item = find_in_ktree(workinfo_root, &look, wi_stt_item = find_in_ktree(workinfo_root, &look, ctx);
cmp_workinfo, ctx);
DATA_WORKINFO_NULL(wi_stt, wi_stt_item); DATA_WORKINFO_NULL(wi_stt, wi_stt_item);
} }
K_RUNLOCK(workinfo_free); K_RUNLOCK(workinfo_free);
@ -4556,8 +4550,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin,
K_RLOCK(workinfo_free); K_RLOCK(workinfo_free);
if (before) { if (before) {
DATE_ZERO(&(workinfo.expirydate)); DATE_ZERO(&(workinfo.expirydate));
wi_fin_item = find_before_in_ktree(workinfo_root, &look, wi_fin_item = find_before_in_ktree(workinfo_root, &look, ctx);
cmp_workinfo, ctx);
while (wi_fin_item) { while (wi_fin_item) {
DATA_WORKINFO(wi_fin, wi_fin_item); DATA_WORKINFO(wi_fin, wi_fin_item);
if (CURRENT(&(wi_fin->expirydate))) if (CURRENT(&(wi_fin->expirydate)))
@ -4567,8 +4560,7 @@ static bool gen_workmarkers(PGconn *conn, MARKS *stt, bool after, MARKS *fin,
} else { } else {
workinfo.expirydate.tv_sec = default_expiry.tv_sec; workinfo.expirydate.tv_sec = default_expiry.tv_sec;
workinfo.expirydate.tv_usec = default_expiry.tv_usec; workinfo.expirydate.tv_usec = default_expiry.tv_usec;
wi_fin_item = find_in_ktree(workinfo_root, &look, wi_fin_item = find_in_ktree(workinfo_root, &look, ctx);
cmp_workinfo, ctx);
DATA_WORKINFO_NULL(wi_fin, wi_fin_item); DATA_WORKINFO_NULL(wi_fin, wi_fin_item);
} }
K_RUNLOCK(workinfo_free); K_RUNLOCK(workinfo_free);
@ -4647,7 +4639,7 @@ bool workmarkers_generate(PGconn *conn, char *err, size_t siz, char *by,
INIT_MARKS(&look); INIT_MARKS(&look);
look.data = (void *)(&marks); look.data = (void *)(&marks);
K_RLOCK(marks_free); 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) { while (m_item) {
DATA_MARKS(mused, m_item); DATA_MARKS(mused, m_item);
if (CURRENT(&(mused->expirydate)) && MUSED(mused->status)) if (CURRENT(&(mused->expirydate)) && MUSED(mused->status))
@ -4854,7 +4846,7 @@ K_ITEM *find_marks(int64_t workinfoid)
INIT_MARKS(&look); INIT_MARKS(&look);
look.data = (void *)(&marks); 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) const char *marks_marktype(char *marktype)
@ -5026,7 +5018,7 @@ K_ITEM *_get_userinfo(int64_t userid, bool lock)
look.data = (void *)(&userinfo); look.data = (void *)(&userinfo);
if (lock) if (lock)
K_RLOCK(userinfo_free); K_RLOCK(userinfo_free);
find = find_in_ktree(userinfo_root, &look, cmp_userinfo, ctx); find = find_in_ktree(userinfo_root, &look, ctx);
if (lock) if (lock)
K_RUNLOCK(userinfo_free); K_RUNLOCK(userinfo_free);
return find; return find;
@ -5059,7 +5051,7 @@ K_ITEM *_find_create_userinfo(int64_t userid, bool lock, WHERE_FFL_ARGS)
else else
bigint_to_buf(userid, row->username, sizeof(row->username)); 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); k_add_head(userinfo_store, ui_item);
if (lock) if (lock)
K_WUNLOCK(userinfo_free); K_WUNLOCK(userinfo_free);

311
src/ckdb_dbio.c

@ -513,14 +513,14 @@ unparam:
free_users_data(item); free_users_data(item);
k_add_head(users_free, item); k_add_head(users_free, item);
} else { } else {
users_root = remove_from_ktree(users_root, u_item, cmp_users); remove_from_ktree(users_root, u_item);
userid_root = remove_from_ktree(userid_root, u_item, cmp_userid); remove_from_ktree(userid_root, u_item);
copy_tv(&(users->expirydate), cd); copy_tv(&(users->expirydate), cd);
users_root = add_to_ktree(users_root, u_item, cmp_users); add_to_ktree(users_root, u_item);
userid_root = add_to_ktree(userid_root, u_item, cmp_userid); add_to_ktree(userid_root, u_item);
users_root = add_to_ktree(users_root, item, cmp_users); add_to_ktree(users_root, item);
userid_root = add_to_ktree(userid_root, item, cmp_userid); add_to_ktree(userid_root, item);
k_add_head(users_store, item); k_add_head(users_store, item);
} }
K_WUNLOCK(users_free); K_WUNLOCK(users_free);
@ -648,8 +648,8 @@ unitem:
free_users_data(item); free_users_data(item);
k_add_head(users_free, item); k_add_head(users_free, item);
} else { } else {
users_root = add_to_ktree(users_root, item, cmp_users); add_to_ktree(users_root, item);
userid_root = add_to_ktree(userid_root, item, cmp_userid); add_to_ktree(userid_root, item);
k_add_head(users_store, item); k_add_head(users_store, item);
} }
K_WUNLOCK(users_free); K_WUNLOCK(users_free);
@ -760,14 +760,14 @@ unparam:
free_users_data(u_item); free_users_data(u_item);
k_add_head(users_free, u_item); k_add_head(users_free, u_item);
} else { } else {
users_root = remove_from_ktree(users_root, old_u_item, cmp_users); remove_from_ktree(users_root, old_u_item);
userid_root = remove_from_ktree(userid_root, old_u_item, cmp_userid); remove_from_ktree(userid_root, old_u_item);
copy_tv(&(old_users->expirydate), cd); copy_tv(&(old_users->expirydate), cd);
users_root = add_to_ktree(users_root, old_u_item, cmp_users); add_to_ktree(users_root, old_u_item);
userid_root = add_to_ktree(userid_root, old_u_item, cmp_userid); add_to_ktree(userid_root, old_u_item);
users_root = add_to_ktree(users_root, u_item, cmp_users); add_to_ktree(users_root, u_item);
userid_root = add_to_ktree(userid_root, u_item, cmp_userid); add_to_ktree(userid_root, u_item);
k_add_head(users_store, u_item); k_add_head(users_store, u_item);
} }
K_WUNLOCK(users_free); K_WUNLOCK(users_free);
@ -883,8 +883,8 @@ bool users_fill(PGconn *conn)
username_trim(row); username_trim(row);
users_root = add_to_ktree(users_root, item, cmp_users); add_to_ktree(users_root, item);
userid_root = add_to_ktree(userid_root, item, cmp_userid); add_to_ktree(userid_root, item);
k_add_head(users_store, item); k_add_head(users_store, item);
} }
if (!ok) { if (!ok) {
@ -1011,11 +1011,11 @@ unparam:
if (ok) { if (ok) {
// Update it // Update it
if (old_item) { 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); 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_add_head(useratts_store, ua_item);
} }
K_WUNLOCK(useratts_free); K_WUNLOCK(useratts_free);
@ -1162,9 +1162,9 @@ unparam:
K_WLOCK(useratts_free); K_WLOCK(useratts_free);
if (ok && item) { if (ok && item) {
useratts_root = remove_from_ktree(useratts_root, item, cmp_useratts); remove_from_ktree(useratts_root, item);
copy_tv(&(useratts->expirydate), cd); 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); K_WUNLOCK(useratts_free);
@ -1269,7 +1269,7 @@ bool useratts_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
useratts_root = add_to_ktree(useratts_root, item, cmp_useratts); add_to_ktree(useratts_root, item);
k_add_head(useratts_store, item); k_add_head(useratts_store, item);
} }
if (!ok) if (!ok)
@ -1400,7 +1400,7 @@ unitem:
if (!ret) if (!ret)
k_add_head(workers_free, item); k_add_head(workers_free, item);
else { else {
workers_root = add_to_ktree(workers_root, item, cmp_workers); add_to_ktree(workers_root, item);
k_add_head(workers_store, item); k_add_head(workers_store, item);
// Ensure there is a matching workerstatus // Ensure there is a matching workerstatus
find_create_workerstatus(userid, workername, find_create_workerstatus(userid, workername,
@ -1639,7 +1639,7 @@ bool workers_fill(PGconn *conn)
break; break;
TXT_TO_BIGINT("workerid", field, row->workerid); 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); k_add_head(workers_store, item);
/* Make sure a workerstatus exists for each worker /* Make sure a workerstatus exists for each worker
@ -1869,15 +1869,11 @@ unparam:
else { else {
// It wasn't a match, thus it was expired // It wasn't a match, thus it was expired
n++; n++;
paymentaddresses_root = remove_from_ktree(paymentaddresses_root, item, remove_from_ktree(paymentaddresses_root, item);
cmp_paymentaddresses); remove_from_ktree(paymentaddresses_create_root, item);
paymentaddresses_create_root = remove_from_ktree(paymentaddresses_create_root,
item, cmp_payaddr_create);
copy_tv(&(row->expirydate), cd); copy_tv(&(row->expirydate), cd);
paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, add_to_ktree(paymentaddresses_root, item);
cmp_paymentaddresses); add_to_ktree(paymentaddresses_create_root, item);
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
item, cmp_payaddr_create);
} }
item = prev; item = prev;
DATA_PAYMENTADDRESSES_NULL(row, item); DATA_PAYMENTADDRESSES_NULL(row, item);
@ -1889,10 +1885,8 @@ unparam:
next = match->next; next = match->next;
DATA_PAYMENTADDRESSES(pa, match); DATA_PAYMENTADDRESSES(pa, match);
if (!pa->match) { if (!pa->match) {
paymentaddresses_root = add_to_ktree(paymentaddresses_root, match, add_to_ktree(paymentaddresses_root, match);
cmp_paymentaddresses); add_to_ktree(paymentaddresses_create_root, match);
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
match, cmp_payaddr_create);
k_unlink_item(pa_store, match); k_unlink_item(pa_store, match);
k_add_head(paymentaddresses_store, match); k_add_head(paymentaddresses_store, match);
count++; count++;
@ -1981,10 +1975,8 @@ bool paymentaddresses_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
paymentaddresses_root = add_to_ktree(paymentaddresses_root, item, add_to_ktree(paymentaddresses_root, item);
cmp_paymentaddresses); add_to_ktree(paymentaddresses_create_root, item);
paymentaddresses_create_root = add_to_ktree(paymentaddresses_create_root,
item, cmp_payaddr_create);
k_add_head(paymentaddresses_store, item); k_add_head(paymentaddresses_store, item);
} }
if (!ok) 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 { } else {
if (old_p_item) { if (old_p_item) {
DATA_PAYMENTS(oldp, 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); 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_add_head(payments_store, p_item);
} }
K_WUNLOCK(payments_free); K_WUNLOCK(payments_free);
@ -2252,7 +2244,7 @@ bool payments_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
payments_root = add_to_ktree(payments_root, item, cmp_payments); add_to_ktree(payments_root, item);
k_add_head(payments_store, item); k_add_head(payments_store, item);
} }
if (!ok) 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); INIT_OPTIONCONTROL(&look);
look.data = (void *)row; look.data = (void *)row;
K_RLOCK(optioncontrol_free); 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); K_RUNLOCK(optioncontrol_free);
if (!conn) { if (!conn) {
@ -2446,13 +2438,12 @@ nostart:
} else { } else {
// Discard old // Discard old
if (old_item) { if (old_item) {
optioncontrol_root = remove_from_ktree(optioncontrol_root, old_item, remove_from_ktree(optioncontrol_root, old_item);
cmp_optioncontrol);
k_unlink_item(optioncontrol_store, old_item); k_unlink_item(optioncontrol_store, old_item);
free_optioncontrol_data(old_item); free_optioncontrol_data(old_item);
k_add_head(optioncontrol_free, 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); k_add_head(optioncontrol_store, oc_item);
if (strcmp(row->optionname, SWITCH_STATE_NAME) == 0) { if (strcmp(row->optionname, SWITCH_STATE_NAME) == 0) {
switch_state = atoi(row->optionvalue); switch_state = atoi(row->optionvalue);
@ -2584,7 +2575,7 @@ bool optioncontrol_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
optioncontrol_root = add_to_ktree(optioncontrol_root, item, cmp_optioncontrol); add_to_ktree(optioncontrol_root, item);
k_add_head(optioncontrol_store, item); k_add_head(optioncontrol_store, item);
// There should only be one CURRENT version of switch_state // 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); HISTORYDATETRANSFER(trf_root, row);
K_WLOCK(workinfo_free); 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; workinfoid = row->workinfoid;
free_workinfo_data(item); free_workinfo_data(item);
k_add_head(workinfo_free, item); k_add_head(workinfo_free, item);
@ -2732,7 +2723,7 @@ unparam:
hex2bin(ndiffbin, row->bits, 4); hex2bin(ndiffbin, row->bits, 4);
current_ndiff = diff_from_nbits(ndiffbin); 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); k_add_head(workinfo_store, item);
// Remember the bc = 'cd' when the height changes // Remember the bc = 'cd' when the height changes
@ -2900,9 +2891,9 @@ bool workinfo_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
workinfo_root = add_to_ktree(workinfo_root, item, cmp_workinfo); add_to_ktree(workinfo_root, item);
if (!confirm_sharesummary) 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); k_add_head(workinfo_store, item);
if (tv_newer(&(dbstatus.newest_createdate_workinfo), &(row->createdate))) { 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); es_item = last_in_ktree(shares_early_root, ctx);
if (es_item) { if (es_item) {
shares_early_root = remove_from_ktree(shares_early_root, remove_from_ktree(shares_early_root, es_item);
es_item,
cmp_shares);
k_unlink_item(shares_early_store, es_item); k_unlink_item(shares_early_store, es_item);
} }
K_WUNLOCK(shares_free); K_WUNLOCK(shares_free);
@ -3078,7 +3067,7 @@ static void shares_process_early(PGconn *conn, int64_t good_wid, tv_t *good_cd,
return; return;
redo: redo:
K_WLOCK(shares_free); 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_add_tail(shares_early_store, es_item);
K_WUNLOCK(shares_free); K_WUNLOCK(shares_free);
return; return;
@ -3093,7 +3082,7 @@ keep:
early_shares->oldcount, early_shares->redo); early_shares->oldcount, early_shares->redo);
FREENULL(st); FREENULL(st);
K_WLOCK(shares_free); 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_add_head(shares_store, es_item);
K_WUNLOCK(shares_free); K_WUNLOCK(shares_free);
return; return;
@ -3200,8 +3189,7 @@ bool shares_add(PGconn *conn, char *workinfoid, char *username, char *workername
shares->oldcount = 0; shares->oldcount = 0;
K_WLOCK(shares_free); K_WLOCK(shares_free);
// They need to be sorted by workinfoid // They need to be sorted by workinfoid
shares_early_root = add_to_ktree(shares_early_root, s_item, add_to_ktree(shares_early_root, s_item);
cmp_shares);
k_add_head(shares_early_store, s_item); k_add_head(shares_early_store, s_item);
K_WUNLOCK(shares_free); K_WUNLOCK(shares_free);
/* It was all OK except the missing workinfoid /* 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); ok = shares_process(conn, shares, trf_root);
if (ok) { if (ok) {
K_WLOCK(shares_free); 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_add_head(shares_store, s_item);
K_WUNLOCK(shares_free); 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); es_item = last_in_ktree(shareerrors_early_root, ctx);
if (es_item) { if (es_item) {
shareerrors_early_root = remove_from_ktree(shareerrors_early_root, remove_from_ktree(shareerrors_early_root, es_item);
es_item,
cmp_shareerrors);
k_unlink_item(shareerrors_early_store, es_item); k_unlink_item(shareerrors_early_store, es_item);
} }
K_WUNLOCK(shareerrors_free); K_WUNLOCK(shareerrors_free);
@ -3381,8 +3367,7 @@ static void shareerrors_process_early(PGconn *conn, int64_t good_wid,
return; return;
redo: redo:
K_WLOCK(shareerrors_free); K_WLOCK(shareerrors_free);
shareerrors_early_root = add_to_ktree(shareerrors_early_root, es_item, add_to_ktree(shareerrors_early_root, es_item);
cmp_shareerrors);
k_add_tail(shareerrors_early_store, es_item); k_add_tail(shareerrors_early_store, es_item);
K_WUNLOCK(shareerrors_free); K_WUNLOCK(shareerrors_free);
return; return;
@ -3397,7 +3382,7 @@ keep:
early_shareerrors->oldcount, early_shareerrors->redo); early_shareerrors->oldcount, early_shareerrors->redo);
FREENULL(st); FREENULL(st);
K_WLOCK(shareerrors_free); 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_add_head(shareerrors_store, es_item);
K_WUNLOCK(shareerrors_free); K_WUNLOCK(shareerrors_free);
return; return;
@ -3494,9 +3479,7 @@ bool shareerrors_add(PGconn *conn, char *workinfoid, char *username,
shareerrors->oldcount = 0; shareerrors->oldcount = 0;
K_WLOCK(shareerrors_free); K_WLOCK(shareerrors_free);
// They need to be sorted by workinfoid // They need to be sorted by workinfoid
shareerrors_early_root = add_to_ktree(shareerrors_early_root, add_to_ktree(shareerrors_early_root, s_item);
s_item,
cmp_shareerrors);
k_add_head(shareerrors_early_store, s_item); k_add_head(shareerrors_early_store, s_item);
K_WUNLOCK(shareerrors_free); K_WUNLOCK(shareerrors_free);
/* It was all OK except the missing workinfoid /* 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); ok = shareerrors_process(conn, shareerrors, trf_root);
if (ok) { if (ok) {
K_WLOCK(shareerrors_free); K_WLOCK(shareerrors_free);
shareerrors_root = add_to_ktree(shareerrors_root, s_item, add_to_ktree(shareerrors_root, s_item);
cmp_shareerrors);
k_add_head(shareerrors_store, s_item); k_add_head(shareerrors_store, s_item);
K_WUNLOCK(shareerrors_free); 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 *old_sharesummary_store = k_new_store(sharesummary_free);
K_STORE *new_markersummary_store = k_new_store(markersummary_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))) { if (!CURRENT(&(workmarkers->expirydate))) {
reason = "unexpired"; reason = "unexpired";
@ -3617,8 +3599,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers,
INIT_MARKERSUMMARY(&ms_look); INIT_MARKERSUMMARY(&ms_look);
ms_look.data = (void *)(&lookmarkersummary); ms_look.data = (void *)(&lookmarkersummary);
K_RLOCK(markersummary_free); K_RLOCK(markersummary_free);
ms_item = find_after_in_ktree(markersummary_root, &ms_look, ms_item = find_after_in_ktree(markersummary_root, &ms_look, ms_ctx);
cmp_markersummary, ms_ctx);
K_RUNLOCK(markersummary_free); K_RUNLOCK(markersummary_free);
DATA_MARKERSUMMARY_NULL(markersummary, ms_item); DATA_MARKERSUMMARY_NULL(markersummary, ms_item);
if (ms_item && markersummary->markerid == workmarkers->markerid) { 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 * Those incoming shares will not be touching the sharesummaries
* we are processing here */ * we are processing here */
K_RLOCK(sharesummary_free); K_RLOCK(sharesummary_free);
ss_item = find_before_in_ktree(sharesummary_workinfoid_root, &ss_look, ss_item = find_before_in_ktree(sharesummary_workinfoid_root,
cmp_sharesummary_workinfoid, ss_ctx); &ss_look, ss_ctx);
K_RUNLOCK(sharesummary_free); K_RUNLOCK(sharesummary_free);
while (ss_item) { while (ss_item) {
DATA_SHARESUMMARY(sharesummary, ss_item); DATA_SHARESUMMARY(sharesummary, ss_item);
@ -3659,8 +3640,7 @@ bool sharesummaries_to_markersummaries(PGconn *conn, WORKMARKERS *workmarkers,
lookmarkersummary.workername = sharesummary->workername; lookmarkersummary.workername = sharesummary->workername;
ms_look.data = (void *)(&lookmarkersummary); ms_look.data = (void *)(&lookmarkersummary);
ms_item = find_in_ktree(ms_root, &ms_look, ms_item = find_in_ktree(ms_root, &ms_look, ms_ctx);
cmp_markersummary, ms_ctx);
if (!ms_item) { if (!ms_item) {
K_WLOCK(markersummary_free); K_WLOCK(markersummary_free);
ms_item = k_unlink_head(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, DUP_POINTER(markersummary_free,
markersummary->workername, markersummary->workername,
sharesummary->workername); sharesummary->workername);
ms_root = add_to_ktree(ms_root, ms_item, add_to_ktree(ms_root, ms_item);
cmp_markersummary);
LOGDEBUG("%s() new ms %"PRId64"/%"PRId64"/%s", LOGDEBUG("%s() new ms %"PRId64"/%"PRId64"/%s",
shortname, markersummary->markerid, shortname, markersummary->markerid,
@ -3796,12 +3775,8 @@ flail:
ms_item = new_markersummary_store->head; ms_item = new_markersummary_store->head;
while (ms_item) { while (ms_item) {
// move the new markersummaries into the trees/stores // move the new markersummaries into the trees/stores
markersummary_root = add_to_ktree(markersummary_root, add_to_ktree(markersummary_root, ms_item);
ms_item, add_to_ktree(markersummary_userid_root, ms_item);
cmp_markersummary);
markersummary_userid_root = add_to_ktree(markersummary_userid_root,
ms_item,
cmp_markersummary_userid);
// create/update the pool markersummaries // create/update the pool markersummaries
DATA_MARKERSUMMARY(markersummary, ms_item); DATA_MARKERSUMMARY(markersummary, ms_item);
@ -3812,9 +3787,7 @@ flail:
bzero(p_markersummary, sizeof(*p_markersummary)); bzero(p_markersummary, sizeof(*p_markersummary));
p_markersummary->markerid = markersummary->markerid; p_markersummary->markerid = markersummary->markerid;
POOL_MS(p_markersummary); POOL_MS(p_markersummary);
markersummary_pool_root = add_to_ktree(markersummary_pool_root, add_to_ktree(markersummary_pool_root, p_ms_item);
p_ms_item,
cmp_markersummary);
k_add_head(markersummary_pool_store, p_ms_item); k_add_head(markersummary_pool_store, p_ms_item);
} }
markersummary_to_pool(p_markersummary, markersummary); markersummary_to_pool(p_markersummary, markersummary);
@ -3828,20 +3801,14 @@ flail:
ss_item = old_sharesummary_store->head; ss_item = old_sharesummary_store->head;
while (ss_item) { while (ss_item) {
// remove the old sharesummaries from the trees // remove the old sharesummaries from the trees
sharesummary_root = remove_from_ktree(sharesummary_root, remove_from_ktree(sharesummary_root, ss_item);
ss_item, remove_from_ktree(sharesummary_workinfoid_root, ss_item);
cmp_sharesummary);
sharesummary_workinfoid_root = remove_from_ktree(sharesummary_workinfoid_root,
ss_item,
cmp_sharesummary_workinfoid);
// remove the pool sharesummaries // remove the pool sharesummaries
DATA_SHARESUMMARY(sharesummary, ss_item); DATA_SHARESUMMARY(sharesummary, ss_item);
p_ss_item = find_sharesummary_p(sharesummary->workinfoid); p_ss_item = find_sharesummary_p(sharesummary->workinfoid);
if (p_ss_item) { if (p_ss_item) {
sharesummary_pool_root = remove_from_ktree(sharesummary_pool_root, remove_from_ktree(sharesummary_pool_root, p_ss_item);
p_ss_item,
cmp_sharesummary);
k_unlink_item(sharesummary_pool_store, p_ss_item); k_unlink_item(sharesummary_pool_store, p_ss_item);
free_sharesummary_data(p_ss_item); free_sharesummary_data(p_ss_item);
k_add_head(sharesummary_free, p_ss_item); k_add_head(sharesummary_free, p_ss_item);
@ -3864,7 +3831,7 @@ flail:
workmarkers->description, workmarkers->description,
workmarkers->status); workmarkers->status);
} }
ms_root = free_ktree(ms_root, NULL); free_ktree(ms_root, NULL);
new_markersummary_store = k_free_store(new_markersummary_store); new_markersummary_store = k_free_store(new_markersummary_store);
old_sharesummary_store = k_free_store(old_sharesummary_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) { if (new || p_new) {
K_WLOCK(sharesummary_free); K_WLOCK(sharesummary_free);
if (new) { if (new) {
sharesummary_root = add_to_ktree(sharesummary_root, item, cmp_sharesummary); add_to_ktree(sharesummary_root, item);
sharesummary_workinfoid_root = add_to_ktree(sharesummary_workinfoid_root, add_to_ktree(sharesummary_workinfoid_root, item);
item,
cmp_sharesummary_workinfoid);
k_add_head(sharesummary_store, item); k_add_head(sharesummary_store, item);
} }
if (p_new) { if (p_new) {
sharesummary_pool_root = add_to_ktree(sharesummary_pool_root, add_to_ktree(sharesummary_pool_root, p_item);
p_item,
cmp_sharesummary);
k_add_head(sharesummary_pool_store, p_item); k_add_head(sharesummary_pool_store, p_item);
} }
K_WUNLOCK(sharesummary_free); K_WUNLOCK(sharesummary_free);
@ -4290,14 +4253,14 @@ unparam:
k_add_head(blocks_free, b_item); k_add_head(blocks_free, b_item);
else { else {
if (update_old) { 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); 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 // Copy it over to avoid having to recalculate it
row->netdiff = oldblocks->netdiff; row->netdiff = oldblocks->netdiff;
} else } else
row->netdiff = 0; 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); k_add_head(blocks_store, b_item);
blocks_stats_rebuild = true; blocks_stats_rebuild = true;
// 'confirmed' is unchanged so no need to recalc *createdate // 'confirmed' is unchanged so no need to recalc *createdate
@ -4670,14 +4633,14 @@ flail:
k_add_head(blocks_free, b_item); k_add_head(blocks_free, b_item);
else { else {
if (update_old) { 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); 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 // Copy it over to avoid having to recalculate it
row->netdiff = oldblocks->netdiff; row->netdiff = oldblocks->netdiff;
} else } else
row->netdiff = 0; 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); k_add_head(blocks_store, b_item);
blocks_stats_rebuild = true; blocks_stats_rebuild = true;
// recalc the *createdate fields for possibly affected blocks // recalc the *createdate fields for possibly affected blocks
@ -4897,7 +4860,7 @@ bool blocks_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
blocks_root = add_to_ktree(blocks_root, item, cmp_blocks); add_to_ktree(blocks_root, item);
k_add_head(blocks_store, item); k_add_head(blocks_store, item);
if (tv_newer(&(dbstatus.newest_createdate_blocks), &(row->createdate))) 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 { } else {
if (old_mp_item) { if (old_mp_item) {
DATA_MININGPAYOUTS(oldmp, 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); 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_add_head(miningpayouts_store, mp_item);
} }
K_WUNLOCK(miningpayouts_free); K_WUNLOCK(miningpayouts_free);
@ -5142,7 +5105,7 @@ bool miningpayouts_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
miningpayouts_root = add_to_ktree(miningpayouts_root, item, cmp_miningpayouts); add_to_ktree(miningpayouts_root, item);
k_add_head(miningpayouts_store, item); k_add_head(miningpayouts_store, item);
tick(); tick();
@ -5176,17 +5139,17 @@ void payouts_add_ram(bool ok, K_ITEM *p_item, K_ITEM *old_p_item, tv_t *cd)
} else { } else {
if (old_p_item) { if (old_p_item) {
DATA_PAYOUTS(oldp, old_p_item); DATA_PAYOUTS(oldp, old_p_item);
payouts_root = remove_from_ktree(payouts_root, old_p_item, cmp_payouts); remove_from_ktree(payouts_root, old_p_item);
payouts_id_root = remove_from_ktree(payouts_id_root, old_p_item, cmp_payouts_id); remove_from_ktree(payouts_id_root, old_p_item);
payouts_wid_root = remove_from_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid); remove_from_ktree(payouts_wid_root, old_p_item);
copy_tv(&(oldp->expirydate), cd); copy_tv(&(oldp->expirydate), cd);
payouts_root = add_to_ktree(payouts_root, old_p_item, cmp_payouts); add_to_ktree(payouts_root, old_p_item);
payouts_id_root = add_to_ktree(payouts_id_root, old_p_item, cmp_payouts_id); add_to_ktree(payouts_id_root, old_p_item);
payouts_wid_root = add_to_ktree(payouts_wid_root, old_p_item, cmp_payouts_wid); add_to_ktree(payouts_wid_root, old_p_item);
} }
payouts_root = add_to_ktree(payouts_root, p_item, cmp_payouts); add_to_ktree(payouts_root, p_item);
payouts_id_root = add_to_ktree(payouts_id_root, p_item, cmp_payouts_id); add_to_ktree(payouts_id_root, p_item);
payouts_wid_root = add_to_ktree(payouts_wid_root, p_item, cmp_payouts_wid); add_to_ktree(payouts_wid_root, p_item);
k_add_head(payouts_store, p_item); k_add_head(payouts_store, p_item);
} }
K_WUNLOCK(payouts_free); 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 // No more possible errors, so update the ram tables
DATA_PAYOUTS(payouts, po_item); DATA_PAYOUTS(payouts, po_item);
payouts_root = remove_from_ktree(payouts_root, po_item, cmp_payouts); remove_from_ktree(payouts_root, po_item);
payouts_id_root = remove_from_ktree(payouts_id_root, po_item, cmp_payouts_id); remove_from_ktree(payouts_id_root, po_item);
payouts_wid_root = remove_from_ktree(payouts_wid_root, po_item, cmp_payouts_wid); remove_from_ktree(payouts_wid_root, po_item);
copy_tv(&(payouts->expirydate), now); copy_tv(&(payouts->expirydate), now);
payouts_root = add_to_ktree(payouts_root, po_item, cmp_payouts); add_to_ktree(payouts_root, po_item);
payouts_id_root = add_to_ktree(payouts_id_root, po_item, cmp_payouts_id); add_to_ktree(payouts_id_root, po_item);
payouts_wid_root = add_to_ktree(payouts_wid_root, po_item, cmp_payouts_wid); add_to_ktree(payouts_wid_root, po_item);
mp_item = first_miningpayouts(payoutid, mp_ctx); mp_item = first_miningpayouts(payoutid, mp_ctx);
DATA_MININGPAYOUTS_NULL(mp, mp_item); DATA_MININGPAYOUTS_NULL(mp, mp_item);
while (mp_item && mp->payoutid == payoutid) { while (mp_item && mp->payoutid == payoutid) {
if (CURRENT(&(mp->expirydate))) { if (CURRENT(&(mp->expirydate))) {
next_item = next_in_ktree(mp_ctx); 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); 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; mp_item = next_item;
} else } else
mp_item = next_in_ktree(mp_ctx); 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 && if (payments->payoutid == payoutid &&
CURRENT(&(payments->expirydate))) { CURRENT(&(payments->expirydate))) {
next_item = next_in_ktree(pm_ctx); 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); 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; pm_item = next_item;
} else } else
pm_item = next_in_ktree(pm_ctx); pm_item = next_in_ktree(pm_ctx);
@ -5698,9 +5661,9 @@ bool payouts_fill(PGconn *conn)
&(blocks->blockcreatedate)); &(blocks->blockcreatedate));
} }
payouts_root = add_to_ktree(payouts_root, item, cmp_payouts); add_to_ktree(payouts_root, item);
payouts_id_root = add_to_ktree(payouts_id_root, item, cmp_payouts_id); add_to_ktree(payouts_id_root, item);
payouts_wid_root = add_to_ktree(payouts_wid_root, item, cmp_payouts_wid); add_to_ktree(payouts_wid_root, item);
k_add_head(payouts_store, item); k_add_head(payouts_store, item);
if (CURRENT(&(row->expirydate)) && PAYGENERATED(row->status)) if (CURRENT(&(row->expirydate)) && PAYGENERATED(row->status))
@ -5792,7 +5755,7 @@ bool auths_add(PGconn *conn, char *poolinstance, char *username,
HISTORYDATETRANSFER(trf_root, row); HISTORYDATETRANSFER(trf_root, row);
K_WLOCK(auths_free); 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_add_head(auths_free, a_item);
K_WUNLOCK(auths_free); K_WUNLOCK(auths_free);
@ -5825,7 +5788,7 @@ unitem:
if (!ok) if (!ok)
k_add_head(auths_free, a_item); k_add_head(auths_free, a_item);
else { 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); k_add_head(auths_store, a_item);
} }
#endif #endif
@ -5875,7 +5838,7 @@ bool poolstats_add(PGconn *conn, bool store, char *poolinstance,
SIMPLEDATEINIT(row, cd, by, code, inet); SIMPLEDATEINIT(row, cd, by, code, inet);
SIMPLEDATETRANSFER(trf_root, row); 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_WLOCK(poolstats_free);
k_add_head(poolstats_free, p_item); k_add_head(poolstats_free, p_item);
K_WUNLOCK(poolstats_free); K_WUNLOCK(poolstats_free);
@ -5937,7 +5900,7 @@ unparam:
if (!ok) if (!ok)
k_add_head(poolstats_free, p_item); k_add_head(poolstats_free, p_item);
else { 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_add_head(poolstats_store, p_item);
} }
K_WUNLOCK(poolstats_free); K_WUNLOCK(poolstats_free);
@ -6083,7 +6046,7 @@ bool poolstats_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
poolstats_root = add_to_ktree(poolstats_root, item, cmp_poolstats); add_to_ktree(poolstats_root, item);
k_add_head(poolstats_store, item); k_add_head(poolstats_store, item);
if (tv_newer(&(dbstatus.newest_createdate_poolstats), &(row->createdate))) 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); K_WLOCK(userstats_free);
us_next = userstats_eos_store->head; us_next = userstats_eos_store->head;
while (us_next) { while (us_next) {
us_item = find_in_ktree(userstats_root, us_next, us_item = find_in_ktree(userstats_root, us_next, ctx);
cmp_userstats, ctx);
if (!us_item) { if (!us_item) {
// New user+worker - store it in RAM // New user+worker - store it in RAM
us_match = us_next; us_match = us_next;
us_next = us_match->next; us_next = us_match->next;
k_unlink_item(userstats_eos_store, us_match); k_unlink_item(userstats_eos_store, us_match);
userstats_root = add_to_ktree(userstats_root, us_match, add_to_ktree(userstats_root, us_match);
cmp_userstats);
k_add_head(userstats_store, us_match); k_add_head(userstats_store, us_match);
} else { } else {
DATA_USERSTATS(next, us_next); DATA_USERSTATS(next, us_next);
@ -6270,12 +6231,10 @@ bool workerstats_add(char *poolinstance, char *elapsed, char *username,
workerstatus_update(NULL, NULL, row); workerstatus_update(NULL, NULL, row);
K_WLOCK(userstats_free); K_WLOCK(userstats_free);
us_match = find_in_ktree(userstats_root, us_item, us_match = find_in_ktree(userstats_root, us_item, ctx);
cmp_userstats, ctx);
if (!us_match) { if (!us_match) {
// New user+worker - store it in RAM // New user+worker - store it in RAM
userstats_root = add_to_ktree(userstats_root, us_item, add_to_ktree(userstats_root, us_item);
cmp_userstats);
k_add_head(userstats_store, us_item); k_add_head(userstats_store, us_item);
} else { } else {
DATA_USERSTATS(match, us_match); DATA_USERSTATS(match, us_match);
@ -6520,8 +6479,8 @@ bool markersummary_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
markersummary_root = add_to_ktree(markersummary_root, item, cmp_markersummary); add_to_ktree(markersummary_root, item);
markersummary_userid_root = add_to_ktree(markersummary_userid_root, item, cmp_markersummary_userid); add_to_ktree(markersummary_userid_root, item);
k_add_head(markersummary_store, item); k_add_head(markersummary_store, item);
p_item = find_markersummary_p(row->markerid); p_item = find_markersummary_p(row->markerid);
@ -6533,9 +6492,7 @@ bool markersummary_fill(PGconn *conn)
bzero(p_row, sizeof(*p_row)); bzero(p_row, sizeof(*p_row));
p_row->markerid = row->markerid; p_row->markerid = row->markerid;
POOL_MS(p_row); POOL_MS(p_row);
markersummary_pool_root = add_to_ktree(markersummary_pool_root, add_to_ktree(markersummary_pool_root, p_item);
p_item,
cmp_markersummary);
k_add_head(markersummary_pool_store, p_item); k_add_head(markersummary_pool_store, p_item);
} else { } else {
DATA_MARKERSUMMARY(p_row, p_item); DATA_MARKERSUMMARY(p_row, p_item);
@ -6769,29 +6726,18 @@ unparam:
} }
else { else {
if (old_wm_item) { if (old_wm_item) {
workmarkers_root = remove_from_ktree(workmarkers_root, remove_from_ktree(workmarkers_root, old_wm_item);
old_wm_item, remove_from_ktree(workmarkers_workinfoid_root,
cmp_workmarkers); old_wm_item);
workmarkers_workinfoid_root = remove_from_ktree(workmarkers_workinfoid_root,
old_wm_item,
cmp_workmarkers_workinfoid);
copy_tv(&(oldworkmarkers->expirydate), cd); copy_tv(&(oldworkmarkers->expirydate), cd);
workmarkers_root = add_to_ktree(workmarkers_root, add_to_ktree(workmarkers_root, old_wm_item);
old_wm_item, add_to_ktree(workmarkers_workinfoid_root, old_wm_item);
cmp_workmarkers);
workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root,
old_wm_item,
cmp_workmarkers_workinfoid);
} }
if (wm_item) { if (wm_item) {
shift_rewards(wm_item); shift_rewards(wm_item);
workmarkers_root = add_to_ktree(workmarkers_root, add_to_ktree(workmarkers_root, wm_item);
wm_item, add_to_ktree(workmarkers_workinfoid_root, wm_item);
cmp_workmarkers);
workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root,
wm_item,
cmp_workmarkers_workinfoid);
k_add_head(workmarkers_store, wm_item); k_add_head(workmarkers_store, wm_item);
} }
} }
@ -6887,9 +6833,8 @@ bool workmarkers_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
workmarkers_root = add_to_ktree(workmarkers_root, item, cmp_workmarkers); add_to_ktree(workmarkers_root, item);
workmarkers_workinfoid_root = add_to_ktree(workmarkers_workinfoid_root, add_to_ktree(workmarkers_workinfoid_root, item);
item, cmp_workmarkers_workinfoid);
k_add_head(workmarkers_store, item); k_add_head(workmarkers_store, item);
if (dbstatus.newest_workmarker_workinfoid < row->workinfoidend) { if (dbstatus.newest_workmarker_workinfoid < row->workinfoidend) {
@ -7086,12 +7031,12 @@ unparam:
} }
} else { } else {
if (old_m_item) { 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); 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) { 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); k_add_head(marks_store, m_item);
} }
} }
@ -7186,7 +7131,7 @@ bool marks_fill(PGconn *conn)
if (!ok) if (!ok)
break; break;
marks_root = add_to_ktree(marks_root, item, cmp_marks); add_to_ktree(marks_root, item);
k_add_head(marks_store, item); k_add_head(marks_store, item);
tick(); tick();

453
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 * 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 * 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 Yo true
#define No false #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) if (node == NULL)
FAIL("%s", "OOM"); 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; tree->cmp_funct = cmp_funct;
ktree->red = RED_BLACK;
ktree->parent = nil;
ktree->left = nil;
ktree->right = nil;
ktree->data = NULL;
ktree->test = 0;
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"); FAIL("%s", "OOM");
ktree->isNil = No; knode->isNil = No;
ktree->red = RED_RED; knode->red = RED_RED;
ktree->parent = nil; knode->parent = nil;
ktree->left = nil; knode->left = nil;
ktree->right = nil; knode->right = nil;
ktree->data = data; knode->data = data;
ktree->test = 0; knode->test = 0;
return ktree; return knode;
} }
static int bCount = 0; static int bCount = 0;
@ -73,54 +87,54 @@ static long getTestValue()
return ++testValue; 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; char col;
if (root->isNil == Yo) if (node->isNil == Yo)
return; return;
if (root->left->isNil == No) if (node->left->isNil == No)
{ {
path[pos] = 'L'; path[pos] = 'L';
path[pos+1] = '\0'; 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'; path[pos] = '\0';
if (root->red == RED_RED) if (node->red == RED_RED)
col = 'R'; col = 'R';
else else
// if (root->red == RED_BLACK) // if (node->red == RED_BLACK)
col = 'B'; 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] = 'R';
path[pos+1] = '\0'; 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]; char buf[42424];
printf("dump:\n"); printf("dump:\n");
if (root->isNil == No) if (tree->root->isNil == No)
{ {
buf[0] = 'T'; buf[0] = 'T';
buf[1] = '\0'; buf[1] = '\0';
show_ktree(root, buf, 1, dsp_funct); show_ktree(tree->root, buf, 1, dsp_funct);
} }
else 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_TREE_CTX ctx[1];
K_ITEM *item; K_ITEM *item;
@ -154,11 +168,11 @@ void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL
if (msg) if (msg)
fprintf(stream, "%s %s\n", stamp, msg); fprintf(stream, "%s %s\n", stamp, msg);
else 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) while (item)
{ {
list->dsp_func(item, stream); 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); 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) 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); 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) if (cur->red != RED_RED)
count++; count++;
@ -259,108 +273,118 @@ static void bTest(K_TREE *root, K_TREE *cur, char *msg, int count, KTREE_FFL_ARG
else else
FAIL("BTESTVALUE '%s' count=%d", msg, count); FAIL("BTESTVALUE '%s' count=%d", msg, count);
bTest(root, cur->left, msg, count, KTREE_FFL_PASS); bTest(cur->left, msg, count, KTREE_FFL_PASS);
bTest(root, cur->right, 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; bCount = 0;
bTestValue = getTestValue(); 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) if (node->test != lrpTestValue)
top->test = lrpTestValue; node->test = lrpTestValue;
else else
FAIL("LRPTESTVALUE '%s'", msg); 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); 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); 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; return;
if (debugNil) if (debugNil)
{ {
nilTestValue = getTestValue(); 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(); lrpTestValue = getTestValue();
lrpTest(root, msg, KTREE_FFL_PASS); lrpTest(tree->root, msg, KTREE_FFL_PASS);
} }
if (debugColor && root->isNil == No) if (debugColor && tree->root->isNil == No)
bTestInit(root, msg, KTREE_FFL_PASS); 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) while (node->left->isNil == No)
root = root->left; node = node->left;
*ctx = root; *ctx = node;
return(root->data); return(node->data);
} }
*ctx = NULL; *ctx = NULL;
return(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) while (node->right->isNil == No)
root = root->right; node = node->right;
*ctx = root; *ctx = node;
return(root->data); return(node->data);
} }
*ctx = NULL; *ctx = NULL;
return(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_ITEM *_next_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS)
{ {
K_TREE *parent; K_NODE *parent;
K_TREE *ktree = (K_TREE *)(*ctx); K_NODE *knode = (K_NODE *)(*ctx);
if (ktree->isNil == No) if (knode->isNil == No)
{ {
if (ktree->right->isNil == No) if (knode->right->isNil == No)
return(first_in_ktree(ktree->right, ctx)); return(_first_in_knode(knode->right, ctx, KTREE_FFL_PASS));
else else
{ {
parent = ktree->parent; parent = knode->parent;
while (parent->isNil == No && ktree == parent->right) while (parent->isNil == No && knode == parent->right)
{ {
ktree = parent; knode = parent;
parent = parent->parent; parent = parent->parent;
} }
if (parent->isNil == No) 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_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS)
{ {
K_TREE *parent; K_NODE *parent;
K_TREE *ktree = (K_TREE *)(*ctx); K_NODE *knode = (K_NODE *)(*ctx);
if (ktree->isNil == No) if (knode->isNil == No)
{ {
if (ktree->left->isNil == No) if (knode->left->isNil == No)
return(last_in_ktree(ktree->left, ctx)); return(_last_in_knode(knode->left, ctx, KTREE_FFL_PASS));
else else
{ {
parent = ktree->parent; parent = knode->parent;
while (parent->isNil == No && ktree == parent->left) while (parent->isNil == No && knode == parent->left)
{ {
ktree = parent; knode = parent;
parent = parent->parent; parent = parent->parent;
} }
if (parent->isNil == No) if (parent->isNil == No)
@ -404,9 +428,9 @@ K_ITEM *_prev_in_ktree(K_TREE_CTX *ctx, KTREE_FFL_ARGS)
return(NULL); 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; rotate = about->right;
about->right = rotate->left; about->right = rotate->left;
@ -432,9 +456,9 @@ static K_TREE *left_rotate(K_TREE *root, K_TREE *about)
return(root); 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; rotate = about->left;
about->left = rotate->right; about->left = rotate->right;
@ -458,50 +482,50 @@ static K_TREE *right_rotate(K_TREE *root, K_TREE *about)
return(root); 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_NODE *knode;
K_TREE *x, *y; K_NODE *x, *y;
K_TREE *pp; K_NODE *pp;
cmp_t cmp; cmp_t cmp;
if (root == NULL) if (tree == NULL)
FAIL("%s", "ADDNULL add ktree is 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) if (tree->root->parent != nil && tree->root->parent != NULL)
FAIL("%s", "ADDROOT add root isn't the root"); 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) if (tree->root != nil)
free(root); free(tree->root);
root = ktree; tree->root = knode;
} }
else else
{ {
x = root; x = tree->root;
y = nil; y = nil;
while (x->isNil == No) while (x->isNil == No)
{ {
y = x; y = x;
if ((cmp = (*cmp_funct)(ktree->data, x->data)) < 0) if ((cmp = tree->cmp_funct(knode->data, x->data)) < 0)
x = x->left; x = x->left;
else else
x = x->right; x = x->right;
} }
ktree->parent = y; knode->parent = y;
if (cmp < 0) if (cmp < 0)
y->left = ktree; y->left = knode;
else else
y->right = ktree; y->right = knode;
x = ktree; x = knode;
while (x != root && x->parent->red == RED_RED) while (x != tree->root && x->parent->red == RED_RED)
{ {
pp = x->parent->parent; pp = x->parent->parent;
if (x->parent == pp->left) 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) if (x == x->parent->right)
{ {
x = x->parent; x = x->parent;
root = left_rotate(root, x); tree->root = left_rotate(tree->root, x);
pp = x->parent->parent; pp = x->parent->parent;
} }
x->parent->red = RED_BLACK; x->parent->red = RED_BLACK;
pp->red = RED_RED; pp->red = RED_RED;
root = right_rotate(root, pp); tree->root = right_rotate(tree->root, pp);
} }
} }
else 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) if (x == x->parent->left)
{ {
x = x->parent; x = x->parent;
root = right_rotate(root, x); tree->root = right_rotate(tree->root, x);
pp = x->parent->parent; pp = x->parent->parent;
} }
x->parent->red = RED_BLACK; x->parent->red = RED_BLACK;
pp->red = RED_RED; pp->red = RED_RED;
root = left_rotate(root, pp); tree->root = left_rotate(tree->root, pp);
} }
} }
} }
} }
root->red = RED_BLACK; tree->root->red = RED_BLACK;
//check_ktree(root, "<add", NULL, 1, 1, 1, KTREE_FFL_PASS);
return(root); //check_ktree(tree, "<add", NULL, 1, 1, 1, KTREE_FFL_PASS);
} }
K_ITEM *_find_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_in_ktree(K_TREE *tree, K_ITEM *data, K_TREE_CTX *ctx, KTREE_FFL_ARGS)
{ {
K_NODE *knode;
cmp_t cmp = -1; cmp_t cmp = -1;
if (ktree == NULL) if (tree == NULL)
FAIL("%s", "FINDNULL find ktree is NULL"); FAIL("%s", "FINDNULL find tree is NULL");
if (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) if (cmp > 0)
ktree = ktree->left; knode = knode->left;
else else
ktree = ktree->right; knode = knode->right;
} }
} }
if (ktree->isNil == No) if (knode->isNil == No)
{ {
*ctx = ktree; *ctx = knode;
return(ktree->data); return(knode->data);
} }
else 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; cmp_t cmp = -1, oldcmp = -1;
if (ktree == NULL) if (tree == NULL)
FAIL("%s", "FINDNULL find_after ktree is 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; oldcmp = cmp;
if (cmp > 0) if (cmp > 0)
ktree = ktree->left; knode = knode->left;
else else
ktree = ktree->right; knode = knode->right;
} }
} }
if (ktree->isNil == No) if (knode->isNil == No)
{ {
*ctx = ktree; *ctx = knode;
return next_in_ktree(ctx); return next_in_ktree(ctx);
} }
else 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; cmp_t cmp = 1, oldcmp = 1;
if (ktree == NULL) if (tree == NULL)
FAIL("%s", "FINDNULL find_before ktree is 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; oldcmp = cmp;
if (cmp > 0) if (cmp > 0)
ktree = ktree->left; knode = knode->left;
else else
ktree = ktree->right; knode = knode->right;
} }
} }
if (ktree->isNil == No) if (knode->isNil == No)
{ {
*ctx = ktree; *ctx = knode;
return prev_in_ktree(ctx); return prev_in_ktree(ctx);
} }
else 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) while (fix != root && fix->red != RED_RED)
{ {
@ -758,37 +796,40 @@ static K_TREE *removeFixup(K_TREE *root, K_TREE *fix)
return root; 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' // 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_CTX tmpctx[1];
K_TREE *found; K_NODE *found;
K_ITEM *fdata; K_ITEM *fdata;
K_TREE *x, *y, *nil2; K_NODE *x, *y, *nil2;
// cmp_t cmp; // cmp_t cmp;
int yred; 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) if (tree == NULL)
FAIL("%s", "REMNULL remove ktree is 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; *ctx = NULL;
return(root); return;
} }
if (root->parent->isNil == No) if (tree->root->parent->isNil == No)
FAIL("%s", "REMROOT remove root isn't the root"); 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) 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"); FAIL("%s", "BADFIND cmp(found, remove) != 0");
found = *ctx; 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; nil2 = NULL;
else else
{ {
nil2 = new_ktree(); nil2 = _new_knode(KTREE_FFL_PASS);
x = nil2; x = nil2;
} }
x->parent = y->parent; x->parent = y->parent;
if (x->parent->isNil == Yo) if (x->parent->isNil == Yo)
root = x; tree->root = x;
else else
{ {
if (x->parent->left == y) 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 (y != found)
{ {
if (root == found) if (tree->root == found)
root = y; tree->root = y;
if (x == found) if (x == found)
x = y; 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) if (yred != RED_RED)
root = removeFixup(root, x); tree->root = removeFixup(tree->root, x);
if (nil2 != NULL) 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) if (nil2->parent->isNil == No && nil2->parent->right == nil2)
nil2->parent->right = nil; nil2->parent->right = nil;
if (root == nil2) if (tree->root == nil2)
root = nil; tree->root = nil;
/* /*
if (dbg != 0) if (dbg != 0)
@ -889,24 +930,24 @@ DBG("@remove nil2->left wasn't nil!!!\n");
DBG("@remove nil2->right wasn't nil!!!\n"); DBG("@remove nil2->right wasn't nil!!!\n");
} }
cmp = 0; cmp = 0;
fdata = first_in_ktree(root, tmpctx);; fdata = first_in_ktree(tree, tmpctx);;
while (fdata != NULL) while (fdata != NULL)
{ {
cmp++; cmp++;
x = *tmpctx; x = *tmpctx;
if (x == nil2) if (x == nil2)
{ {
DBG("@remove found nil2 in ktree %f!!!\n", cmp); DBG("@remove found nil2 in ktree %d!!!\n", (int)cmp);
} }
else else
if (x->left == nil2) 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 else
if (x->right == nil2) 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);; fdata = next_in_ktree(tmpctx);;
@ -920,10 +961,10 @@ DBG("@remove found nil2 in ktree(right) %f!!!\n", cmp);
if (dbg != 0) if (dbg != 0)
{ {
cmp = 0; cmp = 0;
fdata = first_in_ktree(root, tmpctx);; fdata = first_in_ktree(tree, tmpctx);;
while (fdata != NULL) while (fdata != NULL)
{ {
if (cmp_funct(fdata, root->data) < 0) if (tree->cmp_funct(fdata, tree->root->data) < 0)
cmp--; cmp--;
else else
cmp++; cmp++;
@ -932,52 +973,48 @@ if (dbg != 0)
} }
if (cmp < -10 || cmp > 10) if (cmp < -10 || cmp > 10)
{ {
DBG("@remove after balance=%f :(\n", cmp); DBG("@remove after balance=%d :(\n", (int)cmp);
} }
} }
*/ */
//check_ktree(root, "<remove", NULL, 1, 1, 1, KTREE_FFL_PASS); //check_ktree(tree, "<remove", NULL, 1, 1, 1, KTREE_FFL_PASS);
return root; return;
} }
K_TREE *_remove_from_ktree_free(K_TREE *root, K_ITEM *data, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS) void _remove_from_ktree_free(K_TREE *root, K_ITEM *data, KTREE_FFL_ARGS)
{ {
K_TREE_CTX ctx[1]; K_TREE_CTX ctx[1];
root = _remove_from_ktree(root, data, cmp_funct, ctx, KTREE_FFL_PASS); _remove_from_ktree(root, data, ctx, KTREE_FFL_PASS);
if (*ctx) if (*ctx)
free(*ctx); free(*ctx);
return root;
} }
static void free_ktree_sub(K_TREE *ktree, void (*free_funct)(void *)) static void free_ktree_sub(K_NODE *knode, void (*free_funct)(void *))
{ {
if (ktree != NULL && ktree != nil) if (knode != NULL && knode != nil)
{ {
if (ktree->data != NULL && free_funct) if (knode->data != NULL && free_funct)
(*free_funct)(ktree->data); free_funct(knode->data);
free_ktree_sub(ktree->left, free_funct); free_ktree_sub(knode->left, free_funct);
free_ktree_sub(ktree->right, 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) if (tree == NULL)
FAIL("%s", "FREENULL free NULL ktree"); FAIL("%s", "FREENULL free NULL tree");
if (ktree->parent != NULL && ktree->parent != nil)
FAIL("%s", "FREENOTROOT free ktree not root");
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);
} }

65
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 * 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 * 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_BIGINT CMP_BIG
#define CMP_DOUBLE CMP_BIG #define CMP_DOUBLE CMP_BIG
typedef struct ktree typedef struct knode
{ {
bool isNil; bool isNil;
bool red; bool red;
struct ktree *parent; struct knode *parent;
struct ktree *left; struct knode *left;
struct ktree *right; struct knode *right;
K_ITEM *data; K_ITEM *data;
long test; long test;
} K_NODE;
typedef struct ktree
{
K_NODE *root;
cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *);
} K_TREE; } K_TREE;
typedef void *K_TREE_CTX; typedef void *K_TREE_CTX;
extern K_TREE *_new_ktree(KTREE_FFL_ARGS); extern K_TREE *_new_ktree(cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), KTREE_FFL_ARGS);
#define new_ktree() _new_ktree(KLIST_FFL_HERE) #define new_ktree(_cmp_funct) _new_ktree(_cmp_funct, KLIST_FFL_HERE)
extern void _dump_ktree(K_TREE *root, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS); extern void _dump_ktree(K_TREE *tree, char *(*dsp_funct)(K_ITEM *), KTREE_FFL_ARGS);
#define dump_ktree(_root, _dsp_funct) _dump_ktree(_root, _dsp_funct, KLIST_FFL_HERE) #define dump_ktree(_tree, _dsp_funct) _dump_ktree(_tree, _dsp_funct, KLIST_FFL_HERE)
extern void _dsp_ktree(K_LIST *list, K_TREE *root, char *filename, char *msg, KTREE_FFL_ARGS); extern void _dsp_ktree(K_LIST *list, K_TREE *tree, char *filename, char *msg, KTREE_FFL_ARGS);
#define dsp_ktree(_list, _root, _filename, _msg) _dsp_ktree(_list, _root, _filename, _msg, KLIST_FFL_HERE) #define dsp_ktree(_list, _tree, _filename, _msg) _dsp_ktree(_list, _tree, _filename, _msg, KLIST_FFL_HERE)
extern K_ITEM *_first_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS); extern K_ITEM *_first_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS);
#define first_in_ktree(_root, _ctx) _first_in_ktree(_root, _ctx, KLIST_FFL_HERE) #define first_in_ktree(_tree, _ctx) _first_in_ktree(_tree, _ctx, KLIST_FFL_HERE)
extern K_ITEM *_last_in_ktree(K_TREE *root, K_TREE_CTX *ctx, KTREE_FFL_ARGS); extern K_ITEM *_last_in_ktree(K_TREE *tree, K_TREE_CTX *ctx, KTREE_FFL_ARGS);
#define last_in_ktree(_root, _ctx) _last_in_ktree(_root, _ctx, KLIST_FFL_HERE) #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); 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) #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); 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) #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); extern void _add_to_ktree(K_TREE *tree, K_ITEM *data, KTREE_FFL_ARGS);
#define add_to_ktree(_root, _data, _cmp_func) _add_to_ktree(_root, _data, _cmp_func, KLIST_FFL_HERE) #define add_to_ktree(_tree, _data) _add_to_ktree(_tree, _data, 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); extern K_ITEM *_find_in_ktree(K_TREE *tree, K_ITEM *data, 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) #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, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); 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, _cmp_funct, _ctx) _find_after_in_ktree(_ktree, _data, _cmp_funct, _ctx, KLIST_FFL_HERE) #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, cmp_t (*cmp_funct)(K_ITEM *, K_ITEM *), K_TREE_CTX *ctx, KTREE_FFL_ARGS); 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, _cmp_funct, _ctx) _find_before_in_ktree(_ktree, _data, _cmp_funct, _ctx, KLIST_FFL_HERE) #define find_before_in_ktree(_ktree, _data, _ctx) _find_before_in_ktree(_ktree, _data, _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 void _remove_from_ktree(K_TREE *tree, K_ITEM *data, 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); extern void _remove_from_ktree_free(K_TREE *tree, K_ITEM *data, KTREE_FFL_ARGS);
#define remove_from_ktree(_root, _data, _cmp_funct) _remove_from_ktree_free(_root, _data, _cmp_funct, KLIST_FFL_HERE) #define remove_from_ktree(_tree, _data) _remove_from_ktree_free(_tree, _data, KLIST_FFL_HERE)
extern K_TREE *_free_ktree(K_TREE *root, void (*free_funct)(void *), KTREE_FFL_ARGS); extern void _free_ktree(K_TREE *tree, void (*free_funct)(void *), KTREE_FFL_ARGS);
#define free_ktree(_root, _free_funct) _free_ktree(_root, _free_funct, KLIST_FFL_HERE) #define free_ktree(_tree, _free_funct) do { \
_free_ktree(_tree, _free_funct, KLIST_FFL_HERE); \
_tree = NULL; \
} while (0)
#endif #endif

Loading…
Cancel
Save