void test_art_long_prefix(void) { art_tree t; int res = art_tree_init(&t); uintptr_t v; const char *s; fail_unless(res == 0); s = "this:key:has:a:long:prefix:3"; v = 3; fail_unless(NULL == art_insert(&t, (unsigned char *)s, (int)strlen(s) + 1, (void *)v)); s = "this:key:has:a:long:common:prefix:2"; v = 2; fail_unless(NULL == art_insert(&t, (unsigned char *)s, (int)strlen(s) + 1, (void *)v)); s = "this:key:has:a:long:common:prefix:1"; v = 1; fail_unless(NULL == art_insert(&t, (unsigned char *)s, (int)strlen(s) + 1, (void *)v)); // Search for the keys s = "this:key:has:a:long:common:prefix:1"; fail_unless( 1 == (uintptr_t)art_search(&t, (unsigned char *)s, (int)strlen(s) + 1)); s = "this:key:has:a:long:common:prefix:2"; fail_unless( 2 == (uintptr_t)art_search(&t, (unsigned char *)s, (int)strlen(s) + 1)); s = "this:key:has:a:long:prefix:3"; fail_unless( 3 == (uintptr_t)art_search(&t, (unsigned char *)s, (int)strlen(s) + 1)); { const char *expected[] = { "this:key:has:a:long:common:prefix:1", "this:key:has:a:long:common:prefix:2", "this:key:has:a:long:prefix:3", }; prefix_data p = {0, 3, expected}; fail_unless(!art_iter_prefix(&t, (unsigned char *)"this:key:has", 12, test_prefix_cb, &p)); diag("Count: %d Max: %d", p.count, p.max_count); fail_unless(p.count == p.max_count); } res = art_tree_destroy(&t); fail_unless(res == 0); }
// Searches the primary tree and the delta list for a filter static bloom_filter_wrapper* find_filter(bloom_filtmgr *mgr, char *filter_name) { // Search the tree first bloom_filter_wrapper *filt = art_search(mgr->filter_map, (unsigned char*)filter_name, strlen(filter_name)+1); if (filt) return filt; // Check if the primary has all delta changes if (mgr->primary_vsn == mgr->vsn) return NULL; // Search the delta list filter_list *current = mgr->delta; while (current) { // Check if this is a match if (current->type != BARRIER && strcmp(current->filter->filter->filter_name, filter_name) == 0) { return current->filter; } // Don't seek past what the primary map incorporates if (current->vsn == mgr->primary_vsn + 1) break; current = current->next; } // Not found return NULL; }
/** * Searches the primary tree and the delta list for a set */ static hlld_set_wrapper* find_set(hlld_setmgr *mgr, char *set_name) { // Search the tree first hlld_set_wrapper *set = art_search(mgr->set_map, set_name, strlen(set_name)+1); // If we found the set, check if it is active if (set) return set; // Check if the primary has all delta changes if (mgr->primary_vsn == mgr->vsn) return NULL; // Search the delta list set_list *current = mgr->delta; while (current) { // Check if this is a match if (current->type != BARRIER && strcmp(current->set->set->set_name, set_name) == 0) { return current->set; } // Don't seek past what the primary set map incorporates if (current->vsn == mgr->primary_vsn + 1) break; current = current->next; } // Not found return NULL; }
int search_element(struct ds_context *ctx) { PMEMobjpool *pop; TOID(var_string) value; int errors = 0; if (ctx == NULL) { errors++; } else if (ctx->pop == NULL) { errors++; } if (!errors) { pop = ctx->pop; printf("search key [%s]: ", (char *)ctx->key); value = art_search(pop, ctx->key, ctx->key_len); if (TOID_IS_NULL(value)) { printf("not found\n"); } else { printf("value [%s]\n", D_RO(value)->s); } } return errors; }
vio_function_info *vio_cdict_lookup(art_tree *cdict, const char *key, uint32_t klen) { unsigned char *real_key = alloca(klen + 1); for (uint32_t i = 0; i < klen; ++i) real_key[i] = (unsigned char)key[i]; real_key[klen] = '\0'; return (vio_function_info *)art_search(cdict, real_key, klen); }
END_TEST START_TEST(test_art_insert_copy_delete) { art_tree t; int res = init_art_tree(&t); fail_unless(res == 0); int len; char buf[512]; FILE *f = fopen("tests/words.txt", "r"); uintptr_t line = 1, nlines; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; fail_unless(NULL == art_insert(&t, buf, len, (void*)line)); line++; } nlines = line - 1; // Create a new tree art_tree t2; fail_unless(art_copy(&t2, &t) == 0); // Destroy the original res = destroy_art_tree(&t); fail_unless(res == 0); // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; // Search first, ensure all entries still // visible uintptr_t val = (uintptr_t)art_search(&t2, buf, len); fail_unless(line == val, "Line: %d Val: %" PRIuPTR " Str: %s\n", line, val, buf); // Delete, should get lineno back val = (uintptr_t)art_delete(&t2, buf, len); fail_unless(line == val, "Line: %d Val: %" PRIuPTR " Str: %s\n", line, val, buf); // Check the size fail_unless(art_size(&t2) == nlines - line); line++; } res = destroy_art_tree(&t2); fail_unless(res == 0); }
void test_art_insert_delete(void) { art_tree t; int res = art_tree_init(&t); int len; char buf[512]; FILE *f = fopen("thirdparty/libart/tests/words.txt", "r"); uintptr_t line = 1, nlines; fail_unless(res == 0); while (fgets(buf, sizeof buf, f)) { len = (int)strlen(buf); buf[len - 1] = '\0'; if (art_insert(&t, (unsigned char *)buf, len, (void *)line)) { fail("art_insert didn't return NULL"); } line++; } nlines = line - 1; // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { uintptr_t val; len = (int)strlen(buf); buf[len - 1] = '\0'; // Search first, ensure all entries still // visible val = (uintptr_t)art_search(&t, (unsigned char *)buf, len); if (line != val) { fail("Line: %d Val: %" PRIuPTR " Str: %s", line, val, buf); } // Delete, should get lineno back val = (uintptr_t)art_delete(&t, (unsigned char *)buf, len); if (line != val) { fail("Line: %d Val: %" PRIuPTR " Str: %s", line, val, buf); } // Check the size if (art_size(&t) != nlines - line) { fail("bad size after delete"); } line++; } // Check the minimum and maximum fail_unless(!art_minimum(&t)); fail_unless(!art_maximum(&t)); res = art_tree_destroy(&t); fail_unless(res == 0); }
int vio_dict_lookup(vio_dict *dict, const char *key, uint32_t klen, uint32_t *out) { /* art_search seems that it may have a bug/unexpected behavior where a key with non-null characters past klen doesn't find the value. */ unsigned char *real_key = alloca(klen + 1); for (uint32_t i = 0; i < klen; ++i) real_key[i] = (unsigned char)key[i]; real_key[klen] = '\0'; void *idx = art_search(&dict->words, real_key, klen); if (idx) *out = (uint32_t)idx - 1; return idx != NULL; }
void test_art_prefix(void) { art_tree t; void *v; art_tree_init(&t); fail_unless(art_insert(&t, (const unsigned char*)"food", 4, "food") == NULL); fail_unless(art_insert(&t, (const unsigned char*)"foo", 3, "foo") == NULL); diag("size is now %d", art_size(&t)); fail_unless(art_size(&t) == 2); fail_unless((v = art_search(&t, (const unsigned char*)"food", 4)) != NULL); diag("food lookup yields %s", v); fail_unless(v && strcmp((char*)v, "food") == 0); art_iter(&t, dump_iter, NULL); fail_unless((v = art_search(&t, (const unsigned char*)"foo", 3)) != NULL); diag("foo lookup yields %s", v); fail_unless(v && strcmp((char*)v, "foo") == 0); art_tree_destroy(&t); }
void test_art_insert_search_uuid(void) { art_tree t; art_leaf *l; int res = art_tree_init(&t); int len; char buf[512]; FILE *f = fopen("thirdparty/libart/tests/uuid.txt", "r"); uintptr_t line = 1; fail_unless(res == 0); while (fgets(buf, sizeof buf, f)) { len = (int)strlen(buf); buf[len - 1] = '\0'; if (art_insert(&t, (unsigned char *)buf, len, (void *)line)) { fail("art_insert didn't return NULL"); } line++; } // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { uintptr_t val; len = (int)strlen(buf); buf[len - 1] = '\0'; val = (uintptr_t)art_search(&t, (unsigned char *)buf, len); if (line != val) { fail("Line: %d Val: %" PRIuPTR " Str: %s\n", line, val, buf); } line++; } // Check the minimum l = art_minimum(&t); diag("minimum is %s", l->key); fail_unless( l && strcmp((char *)l->key, "00026bda-e0ea-4cda-8245-522764e9f325") == 0); // Check the maximum l = art_maximum(&t); diag("maximum is %s", l->key); fail_unless( l && strcmp((char *)l->key, "ffffcb46-a92e-4822-82af-a7190f9c1ec5") == 0); res = art_tree_destroy(&t); fail_unless(res == 0); }
void test_art_insert_search(void) { art_tree t; int res = art_tree_init(&t); int len; char buf[512]; FILE *f = fopen("thirdparty/libart/tests/words.txt", "r"); uintptr_t line = 1; art_leaf *l; fail_unless(res == 0); while (fgets(buf, sizeof buf, f)) { len = (int)strlen(buf); buf[len - 1] = '\0'; if (art_insert(&t, (unsigned char *)buf, len, (void *)line)) { fail("art_insert didn't return NULL"); } line++; } // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { len = (int)strlen(buf); buf[len - 1] = '\0'; { uintptr_t val = (uintptr_t)art_search(&t, (unsigned char *)buf, len); if (line != val) { fail("Line: %d Val: %" PRIuPTR " Str: %s", line, val, buf); } } line++; } // Check the minimum l = art_minimum(&t); fail_unless(l && strcmp((char *)l->key, "A") == 0); // Check the maximum l = art_maximum(&t); fail_unless(l && strcmp((char *)l->key, "zythum") == 0); res = art_tree_destroy(&t); fail_unless(res == 0); }
END_TEST START_TEST(test_art_insert_search) { art_tree t; int res = art_tree_init(&t); fail_unless(res == 0); int len; char buf[512]; FILE *f = fopen("tests/words.txt", "r"); uintptr_t line = 1; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; fail_unless(NULL == art_insert(&t, (unsigned char*)buf, len, (void*)line)); line++; } // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; uintptr_t val = (uintptr_t)art_search(&t, (unsigned char*)buf, len); fail_unless(line == val, "Line: %d Val: %" PRIuPTR " Str: %s\n", line, val, buf); line++; } // Check the minimum art_leaf *l = art_minimum(&t); fail_unless(l && strcmp((char*)l->key, "A") == 0); // Check the maximum l = art_maximum(&t); fail_unless(l && strcmp((char*)l->key, "zythum") == 0); res = art_tree_destroy(&t); fail_unless(res == 0); }
END_TEST START_TEST(test_art_insert_search_uuid) { art_tree t; int res = art_tree_init(&t); fail_unless(res == 0); int len; char buf[512]; FILE *f = fopen("tests/uuid.txt", "r"); uintptr_t line = 1; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; fail_unless(NULL == art_insert(&t, (unsigned char*)buf, len, (void*)line)); line++; } // Seek back to the start fseek(f, 0, SEEK_SET); // Search for each line line = 1; while (fgets(buf, sizeof buf, f)) { len = strlen(buf); buf[len-1] = '\0'; uintptr_t val = (uintptr_t)art_search(&t, (unsigned char*)buf, len); fail_unless(line == val, "Line: %d Val: %" PRIuPTR " Str: %s\n", line, val, buf); line++; } // Check the minimum art_leaf *l = art_minimum(&t); fail_unless(l && strcmp((char*)l->key, "00026bda-e0ea-4cda-8245-522764e9f325") == 0); // Check the maximum l = art_maximum(&t); fail_unless(l && strcmp((char*)l->key, "ffffcb46-a92e-4822-82af-a7190f9c1ec5") == 0); res = art_tree_destroy(&t); fail_unless(res == 0); }
static ERL_NIF_TERM elibart_search(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { art_tree* t; ErlNifBinary key; unsigned char buffer[BUFF_SIZE]; // 256K buffer unsigned char *key_copy = buffer; // extract arguments atr_tree, key if(argc != 2) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t)) return enif_make_badarg(env); if (!enif_inspect_binary(env, argv[1], &key)) return enif_make_badarg(env); // buffer size not enough, pay the price if (key.size > BUFF_SIZE) key_copy = malloc(key.size + 1); // TODO review -- is it possible not to copy the key just to add '\0'? memcpy(key_copy, key.data, key.size); key_copy[key.size] = '\0'; // search the art_tree for the given key art_elem_struct *value = art_search(t, key_copy, key.size + 1); // buffer size not enough, pay the price if (key.size > BUFF_SIZE) free(key_copy); // key does not exist in the art_tree if (!value) return mk_atom(env, "empty"); // key exixts, return the associated value ErlNifBinary res; enif_alloc_binary(value->size, &res); memcpy(res.data, value->data, value->size); return enif_make_tuple2(env, mk_atom(env, "ok"), enif_make_binary(env, &res)); }