static inline int si_plannerpeek_checkpoint(siplanner *p, siplan *plan) { /* try to peek a node which has min * lsn <= required value */ int rc_inprogress = 0; sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->branch, pn))) { n = sscast(pn, sinode, nodebranch); if (n->i0.lsnmin <= plan->a) { if (n->flags & SI_LOCK) { rc_inprogress = 2; continue; } goto match; } } if (rc_inprogress) plan->explain = SI_ERETRY; return rc_inprogress; match: si_nodelock(n); plan->explain = SI_ENONE; plan->node = n; return 1; }
static inline int si_plannerpeek_gc(siplanner *p, siplan *plan) { /* try to peek a node with a biggest number * of branches which is ready for gc */ int rc_inprogress = 0; sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->compact, pn))) { n = sscast(pn, sinode, nodecompact); sdindexheader *h = n->self.index.h; if (sslikely(h->dupkeys == 0) || (h->dupmin >= plan->a)) continue; uint32_t used = (h->dupkeys * 100) / h->keys; if (used >= plan->b) { if (n->flags & SI_LOCK) { rc_inprogress = 2; continue; } goto match; } } if (rc_inprogress) plan->explain = SI_ERETRY; return rc_inprogress; match: si_nodelock(n); plan->explain = SI_ENONE; plan->node = n; return 1; }
static void ss_rq_test3(void) { ssa a; ss_aopen(&a, &ss_stda); ssrq q; t( ss_rqinit(&q, &a, 1, 10) == 0 ); ssrqnode *an = ss_malloc(&a, sizeof(ssrqnode)); ssrqnode *bn = ss_malloc(&a, sizeof(ssrqnode)); ssrqnode *cn = ss_malloc(&a, sizeof(ssrqnode)); t( an != NULL ); t( bn != NULL ); t( cn != NULL ); ss_rqinitnode(an); ss_rqinitnode(bn); ss_rqinitnode(cn); ss_rqadd(&q, an, 1); ss_rqadd(&q, bn, 2); ss_rqdelete(&q, bn); ss_rqadd(&q, cn, 3); int i = 3; ssrqnode *n = NULL; while ((n = ss_rqprev(&q, n))) { t( i == n->v ); i = 1; } ss_rqfree(&q, &a); ss_free(&a, an); ss_free(&a, bn); ss_free(&a, cn); }
static void ss_rq_test8(void) { ssa a; ss_aopen(&a, &ss_stda); ssrq q; t( ss_rqinit(&q, &a, 10, 100) == 0 ); ssrqnode *an = ss_malloc(&a, sizeof(ssrqnode)); ssrqnode *bn = ss_malloc(&a, sizeof(ssrqnode)); ssrqnode *cn = ss_malloc(&a, sizeof(ssrqnode)); ssrqnode *dn = ss_malloc(&a, sizeof(ssrqnode)); t( an != NULL ); t( bn != NULL ); t( cn != NULL ); t( dn != NULL ); ss_rqinitnode(an); ss_rqinitnode(bn); ss_rqinitnode(cn); ss_rqinitnode(dn); ss_rqadd(&q, an, 0); ss_rqadd(&q, bn, 10); ss_rqadd(&q, cn, 20); ss_rqadd(&q, dn, 30); int i = 30; ssrqnode *n = NULL; while ((n = ss_rqprev(&q, n))) i -= 10; ss_rqfree(&q, &a); ss_free(&a, an); ss_free(&a, bn); ss_free(&a, cn); ss_free(&a, dn); }
static inline int si_plannerpeek_branch(siplanner *p, siplan *plan) { /* try to peek a node with a biggest in-memory index */ sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->branch, pn))) { n = sscast(pn, sinode, nodebranch); if (n->flags & SI_LOCK) continue; if (n->used >= plan->a) goto match; return 0; } return 0; match: si_nodelock(n); plan->explain = SI_EINDEX_SIZE; plan->node = n; return 1; }
static void si_profiler_histogram_temperature(siprofiler *p) { /* build histogram */ struct { int nodes; int branches; } h[100]; memset(h, 0, sizeof(h)); sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->i->p.temp, pn))) { n = sscast(pn, sinode, nodetemp); h[pn->v].nodes++; h[pn->v].branches += n->branch_count; } /* prepare histogram string */ int count = 0; int i = 99; int size = 0; while (i >= 0 && count < 10) { if (h[i].nodes == 0) { i--; continue; } size += snprintf(p->histogram_temperature_sz + size, sizeof(p->histogram_temperature_sz) - size, "[%d]:%d-%d ", i, h[i].nodes, h[i].branches); i--; count++; } if (size == 0) p->histogram_temperature_ptr = NULL; else { p->histogram_temperature_ptr = p->histogram_temperature_sz; } }
static inline int si_plannerpeek_compact_temperature(siplanner *p, siplan *plan) { /* try to peek a hottest node with number of * branches >= watermark */ sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->temp, pn))) { n = sscast(pn, sinode, nodetemp); if (n->flags & SI_LOCK) continue; if (n->branch_count >= plan->a) goto match; return 0; } return 0; match: si_nodelock(n); plan->explain = SI_ETEMP; plan->node = n; return 1; }
static inline int si_plannerpeek_compact(siplanner *p, siplan *plan) { /* try to peek a node with a biggest number * of branches */ sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->compact, pn))) { n = sscast(pn, sinode, nodecompact); if (n->flags & SI_LOCK) continue; if (n->branch_count >= plan->a) goto match; return 0; } return 0; match: si_nodelock(n); plan->explain = SI_EBRANCH_COUNT; plan->node = n; return 1; }
static inline int si_plannerpeek_age(siplanner *p, siplan *plan) { /* try to peek a node with update >= a and in-memory * index size >= b */ /* full scan */ uint64_t now = ss_utime(); sinode *n = NULL; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->branch, pn))) { n = sscast(pn, sinode, nodebranch); if (n->flags & SI_LOCK) continue; if (n->used >= plan->b && ((now - n->update_time) >= plan->a)) goto match; } return 0; match: si_nodelock(n); plan->explain = SI_EINDEX_AGE; plan->node = n; return 1; }
static inline int si_plannerpeek_backup(siplanner *p, siplan *plan) { /* try to peek a node which has * bsn <= required value */ int rc_inprogress = 0; sinode *n; ssrqnode *pn = NULL; while ((pn = ss_rqprev(&p->branch, pn))) { n = sscast(pn, sinode, nodebranch); if (n->backup < plan->a) { if (n->flags & SI_LOCK) { rc_inprogress = 2; continue; } goto match; } } if (rc_inprogress) { plan->explain = SI_ERETRY; return 2; } si *index = p->i; if (index->backup < plan->a) { plan->plan = SI_BACKUPEND; plan->node = 0; return 1; } return 0; match: si_nodelock(n); plan->explain = SI_ENONE; plan->node = n; return 1; }