int forwards_next_root(struct iter_forwards* fwd, uint16_t* dclass) { struct iter_forward_zone key; rbnode_t* n; struct iter_forward_zone* p; if(*dclass == 0) { /* first root item is first item in tree */ n = rbtree_first(fwd->tree); if(n == RBTREE_NULL) return 0; p = (struct iter_forward_zone*)n; if(dname_is_root(p->name)) { *dclass = p->dclass; return 1; } /* root not first item? search for higher items */ *dclass = p->dclass + 1; return forwards_next_root(fwd, dclass); } /* find class n in tree, we may get a direct hit, or if we don't * this is the last item of the previous class so rbtree_next() takes * us to the next root (if any) */ key.node.key = &key; key.name = (uint8_t*)"\000"; key.namelen = 1; key.namelabs = 0; key.dclass = *dclass; n = NULL; if(rbtree_find_less_equal(fwd->tree, &key, &n)) { /* exact */ return 1; } else { /* smaller element */ if(!n || n == RBTREE_NULL) return 0; /* nothing found */ n = rbtree_next(n); if(n == RBTREE_NULL) return 0; /* no higher */ p = (struct iter_forward_zone*)n; if(dname_is_root(p->name)) { *dclass = p->dclass; return 1; } /* not a root node, return next higher item */ *dclass = p->dclass+1; return forwards_next_root(fwd, dclass); } }
int iter_get_next_root(struct iter_hints* hints, struct iter_forwards* fwd, uint16_t* c) { uint16_t c1 = *c, c2 = *c; int r1 = hints_next_root(hints, &c1); int r2 = forwards_next_root(fwd, &c2); if(!r1 && !r2) /* got none, end of list */ return 0; else if(!r1) /* got one, return that */ *c = c2; else if(!r2) *c = c1; else if(c1 < c2) /* got both take smallest */ *c = c1; else *c = c2; return 1; }