/** * Allocates space for and returns a linked * list of all the filters. * @arg mgr The manager to list from * @arg prefix The prefix to list or NULL * @arg head Output, sets to the address of the list header * @return 0 on success. */ int filtmgr_list_filters(bloom_filtmgr *mgr, char *prefix, bloom_filter_list_head **head) { // Allocate the head bloom_filter_list_head *h = *head = calloc(1, sizeof(bloom_filter_list_head)); // Iterate through a callback to append int prefix_len = 0; if (prefix) { prefix_len = strlen(prefix); art_iter_prefix(mgr->filter_map, (unsigned char*)prefix, prefix_len, filter_map_list_cb, h); } else art_iter(mgr->filter_map, filter_map_list_cb, h); // Joy... we have to potentially handle the delta updates if (mgr->primary_vsn == mgr->vsn) return 0; filter_list *current = mgr->delta; bloom_filter_wrapper *f; while (current) { // Check if this is a match (potential prefix) if (current->type == CREATE) { f = current->filter; if (!prefix_len || !strncmp(f->filter->filter_name, prefix, prefix_len)) { f = current->filter; filter_map_list_cb(h, (unsigned char*)f->filter->filter_name, 0, f); } } // Don't seek past what the primary map incorporates if (current->vsn == mgr->primary_vsn + 1) break; current = current->next; } return 0; }
/** * Allocates space for and returns a linked * list of all the sets. * @arg mgr The manager to list from * @arg prefix The prefix to match on or NULL * @arg head Output, sets to the address of the list header * @return 0 on success. */ int setmgr_list_sets(hlld_setmgr *mgr, char *prefix, hlld_set_list_head **head) { // Allocate the head hlld_set_list_head *h = *head = calloc(1, sizeof(hlld_set_list_head)); // Check if we should use the prefix int prefix_len = 0; if (prefix) { prefix_len = strlen(prefix); art_iter_prefix(mgr->set_map, prefix, prefix_len, set_map_list_cb, h); } else art_iter(mgr->set_map, set_map_list_cb, h); // Joy... we have to potentially handle the delta updates if (mgr->primary_vsn == mgr->vsn) return 0; set_list *current = mgr->delta; hlld_set_wrapper *s; while (current) { // Check if this is a match (potential prefix) if (current->type == CREATE) { s = current->set; if (!prefix_len || !strncmp(s->set->set_name, prefix, prefix_len)) { s = current->set; set_map_list_cb(h, s->set->set_name, 0, s); } } // Don't seek past what the primary set map incorporates if (current->vsn == mgr->primary_vsn + 1) break; current = current->next; } return 0; }
void test_art_insert_iter(void) { art_tree t; int res = art_tree_init(&t); int len; char buf[512]; FILE *f = fopen("thirdparty/libart/tests/words.txt", "r"); uint64_t xor_mask = 0; 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"); } xor_mask ^= (line * (buf[0] + len)); line++; } nlines = line - 1; { uint64_t out[] = {0, 0}; fail_unless(art_iter(&t, iter_cb, &out) == 0); fail_unless(out[0] == nlines); fail_unless(out[1] == xor_mask); } res = art_tree_destroy(&t); fail_unless(res == 0); }
/** * Allocates space for and returns a linked * list of all the cold filters. This has the side effect * of clearing the list of cold filters! * @arg mgr The manager to list from * @arg head Output, sets to the address of the list header * @return 0 on success. */ int filtmgr_list_cold_filters(bloom_filtmgr *mgr, bloom_filter_list_head **head) { // Allocate the head of a new hashmap bloom_filter_list_head *h = *head = calloc(1, sizeof(bloom_filter_list_head)); // Scan for the cold filters. Ignore deltas, since they are either // new (e.g. hot), or being deleted anyways. art_iter(mgr->filter_map, filter_map_list_cold_cb, h); return 0; }
/** * Allocates space for and returns a linked * list of all the cold sets. This has the side effect * of clearing the list of cold sets! * @arg mgr The manager to list from * @arg head Output, sets to the address of the list header * @return 0 on success. */ int setmgr_list_cold_sets(hlld_setmgr *mgr, hlld_set_list_head **head) { // Allocate the head of a new hashmap hlld_set_list_head *h = *head = calloc(1, sizeof(hlld_set_list_head)); // Scan for the cold sets. Ignore deltas, since they are either // new (e.g. hot), or being deleted anyways. art_iter(mgr->set_map, set_map_list_cold_cb, h); return 0; }
static ERL_NIF_TERM elibart_destroy(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { art_tree *t; if (argc != 1) return enif_make_badarg(env); if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t)) return enif_make_badarg(env); art_iter(t, delete_cb, NULL); if (destroy_art_tree((art_tree*) argv[0]) != 0) return mk_error(env, "destroy_art_tree"); return mk_atom(env, "ok"); }
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); }
/** * Cleanup * @arg mgr The manager to destroy * @return 0 on success. */ int destroy_filter_manager(bloom_filtmgr *mgr) { // Stop the vacuum thread mgr->should_run = 0; if (mgr->vacuum_thread) pthread_join(mgr->vacuum_thread, NULL); // Nuke all the keys in the current version. art_iter(mgr->filter_map, filter_map_delete_cb, mgr); // Handle any delta operations filter_list *next, *current = mgr->delta; while (current) { // Only delete pending creates, pending // deletes are still in the primary tree if (current->type == CREATE) delete_filter(current->filter); next = current->next; free(current); current = next; } // Free the clients filtmgr_client *cl_next, *cl = mgr->clients; while (cl) { cl_next = cl->next; free(cl); cl = cl_next; } // Destroy the ART trees destroy_art_tree(mgr->filter_map); destroy_art_tree(mgr->alt_filter_map); free((mgr->filter_map < mgr->alt_filter_map) ? mgr->filter_map : mgr->alt_filter_map); // Free the manager free(mgr); return 0; }
int main(int argc, char *argv[]) { if (initialize_context(&my_context, argc, argv) != 0) { usage(argv[0]); return 1; } if (art_tree_map_init(&myds, &my_context) != 0) { fprintf(stderr, "failed to initialize memory pool file\n"); return 1; } if (my_context.pop == NULL) { perror("pool initialization"); return 1; } if (art_tree_init(my_context.pop, &my_context.newpool)) { perror("pool setup"); return 1; } if ((my_context.mode & FILL)) { if (add_elements(&my_context)) { perror("add elements"); return 1; } } if ((my_context.mode & INSERT)) { if (insert_element(&my_context)) { perror("insert elements"); return 1; } } if ((my_context.mode & SEARCH)) { if (search_element(&my_context)) { perror("search elements"); return 1; } } if ((my_context.mode & REMOVE)) { if (delete_element(&my_context)) { perror("delete elements"); return 1; } } if (my_context.mode & DUMP) { art_iter(my_context.pop, dump_art_leaf_callback, NULL); } if (my_context.mode & GRAPH) { printf("digraph g {\nrankdir=LR;\n"); art_iter(my_context.pop, dump_art_node_callback, NULL); printf("}"); } exit_handler(&my_context); return 0; }