int sp_catown(spcat *c, uint32_t idx, spv *v) { register sppage *p = c->i[idx]; /* equal or equal min or equal max */ switch (cmpkey(c, p, v->key, v->size)) { case 0: return 1; case -1: /* key > page */ /* key > max */ if (idx == c->count-1) return 1; break; case 1: /* key < page */ /* key < min */ if (idx == 0) return 1; break; } /* key > page && key < page+1.min */ if (c->cmp(v->key, v->size, c->i[idx + 1]->min->key, c->i[idx + 1]->min->size, c->cmparg) == -1) return 1; return 0; }
void test_ahtable_sorted_iteration() { fprintf(stderr, "iterating in order through %zu keys ... \n", k); ahtable_iter_t i; ahtable_iter_begin(T, &i, true); size_t count = 0; value_t* u; value_t v; char* prev_key = malloc(m_high + 1); size_t prev_len = 0; const char *key = NULL; size_t len = 0; while (!ahtable_iter_finished(&i)) { memcpy(prev_key, key, len); prev_len = len; ++count; key = ahtable_iter_key(&i, &len); if (prev_key != NULL && cmpkey(prev_key, prev_len, key, len) > 0) { fprintf(stderr, "[error] iteration is not correctly ordered.\n"); } u = ahtable_iter_val(&i); v = str_map_get(M, key, len); if (*u != v) { if (v == 0) { fprintf(stderr, "[error] incorrect iteration (%lu, %lu)\n", *u, v); } else { fprintf(stderr, "[error] incorrect iteration tally (%lu, %lu)\n", *u, v); } } // this way we will see an error if the same key is iterated through // twice str_map_set(M, key, len, 0); ahtable_iter_next(&i); } ahtable_iter_free(&i); free(prev_key); fprintf(stderr, "done.\n"); }
/* Search |tree| for an item matching |item|, and return it if found. Otherwise return |NULL|. */ struct AVLNode * AVL_Find(struct AVLNode *p, const void *item, AVLKEYCOMP cmpkey) { int dir; for (; p != NULL; p = p->Link[dir]) { int cmp = cmpkey(item, p); if (cmp == 0) break; dir = cmp > 0; } return (struct AVLNode *)p; }
sppage* sp_catfind(spcat *c, char *rkey, int size, uint32_t *index) { register int min = 0; register int max = c->count - 1; while (max >= min) { register int mid = min + ((max - min) >> 1); switch (cmpkey(c, c->i[mid], rkey, size)) { case -1: min = mid + 1; continue; case 1: max = mid - 1; continue; default: *index = mid; return c->i[mid]; } } *index = min; return NULL; }
/* Find node <= item */ struct AVLNode * AVL_FindPrev(struct AVLNode *p, const void *item, AVLKEYCOMP cmpkey) { int dir; struct AVLNode *l; if (p == NULL) return p; for (; p != NULL; p = p->Link[dir]) { int cmp = cmpkey(item, p); if (cmp == 0) return p; l = p; dir = cmp > 0; } if (dir == 0) return AVL_Prev(l); else return l; }
void test_hattrie_sorted_iteration() { fprintf(stderr, "iterating in order through %zu keys ... \n", k); hattrie_iter_t* i = hattrie_iter_begin(T, true); size_t count = 0; value_t* u; value_t v; char* key_copy = malloc(m_high + 1); char* prev_key = malloc(m_high + 1); memset(prev_key, 0, m_high + 1); size_t prev_len = 0; const char *key = NULL; size_t len = 0; while (!hattrie_iter_finished(i)) { memcpy(prev_key, key_copy, len); prev_key[len] = '\0'; prev_len = len; ++count; key = hattrie_iter_key(i, &len); /* memory for key may be changed on iter, copy it */ strncpy(key_copy, key, len); if (prev_key != NULL && cmpkey(prev_key, prev_len, key, len) > 0) { fprintf(stderr, "[error] iteration is not correctly ordered.\n"); } u = hattrie_iter_val(i); v = str_map_get(M, key, len); if (*u != v) { if (v == 0) { fprintf(stderr, "[error] incorrect iteration (%lu, %lu)\n", *u, v); } else { fprintf(stderr, "[error] incorrect iteration tally (%lu, %lu)\n", *u, v); } } // this way we will see an error if the same key is iterated through // twice str_map_set(M, key, len, 0); hattrie_iter_next(i); } if (count != M->m) { fprintf(stderr, "[error] iterated through %zu element, expected %zu\n", count, M->m); } hattrie_iter_free(i); free(prev_key); free(key_copy); fprintf(stderr, "done.\n"); }