uint64_t sx_max(sxmanager *m) { ss_spinlock(&m->lock); uint64_t id = 0; if (sx_count(m) > 0) { ssrbnode *node = ss_rbmax(&m->i); sx *max = sscast(node, sx, node); id = max->id; } ss_spinunlock(&m->lock); return id; }
static inline int si_trackvalidate(sitrack *track, ssbuf *buf, sr *r, si *i) { ss_bufreset(buf); ssrbnode *p = ss_rbmax(&track->i); while (p) { sinode *n = sscast(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->scheme); if (ssunlikely(rc == -1)) return -1; n->recover = SI_RDB; } break; } default: /* corrupted states */ return sr_malfunction(r->e, "corrupted database repository: %s", i->scheme->path); } p = ss_rbprev(&track->i, p); } return 0; }
ssrbnode *ss_rbprev(ssrb *t, ssrbnode *n) { if (ssunlikely(n == NULL)) return ss_rbmax(t); if (n->l) { n = n->l; while (n->r) n = n->r; return n; } ssrbnode *p; while ((p = n->p) && p->l == n) n = p; return p; }