static int clone_breakpoints(Process * proc, Process * orig_proc) { /* When copying breakpoints, we also have to copy the * referenced symbols, and link them properly. */ Dict * map = dict_init(&dict_key2hash_int, &dict_key_cmp_int); struct library_symbol * it = proc->list_of_symbols; proc->list_of_symbols = NULL; for (; it != NULL; it = it->next) { struct library_symbol * libsym = clone_library_symbol(it); if (libsym == NULL) { int save_errno; err: save_errno = errno; destroy_library_symbol_chain(proc->list_of_symbols); dict_clear(map); errno = save_errno; return -1; } libsym->next = proc->list_of_symbols; proc->list_of_symbols = libsym; if (dict_enter(map, it, libsym) != 0) goto err; } proc->breakpoints = dict_clone2(orig_proc->breakpoints, address_clone, breakpoint_clone, map); if (proc->breakpoints == NULL) goto err; dict_clear(map); return 0; }
/* Free dict. */ void dict_free(struct dict *dict) { if (dict != NULL) { dict_clear(dict); if (dict->table != NULL) free(dict->table); free(dict); } }
void dict_merge(dict_t *dest, dict_t *source) { dict_load_t load; dnode_t *leftnode = dict_first(dest), *rightnode = dict_first(source); assert (dict_similar(dest, source)); if (source == dest) return; #ifdef NO_FC_SOLVE dest->nodecount = 0; #endif load_begin_internal(&load, dest); for (;;) { if (leftnode != NULL && rightnode != NULL) { if (dest->compare(leftnode->key, rightnode->key, source->context) < 0) goto copyleft; else goto copyright; } else if (leftnode != NULL) { goto copyleft; } else if (rightnode != NULL) { goto copyright; } else { assert (leftnode == NULL && rightnode == NULL); break; } copyleft: { dnode_t *next = dict_next(dest, leftnode); #ifndef NDEBUG leftnode->left = NULL; /* suppress assertion in dict_load_next */ #endif dict_load_next(&load, leftnode, leftnode->key); leftnode = next; continue; } copyright: { dnode_t *next = dict_next(source, rightnode); #ifndef NDEBUG rightnode->left = NULL; #endif dict_load_next(&load, rightnode, rightnode->key); rightnode = next; continue; } } dict_clear(source); dict_load_end(&load); }
static void process_bare_destroy(struct Process *proc, int was_exec) { dict_clear(proc->breakpoints); if (!was_exec) { free(proc->filename); unlist_process(proc); destroy_unwind(proc); } }
/** * Test dict_clear(): * Pass non-dict object; expect TypeError * Pass empty dict; expect retval is OK * Pass empty dict; expect dict is not C_NULL * Pass empty dict; expect length is 0 * Pass non-empty dict; expect length is 0 */ void ut_dict_clear_000(CuTest *tc) { uint8_t heap[HEAP_SIZE]; pPmObj_t pobj = C_NULL; PmReturn_t retval; retval = pm_init(heap, HEAP_SIZE, MEMSPACE_RAM, C_NULL); retval = dict_new(&pobj); retval = dict_clear(PM_ONE); CuAssertTrue(tc, retval == PM_RET_EX_TYPE); retval = dict_clear(pobj); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertPtrNotNull(tc, pobj); CuAssertTrue(tc, ((pPmDict_t)pobj)->length == 0); retval = dict_setItem(pobj, PM_ZERO, PM_ONE); retval = dict_clear(pobj); CuAssertTrue(tc, retval == PM_RET_OK); CuAssertTrue(tc, ((pPmDict_t)pobj)->length == 0); }
void case_dict_clear() { struct dict *dict = dict(); assert(dict_set(dict, "key1", 4, "val1") == DICT_OK); assert(dict_set(dict, "key2", 4, "val2") == DICT_OK); assert(dict_set(dict, "key3", 4, "val3") == DICT_OK); assert(dict_set(dict, "key4", 4, "val4") == DICT_OK); assert(dict_len(dict) == 4); dict_clear(dict); assert(dict_len(dict) == 0); dict_free(dict); }
void breakpoints_init(Process *proc) { struct library_symbol *sym; debug(DEBUG_FUNCTION, "breakpoints_init(pid=%d)", proc->pid); if (proc->breakpoints) { /* let's remove that struct */ dict_apply_to_all(proc->breakpoints, free_bp_cb, NULL); dict_clear(proc->breakpoints); proc->breakpoints = NULL; } proc->breakpoints = dict_init(dict_key2hash_int, dict_key_cmp_int); if (options.libcalls && proc->filename) { /* FIXME: memory leak when called by exec(): */ proc->list_of_symbols = read_elf(proc); if (opt_e) { struct library_symbol **tmp1 = &(proc->list_of_symbols); while (*tmp1) { struct opt_e_t *tmp2 = opt_e; int keep = !opt_e_enable; while (tmp2) { if (!strcmp((*tmp1)->name, tmp2->name)) { keep = opt_e_enable; } tmp2 = tmp2->next; } if (!keep) { *tmp1 = (*tmp1)->next; } else { tmp1 = &((*tmp1)->next); } } } } else { proc->list_of_symbols = NULL; } for (sym = proc->list_of_symbols; sym; sym = sym->next) { /* proc->pid==0 delays enabling. */ insert_breakpoint(proc, sym2addr(proc, sym), sym); } proc->callstack_depth = 0; proc->breakpoints_enabled = -1; }
static void private_process_destroy(struct Process *proc, int was_exec) { /* Pop remaining stack elements. */ while (proc->callstack_depth > 0) { /* When this is called just before a process is * destroyed, the breakpoints should either have been * retracted by now, or were killed by exec. In any * case, it's safe to pretend that there are no * breakpoints associated with the stack elements, so * that stack_pop doesn't attempt to destroy them. */ size_t i = proc->callstack_depth - 1; if (!proc->callstack[i].is_syscall) proc->callstack[i].return_addr = 0; callstack_pop(proc); } if (!was_exec) free(proc->filename); /* Libraries and symbols. This is only relevant in * leader. */ struct library *lib; for (lib = proc->libraries; lib != NULL; ) { struct library *next = lib->next; library_destroy(lib); free(lib); lib = next; } proc->libraries = NULL; /* Breakpoints. */ if (proc->breakpoints != NULL) { proc_each_breakpoint(proc, NULL, destroy_breakpoint_cb, NULL); dict_clear(proc->breakpoints); proc->breakpoints = NULL; } destroy_unwind(proc); }
static void add_to_chain(char*cmd, dict_t*params, gfxfilterchain_t**chain, gfxfilterchain_t**next) { gfxfilterbase_t*f = 0; if(!strcmp(cmd, "maketransparent")) { char*alphastr = dict_lookup(params, "alpha"); int alpha = 255; if(alphastr) alpha=atoi(alphastr); f = malloc(sizeof(gfxfilter_t)); gfxfilter_maketransparent_init((gfxfilter_t*)f, alpha); } else if(!strcmp(cmd, "flatten")) { f = malloc(sizeof(gfxfilter_t)); gfxfilter_flatten_init((gfxfilter_t*)f); } else if(!strcmp(cmd, "rescale_images")) { f = malloc(sizeof(gfxfilter_t)); gfxfilter_rescale_images_init((gfxfilter_t*)f); } else if(!strcmp(cmd, "remove_font_transforms")) { f = malloc(sizeof(gfxtwopassfilter_t)); gfxtwopassfilter_remove_font_transforms_init((gfxtwopassfilter_t*)f); } else if(!strcmp(cmd, "remove_invisible_characters")) { f = malloc(sizeof(gfxtwopassfilter_t)); gfxtwopassfilter_remove_invisible_characters_init((gfxtwopassfilter_t*)f); } else if(!strcmp(cmd, "vectors_to_glyphs")) { f = malloc(sizeof(gfxtwopassfilter_t)); gfxtwopassfilter_vectors_to_glyphs_init((gfxtwopassfilter_t*)f); } else if(!strcmp(cmd, "one_big_font")) { f = malloc(sizeof(gfxtwopassfilter_t)); gfxtwopassfilter_one_big_font_init((gfxtwopassfilter_t*)f); } else { fprintf(stderr, "Unknown filter: %s\n", cmd); } dict_clear(params); gfxfilterchain_t*n = rfx_calloc(sizeof(gfxfilterchain_t)); if(!(*chain)) { (*chain) = (*next) = n; } else { (*next)->next = n; (*next) = n; } n->filter = f; }
static int process_bare_init(struct Process *proc, const char *filename, pid_t pid, int was_exec) { if (!was_exec) { memset(proc, 0, sizeof(*proc)); proc->filename = strdup(filename); if (proc->filename == NULL) { fail: free(proc->filename); if (proc->breakpoints != NULL) dict_clear(proc->breakpoints); return -1; } } /* Add process so that we know who the leader is. */ proc->pid = pid; add_process(proc, was_exec); if (proc->leader == NULL) goto fail; if (proc->leader == proc) { proc->breakpoints = dict_init(target_address_hash, target_address_cmp); if (proc->breakpoints == NULL) goto fail; } else { proc->breakpoints = NULL; } #if defined(HAVE_LIBUNWIND) proc->unwind_priv = _UPT_create(pid); proc->unwind_as = unw_create_addr_space(&_UPT_accessors, 0); #endif /* defined(HAVE_LIBUNWIND) */ return 0; }
/* 同步读取 master 发送的 db 数据 */ void repl_syncReadDB(eventloop* el, int fd, void *data, int mask){ clientContext *cc = (clientContext*)data; size_t nbytes; int off = 0; // 读取 master 传输的 db 数据 nbytes = recv(fd, cc->recvbuf+cc->bytesrecved, RECVBUF_LEN-cc->bytesrecved, 0); if (nbytes == -1){ if (errno==EAGAIN || errno==EINTR){ nbytes = 0; } else { xlog(LOG_DEBUG, "server recv: %s\n", "数据接收失败"); cc_freeClient(cc); goto werr; } } else if (nbytes == 0){ cc_freeClient(cc); goto werr; } // 设置接收到的字节数 cc->bytesrecved += nbytes; // 第一次获得传送 db 的大小 if (server.repl_dbsize == (uint32_t)-1){ if(cc->bytesrecved < sizeof(request_header)) return; net_getHeader(cc); off = sizeof(request_header); server.repl_dbsize = cc->reqheader.bodylen; server.repl_dbkvcount = cc->reqheader.kvcount; xlog(LOG_INFO, "db recv: 待同步 db 文件信息 kvcount=%d, dbsize=%d\n", server.repl_dbkvcount, server.repl_dbsize); memmove(cc->recvbuf, cc->recvbuf+sizeof(request_header), cc->bytesrecved-sizeof(request_header)); cc->bytesrecved -= sizeof(request_header); } // 计算需要写到 db 文件中的数据大小, 避免将非 db 中的数据写到db文件中 int nwrite = cc->bytesrecved<server.repl_dbsize?cc->bytesrecved:server.repl_dbsize; if (write(server.repl_transfer_fd, cc->recvbuf, nwrite) != nwrite){ xlog(LOG_WARN, "sync db; 同步写 db 文件错误 %s\n", strerror(errno)); cc_freeClient(cc); goto werr; } cc->bytesrecved -= nwrite; memmove(cc->recvbuf, cc->recvbuf+nwrite, cc->bytesrecved); server.repl_dbsize -= nwrite; if(server.repl_dbsize == 0){ // db 文件同步完成 if(rename(server.repl_transfer_tmpfile, server.dbfilename) < 0){ xlog(LOG_WARN, "rename dbfile: 重命名 db 文件错误 %s\n", strerror(errno)); cc_freeClient(cc); goto werr; } // empty dict dict_clear(server.db); multi_deleteFileEvent(server.el, cc->fd, MULTI_READABLE); // 加载 db 文件 if (db_load(server.dbfilename) < 0){ xlog(LOG_WARN, "db load: db 文件加载失败\n"); cc_freeClient(cc); goto werr; } sys_free(server.repl_transfer_tmpfile); close(server.repl_transfer_fd); server.master = cc; server.master->flag |= RWCACHED_MASTER; server.repl_state = REPL_CONNECTED; if (multi_createFileEvent(server.el, cc->fd, MULTI_READABLE, readDataFromClient, cc) < 0){ xlog(LOG_WARN, "add event: 创建同步读取事件失败\n"); goto werr; } xlog(LOG_INFO, "master <-->slave 建立同步成功\n"); } return; werr: multi_deleteFileEvent(server.el, server.repl_transfer_s, MULTI_READABLE); close(server.repl_transfer_s); close(server.repl_transfer_fd); unlink(server.repl_transfer_tmpfile); sys_free(server.repl_transfer_tmpfile); server.repl_state = REPL_CONNECT; return; }
int main(int argc, char **argv) { char buf[512], *p, *ptr, *ptr2; int rv; dict *dct; if (argc != 2) quit("usage: %s [type]", appname); srand((unsigned)time(NULL)); dict_malloc_func = xmalloc; ++argv; switch (argv[0][0]) { case 'h': dct = hb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'p': dct = pr_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'r': dct = rb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 't': dct = tr_dict_new((dict_compare_func)strcmp, NULL, key_val_free); break; case 's': dct = sp_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'w': dct = wb_dict_new((dict_compare_func)strcmp, key_val_free); break; case 'H': dct = hashtable_dict_new((dict_compare_func)strcmp, dict_str_hash, key_val_free, HSIZE); break; default: quit("type must be one of h, p, r, t, s, w, or H"); } if (!dct) quit("can't create container"); for (;;) { printf("> "); fflush(stdout); if (fgets(buf, sizeof(buf), stdin) == NULL) break; if ((p = strchr(buf, '\n')) != NULL) *p = 0; for (p = buf; isspace(*p); p++) /* void */; strcpy(buf, p); ptr2 = (ptr = strtok(buf, " ") ? strtok(NULL, " ") : NULL) ? strtok(NULL, " ") : NULL; if (*buf == 0) continue; if (strcmp(buf, "insert") == 0) { if (!ptr2) { printf("usage: insert <key> <data>\n"); continue; } void **datum_location; if (dict_insert(dct, xstrdup(ptr), &datum_location)) { *datum_location = xstrdup(ptr2); printf("inserted '%s': '%s'\n", ptr, *datum_location); } else { printf("key '%s' already in dict: '%s'\n", ptr, *datum_location); } } else if (strcmp(buf, "search") == 0) { if (ptr2) { printf("usage: search <key>\n"); continue; } ptr2 = dict_search(dct, ptr); if (ptr2) printf("found '%s': '%s'\n", ptr, ptr2); else printf("key '%s' not in dict!\n", ptr); } else if (strcmp(buf, "remove") == 0) { if (!ptr || ptr2) { printf("usage: remove <key>\n"); continue; } rv = dict_remove(dct, ptr); if (rv == 0) printf("removed '%s' from dict\n", ptr); else printf("key '%s' not in dict!\n", ptr); } else if (strcmp(buf, "show") == 0) { if (ptr) { printf("usage: show\n"); continue; } dict_itor *itor = dict_itor_new(dct); dict_itor_first(itor); for (; dict_itor_valid(itor); dict_itor_next(itor)) printf("'%s': '%s'\n", (char *)dict_itor_key(itor), (char *)dict_itor_data(itor)); dict_itor_free(itor); } else if (strcmp(buf, "reverse") == 0) { if (ptr) { printf("usage: reverse\n"); continue; } dict_itor *itor = dict_itor_new(dct); dict_itor_last(itor); for (; dict_itor_valid(itor); dict_itor_prev(itor)) printf("'%s': '%s'\n", (char *)dict_itor_key(itor), (char *)dict_itor_data(itor)); dict_itor_free(itor); } else if (strcmp(buf, "clear") == 0) { if (ptr) { printf("usage: clear\n"); continue; } dict_clear(dct); } else if (strcmp(buf, "count") == 0) { if (ptr) { printf("usage: count\n"); continue; } printf("count = %zu\n", dict_count(dct)); } else if (strcmp(buf, "quit") == 0) { break; } else { printf("Usage summary:\n"); printf(" insert <key> <data>\n"); printf(" search <key>\n"); printf(" remove <key>\n"); printf(" clear\n"); printf(" count\n"); printf(" show\n"); printf(" reverse\n"); printf(" quit\n"); } } dict_free(dct); exit(0); }
static void test_dict(void) { DictObject *mp = dict_cnew(10000, 0, 0, 0, 0, 0, 0, 0); //DictObject *mp = dict_new(); char keybuf[100]; size_t valuebuf[] = { 1 }; dict_add(mp, "a", valuebuf); dict_del(mp, "a"); dict_add(mp, "b", valuebuf); dict_del(mp, "b"); dict_add(mp, "c", valuebuf); dict_del(mp, "c"); dict_add(mp, "d", valuebuf); dict_del(mp, "d"); dict_add(mp, "e", valuebuf); dict_del(mp, "e"); dict_add(mp, "xffff", valuebuf); *valuebuf = 123456789; dict_set(mp, "test", valuebuf); DictObject *copy = dict_copy(mp); dict_print_by_value_desc(copy); fprintf(stdout, "===above is copy===\n"); dict_free(copy); *valuebuf = 1; size_t *vp; // while (fscanf(stdin, "%s", keybuf) == 1) { // vp = dict_get(mp, keybuf); // if (vp) // *vp += 1; // else // dict_add(mp, keybuf, valuebuf); // } // this is another faster version while (fscanf(stdin, "%s", keybuf) == 1) { vp = dict_fget(mp, keybuf); *vp += 1; } *valuebuf = 123456789; dict_set(mp, "the", valuebuf); *valuebuf = 145678999; dict_set(mp, "xxx", valuebuf); dict_del(mp, "xxx"); DictObject *mp2 = dict_new(); *valuebuf = 99999999; dict_set(mp2, "xiangnan", valuebuf); *valuebuf = 89999999; dict_add(mp2, "laoma", valuebuf); dict_update(mp, mp2); dict_free(mp2); //dict_print_by_value_desc(mp); dict_print(mp); void *key, *value; IterObject *dio = iter(mp); printf("\ntest iterw...\n"); while(iterw(dio, &key)) { value = dict_get(mp, key); fprintf(stdout, "%s\t%u\n", (char*)key, *(size_t*)value); } *valuebuf = 9888888; dict_set(mp, "emacs", valuebuf); iterf(dio); printf("\nnow test dict_iterkv...\n"); while(dict_iterkv(dio, &key, &value)) { fprintf(stdout, "%s\t%u\n", (char*)key, *(size_t*)value); } free(dio); dict_clear(mp); dict_clear(mp); //just for test dict_free(mp); }
/** * Deletes a dict object, and frees all associated memory. * * @param struct dict *dict * @return void **/ void dict_delete(struct dict *dict) { dict_clear(dict); free(dict->table); free(dict); }
void test_basic(dict *dct, const struct key_info *keys, const unsigned nkeys) { CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j <= i; ++j) CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), keys[j].value); for (unsigned j = i + 1; j < nkeys; ++j) CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), NULL); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert) { /* Verify that hashtable_resize works as expected. */ dict *clone = dict_clone(dct, NULL); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_TRUE(hashtable_resize(dict_private(clone), 3)); CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j < nkeys; ++j) CU_ASSERT_EQUAL(dict_search(clone, keys[j].key), keys[j].value); dict_free(clone); } if (dct->_vtable->clone) { dict *clone = dict_clone(dct, NULL); CU_ASSERT_PTR_NOT_NULL(clone); CU_ASSERT_TRUE(dict_verify(clone)); CU_ASSERT_EQUAL(dict_count(clone), nkeys); for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_EQUAL(dict_search(clone, keys[i].key), keys[i].value); } for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_TRUE(dict_remove(clone, keys[i].key)); } dict_free(clone); } for (unsigned i = 0; i < nkeys; ++i) CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].value); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_FALSE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_EQUAL(*datum_location, keys[i].value); CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); dict_itor *itor = dict_itor_new(dct); CU_ASSERT_PTR_NOT_NULL(itor); char *last_key = NULL; unsigned n = 0; for (dict_itor_first(itor); dict_itor_valid(itor); dict_itor_next(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); ++n; if (dct->_vtable->insert != (dict_insert_func)hashtable_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) < 0); } last_key = dict_itor_key(itor); } } CU_ASSERT_EQUAL(n, nkeys); last_key = NULL; n = 0; for (dict_itor_last(itor); dict_itor_valid(itor); dict_itor_prev(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); ++n; if (dct->_vtable->insert != (dict_insert_func)hashtable_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) > 0); } last_key = dict_itor_key(itor); } } CU_ASSERT_EQUAL(n, nkeys); dict_itor_free(itor); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_FALSE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].alt; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].alt); for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_EQUAL(dict_search(dct, keys[i].key), keys[i].alt); CU_ASSERT_TRUE(dict_remove(dct, keys[i].key)); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_EQUAL(dict_remove(dct, keys[i].key), false); for (unsigned j = 0; j <= i; ++j) { CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), NULL); } for (unsigned j = i + 1; j < nkeys; ++j) { CU_ASSERT_EQUAL(dict_search(dct, keys[j].key), keys[j].alt); } } for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_clear(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) { void **datum_location = NULL; CU_ASSERT_TRUE(dict_insert(dct, keys[i].key, &datum_location)); CU_ASSERT_PTR_NOT_NULL(datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_free(dct), nkeys); }
void test_basic(dict *dct, const struct key_info *keys, const unsigned nkeys, const struct closest_lookup_info *cl_infos, unsigned n_cl_infos) { dict_itor *itor = dict_itor_new(dct); CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j <= i; ++j) test_search(dct, itor, keys[j].key, keys[j].value); for (unsigned j = i + 1; j < nkeys; ++j) test_search(dct, itor, keys[j].key, NULL); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert || dct->_vtable->insert == (dict_insert_func)hashtable2_insert) { /* Verify that hashtable_resize works as expected. */ dict *clone = dict_clone(dct, NULL); CU_ASSERT_TRUE(dict_verify(dct)); if (dct->_vtable->insert == (dict_insert_func)hashtable_insert) { CU_ASSERT_TRUE(hashtable_resize(dict_private(clone), 3)); } else { CU_ASSERT_TRUE(hashtable2_resize(dict_private(clone), 3)); } CU_ASSERT_TRUE(dict_verify(dct)); for (unsigned j = 0; j < nkeys; ++j) test_search(clone, NULL, keys[j].key, keys[j].value); dict_free(clone); } if (dct->_vtable->clone) { dict *clone = dict_clone(dct, NULL); CU_ASSERT_PTR_NOT_NULL(clone); CU_ASSERT_TRUE(dict_verify(clone)); CU_ASSERT_EQUAL(dict_count(clone), nkeys); for (unsigned i = 0; i < nkeys; ++i) { test_search(clone, itor, keys[i].key, keys[i].value); } for (unsigned i = 0; i < nkeys; ++i) { CU_ASSERT_TRUE(dict_remove(clone, keys[i].key)); } dict_free(clone); } for (unsigned i = 0; i < nkeys; ++i) test_search(dct, itor, keys[i].key, keys[i].value); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_FALSE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_EQUAL(*datum_location, keys[i].value); CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_PTR_NOT_NULL(itor); char *last_key = NULL; unsigned n = 0; for (dict_itor_first(itor); dict_itor_valid(itor); dict_itor_next(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); CU_ASSERT_PTR_NOT_NULL(*dict_itor_data(itor)); char *key = dict_itor_key(itor); bool key_matched = false; for (unsigned i = 0; i < nkeys; ++i) { if (keys[i].key == key) { CU_ASSERT_EQUAL(*dict_itor_data(itor), keys[i].value); key_matched = true; break; } } CU_ASSERT_TRUE(key_matched); if (dct->_vtable->insert != (dict_insert_func)hashtable_insert && dct->_vtable->insert != (dict_insert_func)hashtable2_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) < 0); } last_key = dict_itor_key(itor); } ++n; } CU_ASSERT_EQUAL(n, nkeys); last_key = NULL; n = 0; for (dict_itor_last(itor); dict_itor_valid(itor); dict_itor_prev(itor)) { CU_ASSERT_PTR_NOT_NULL(dict_itor_key(itor)); CU_ASSERT_PTR_NOT_NULL(dict_itor_data(itor)); CU_ASSERT_PTR_NOT_NULL(*dict_itor_data(itor)); char *key = dict_itor_key(itor); bool key_matched = false; for (unsigned i = 0; i < nkeys; ++i) { if (keys[i].key == key) { CU_ASSERT_EQUAL(*dict_itor_data(itor), keys[i].value); key_matched = true; break; } } CU_ASSERT_TRUE(key_matched); if (dct->_vtable->insert != (dict_insert_func)hashtable_insert && dct->_vtable->insert != (dict_insert_func)hashtable2_insert) { if (last_key) { CU_ASSERT_TRUE(strcmp(last_key, dict_itor_key(itor)) > 0); } last_key = dict_itor_key(itor); } ++n; } CU_ASSERT_EQUAL(n, nkeys); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_FALSE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NOT_NULL(*datum_location); *datum_location = keys[i].alt; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) test_search(dct, itor, keys[i].key, keys[i].alt); for (unsigned i = 0; i < nkeys; ++i) { test_search(dct, itor, keys[i].key, keys[i].alt); CU_ASSERT_TRUE(dict_remove(dct, keys[i].key)); CU_ASSERT_TRUE(dict_verify(dct)); CU_ASSERT_EQUAL(dict_remove(dct, keys[i].key), false); for (unsigned j = 0; j <= i; ++j) { test_search(dct, itor, keys[j].key, NULL); } for (unsigned j = i + 1; j < nkeys; ++j) { test_search(dct, itor, keys[j].key, keys[j].alt); } } for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_clear(dct), nkeys); for (unsigned i = 0; i < nkeys; ++i) { bool inserted = false; void **datum_location = dict_insert(dct, keys[i].key, &inserted); CU_ASSERT_TRUE(inserted); CU_ASSERT_PTR_NOT_NULL(datum_location); CU_ASSERT_PTR_NULL(*datum_location); *datum_location = keys[i].value; CU_ASSERT_TRUE(dict_verify(dct)); } test_closest_lookup(dct, cl_infos, n_cl_infos); dict_itor_free(itor); CU_ASSERT_EQUAL(dict_count(dct), nkeys); CU_ASSERT_EQUAL(dict_free(dct), nkeys); }
void set_clear(set *s) { dict_clear(&s->set_dict); skip_list_clear(&s->set_list); }