static inline int si_recovercomplete(sitrack *track, sr *r, si *index, srbuf *buf) { /* prepare and build primary index */ sr_bufreset(buf); srrbnode *p = sr_rbmin(&track->i); while (p) { sinode *n = srcast(p, sinode, node); int rc = sr_bufadd(buf, r->a, &n, sizeof(sinode**)); if (srunlikely(rc == -1)) return sr_malfunction(r->e, "%s", "memory allocation failed"); p = sr_rbnext(&track->i, p); } sriter i; sr_iterinit(sr_bufiterref, &i, r); sr_iteropen(sr_bufiterref, &i, buf, sizeof(sinode*)); while (sr_iterhas(sr_bufiterref, &i)) { sinode *n = sr_iterof(sr_bufiterref, &i); if (n->recover & SI_RDB_REMOVE) { int rc = si_nodefree(n, r, 1); if (srunlikely(rc == -1)) return -1; sr_iternext(sr_bufiterref, &i); continue; } n->recover = SI_RDB; si_insert(index, r, n); si_plannerupdate(&index->p, SI_COMPACT|SI_BRANCH, n); sr_iternext(sr_bufiterref, &i); } return 0; }
static inline int si_trackvalidate(sitrack *track, srbuf *buf, sr *r, si *i) { sr_bufreset(buf); srrbnode *p = sr_rbmax(&track->i); while (p) { sinode *n = srcast(p, sinode, node); switch (n->recover) { case SI_RDB|SI_RDB_DBI|SI_RDB_DBSEAL|SI_RDB_REMOVE: case SI_RDB|SI_RDB_DBSEAL|SI_RDB_REMOVE: case SI_RDB|SI_RDB_REMOVE: case SI_RDB_UNDEF|SI_RDB_DBSEAL|SI_RDB_REMOVE: case SI_RDB|SI_RDB_DBI|SI_RDB_DBSEAL: case SI_RDB|SI_RDB_DBI: case SI_RDB: case SI_RDB|SI_RDB_DBSEAL: case SI_RDB_UNDEF|SI_RDB_DBSEAL: { /* match and remove any leftover ancestor */ sinode *ancestor = si_trackget(track, n->self.id.parent); if (ancestor && (ancestor != n)) ancestor->recover |= SI_RDB_REMOVE; break; } case SI_RDB_DBSEAL: { /* find parent */ sinode *parent = si_trackget(track, n->self.id.parent); if (parent) { /* schedule node for removal, if has incomplete merges */ if (parent->recover & SI_RDB_DBI) n->recover |= SI_RDB_REMOVE; else parent->recover |= SI_RDB_REMOVE; } if (! (n->recover & SI_RDB_REMOVE)) { /* complete node */ int rc = si_nodecomplete(n, r, i->conf); if (srunlikely(rc == -1)) return -1; n->recover = SI_RDB; } break; } default: /* corrupted states */ return sr_malfunction(r->e, "corrupted database repository: %s", i->conf->path); } p = sr_rbprev(&track->i, p); } return 0; }
int si_profiler(siprofiler *p) { uint64_t memory_used = 0; srrbnode *pn; sinode *n; pn = sr_rbmin(&p->i->i); while (pn) { n = srcast(pn, sinode, node); p->total_node_count++; p->count += n->i0.count; p->count += n->i1.count; p->total_branch_count += n->branch_count; if (p->total_branch_max < n->branch_count) p->total_branch_max = n->branch_count; if (n->branch_count < 20) p->histogram_branch[n->branch_count]++; else p->histogram_branch_20plus++; memory_used += sv_indexused(&n->i0); memory_used += sv_indexused(&n->i1); sibranch *b = n->branch; while (b) { p->count += b->index.h->keys; p->count_dup += b->index.h->dupkeys; int indexsize = sd_indexsize(b->index.h); p->total_node_size += indexsize + b->index.h->total; p->total_node_origin_size += indexsize + b->index.h->totalorigin; b = b->next; } pn = sr_rbnext(&p->i->i, pn); } if (p->total_node_count > 0) p->total_branch_avg = p->total_branch_count / p->total_node_count; p->memory_used = memory_used; p->read_disk = p->i->read_disk; p->read_cache = p->i->read_cache; si_profiler_histogram_branch(p); return 0; }
n->file.file, strerror(errno)); rcret = -1; } } si_nodefree_branches(n, r); rc = si_nodeclose(n, r); if (srunlikely(rc == -1)) rcret = -1; sr_free(r->a, n); return rcret; } uint32_t si_vgc(sra*, svv*); sr_rbtruncate(si_nodegc_indexgc, si_vgc((sra*)arg, srcast(n, svv, node))) int si_nodegc_index(sr *r, svindex *i) { if (i->i.root) si_nodegc_indexgc(i->i.root, r->a); sv_indexinit(i); return 0; } int si_nodecmp(sinode *n, void *key, int size, srcomparator *c) { sdindexpage *min = sd_indexmin(&n->self.index); sdindexpage *max = sd_indexmax(&n->self.index); int l = sr_compare(c, sd_indexpage_min(min), min->sizemin, key, size); int r = sr_compare(c, sd_indexpage_max(max), max->sizemin, key, size);