void test_ahtable_find_prev() { fprintf(stderr, "finding prev for %zu keys ... \n", k); ahtable_build_index(T); ahtable_iter_t i; ahtable_iter_begin(T, &i, true); value_t* u; const char *key = NULL; char *dkey = NULL; size_t len = 0; while (!ahtable_iter_finished(&i)) { u = ahtable_iter_val(&i); key = ahtable_iter_key(&i, &len); /* increase key last byte by 1 and check result */ dkey = realloc(dkey, len); memcpy(dkey, key, len); ++dkey[len-1]; value_t *fp = NULL; int r = ahtable_find_leq(T, dkey, len, &fp); if (*fp != *u || r != -1) { fprintf(stderr, "[error] ahtable_find_leq should find %lu, " "but found prev=%lu and return -1, returned %d\n", *u, *fp, r); } ahtable_iter_next(&i); } ahtable_iter_free(&i); free(dkey); fprintf(stderr, "done.\n"); }
int hattrie_find_leq (hattrie_t* T, const char* key, size_t len, value_t** dst) { /* create node stack for traceback */ size_t sp = 0; node_ptr bs[NODESTACK_INIT]; /* base stack (will be enough mostly) */ node_ptr *ns = bs; /* generic ptr, could point to new mem */ ns[sp] = T->root; /* find node for given key */ int ret = 1; /* no node on the left matches */ node_ptr node = hattrie_find_ns(&ns, &sp, NODESTACK_INIT, &key, &len); if (node.flag == NULL) { *dst = hattrie_walk(ns, sp, key, hattrie_find_rightmost); if (ns != bs) free(ns); if (*dst) { return -1; /* found previous */ } return 1; /* no previous key found */ } /* assign value from trie or find in table */ if (*node.flag & NODE_TYPE_TRIE) { *dst = &node.t->val; ret = 0; /* found exact match */ } else { *dst = ahtable_tryget(node.b, key, len); if (*dst) { ret = 0; /* found exact match */ } else { /* look for previous in ahtable */ ret = ahtable_find_leq(node.b, key, len, dst); } } /* return if found equal or left in ahtable */ if (*dst == 0) { *dst = hattrie_walk(ns, sp, key, hattrie_find_rightmost); if (*dst) { ret = -1; /* found previous */ } else { ret = 1; /* no previous key found */ } } if (ns != bs) free(ns); return ret; }