JRB jrb_find_gte_gen(JRB n, Jval key,int (*fxn)(Jval, Jval), int *fnd) { int cmp; *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_str called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; cmp = (*fxn)(key, n->blink->key); if (cmp == 0) { *fnd = 1; return n->blink; } if (cmp > 0) return n; else n = n->parent; while (1) { if (isext(n)) return n; cmp = (*fxn)(key, getlext(n)->key); if (cmp == 0) { *fnd = 1; return getlext(n); } if (cmp < 0) n = n->flink ; else n = n->blink; } }
JRB jrb_find_gte_str(JRB n, char *key, int *fnd) { int cmp; *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_str called on non-head 0x%x\n", n); exit(1); } if (n->parent == n) return n; cmp = strcmp(key, n->blink->key.s); if (cmp == 0) { *fnd = 1; return n->blink; } if (cmp > 0) return n; else n = n->parent; while (1) { if (isext(n)) return n; cmp = strcmp(key, getlext(n)->key.s); if (cmp == 0) { *fnd = 1; return getlext(n); } if (cmp < 0) n = n->flink ; else n = n->blink; } }
JRB jrb_find_gte_dbl(JRB n, double dkey, int *fnd) { *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_dbl called on non-head 0x%x\n", n); exit(1); } if (n->parent == n) return n; if (dkey == n->blink->key.d) { *fnd = 1; return n->blink; } if (dkey > n->blink->key.d) return n; else n = n->parent; while (1) { if (isext(n)) return n; if (dkey == getlext(n)->key.d) { *fnd = 1; return getlext(n); } n = (dkey < getlext(n)->key.d) ? n->flink : n->blink; } }
void jrb_iprint_tree(JRB t, int level) { int i; if (ishead(t) && t->parent == t) { printf("tree 0x%x is empty\n", t); } else if (ishead(t)) { printf("Head: 0x%x. Root = 0x%x, < = 0x%x, > = 0x%x\n", t, t->parent, t->blink, t->flink); jrb_iprint_tree(t->parent, 0); } else { if (isext(t)) { for (i = 0; i < level; i++) putchar(' '); printf("Ext node 0x%x: %c,%c: p=0x%x, <=0x%x, >=0x%x k=%d\n", t, isred(t)?'R':'B', isleft(t)?'l':'r', t->parent, t->blink, t->flink, t->key.i); } else { jrb_iprint_tree(t->flink, level+2); jrb_iprint_tree(t->blink, level+2); for (i = 0; i < level; i++) putchar(' '); printf("Int node 0x%x: %c,%c: l=0x%x, r=0x%x, p=0x%x, lr=(%d,%d)\n", t, isred(t)?'R':'B', isleft(t)?'l':'r', t->flink, t->blink, t->parent, getlext(t)->key.i, getrext(t)->key.i); } } }
JRB jrb_find_gte_vptr(JRB n, void *vkey, int *fnd) { *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; if ((char *)vkey == (char *)n->blink->key.v) { *fnd = 1; return n->blink; } if ((char *)vkey > (char *)n->blink->key.v) return n; else n = n->parent; while (1) { if (isext(n)) return n; if ((char *)vkey == (char *)getlext(n)->key.v) { *fnd = 1; return getlext(n); } n = ((char *)vkey < (char *)getlext(n)->key.v) ? n->flink : n->blink; } }
JRB jrb_find_gte_int(JRB n, int ikey, int *fnd) { *fnd = 0; if (!ishead(n)) { fprintf(stderr, "jrb_find_gte_int called on non-head 0x%p\n", (void *)n); exit(1); } if (n->parent == n) return n; if (ikey == n->blink->key.i) { *fnd = 1; return n->blink; } if (ikey > n->blink->key.i) return n; else n = n->parent; while (1) { if (isext(n)) return n; if (ikey == getlext(n)->key.i) { *fnd = 1; return getlext(n); } n = (ikey < getlext(n)->key.i) ? n->flink : n->blink; } }