/* * test_load_factor -- calculates the average load factor of the hash table * when inserting <0, 1M> elements in random order. * * The factor itself isn't really that important because the implementation * is optimized for lookup speed, but it should be reasonable. */ static void test_load_factor() { struct cuckoo *c = cuckoo_new(); UT_ASSERT(c != NULL); /* * The seed is intentionally constant so that the test result is * consistent (at least on the same platform). */ srand(INITIAL_SEED); float avg_load = 0.f; rand64(); int inserted = 0; for (int i = 0; ; ++i) { if (cuckoo_insert(c, rand64() % NVALUES, TEST_VALUE) == 0) { inserted++; avg_load += (float)inserted / cuckoo_get_size(c); if (inserted == NVALUES) break; } } avg_load /= inserted; UT_ASSERT(avg_load >= 0.4f); cuckoo_delete(c); }
/* * obj_fini -- cleanup of obj * * Called by destructor. */ void obj_fini(void) { LOG(3, NULL); cuckoo_delete(pools_ht); ctree_delete(pools_tree); }
void test_delete_basic(uint32_t policy, bool cas) { #define KEY "key" #define VAL "value" struct bstring key; struct val val; rstatus_i status; struct item *it; bool deleted; test_reset(policy, cas); key.data = KEY; key.len = sizeof(KEY) - 1; val.type = VAL_TYPE_STR; val.vstr.data = VAL; val.vstr.len = sizeof(VAL) - 1; time_update(); status = cuckoo_insert(&key, &val, UINT32_MAX - 1); ck_assert_msg(status == CC_OK, "cuckoo_insert not OK - return status %d", status); it = cuckoo_get(&key); ck_assert_msg(it != NULL, "cuckoo_get returned NULL"); deleted = cuckoo_delete(&key); ck_assert_msg(deleted, "cuckoo_delete return false"); it = cuckoo_get(&key); ck_assert_msg(it == NULL, "cuckoo_get returned not NULL"); deleted = cuckoo_delete(&key); ck_assert_msg(!deleted, "cuckoo_delete return true"); #undef KEY #undef VAL }
/* * alloc_class_collection_delete -- deletes the allocation class collection and * all of the classes within it */ void alloc_class_collection_delete(struct alloc_class_collection *ac) { for (size_t i = 0; i < MAX_ALLOCATION_CLASSES; ++i) { struct alloc_class *c = ac->aclasses[i]; if (c != NULL) { alloc_class_delete(ac, c); } } cuckoo_delete(ac->class_map_by_unit_size); Free(ac->class_map_by_alloc_size); Free(ac); }
/* * lane_info_destroy -- destroy lane info hash table */ inline void lane_info_destroy() { if (unlikely(Lane_info_ht == NULL)) return; cuckoo_delete(Lane_info_ht); struct lane_info *record; struct lane_info *head = Lane_info_records; while (head != NULL) { record = head; head = head->next; Free(record); } Lane_info_ht = NULL; Lane_info_records = NULL; Lane_info_cache = NULL; }
static void test_cuckoo_new_delete() { struct cuckoo *c = NULL; /* cuckoo malloc fail */ c = cuckoo_new(); UT_ASSERT(c == NULL); /* tab malloc fail */ c = cuckoo_new(); UT_ASSERT(c == NULL); /* all ok */ c = cuckoo_new(); UT_ASSERT(c != NULL); cuckoo_delete(c); }
static void test_insert_get_remove() { struct cuckoo *c = cuckoo_new(); ASSERT(c != NULL); for (int i = 0; i < TEST_INSERTS; ++i) ASSERT(cuckoo_insert(c, i, TEST_VAL(i)) == 0); for (int i = 0; i < TEST_INSERTS; ++i) ASSERT(cuckoo_get(c, i) == TEST_VAL(i)); for (int i = 0; i < TEST_INSERTS; ++i) ASSERT(cuckoo_remove(c, i) == TEST_VAL(i)); for (int i = 0; i < TEST_INSERTS; ++i) ASSERT(cuckoo_remove(c, i) == NULL); for (int i = 0; i < TEST_INSERTS; ++i) ASSERT(cuckoo_get(c, i) == NULL); cuckoo_delete(c); }
/* * obj_fini -- cleanup of obj * * Called by destructor. */ void obj_fini(void) { LOG(3, NULL); cuckoo_delete(pools); }
static int dtread_readline(const char *line, struct cuckoo_ctx *cu, unsigned int *maxid) { struct dtread_data *dr, *drp; struct dt_dentry *d; unsigned int pid, id, fid, items; unsigned long long size; const char *s; char *name; switch (line[0]) { case '0': if ((dr = dtread_data_alloc()) == NULL) return 0; if ((dr->de->id = atoi(&line[2])) == 0 ) { LOG_ERR("parsing failed for line %s\n", line); dtread_data_free(dr); return 0; } if (!cuckoo_insert(cu, dr->de->id, (void *) dr)) { LOG_ERR("cuckoo_insert() failed at line %s\n", line); dtread_data_free(dr); return 0; } if (dr->de->id > *maxid) *maxid = dr->de->id; break; case '1': s = strchr(line, ' '); if ((s == NULL) || (sscanf(++s, "%u", &pid) < 1 )) { LOG_ERR("parsing pid failed for line %s\n", line); return 0; } if (pid != 0) { drp = (struct dtread_data *) cuckoo_lookup(cu, pid); if (drp == NULL) { LOG_ERR("cuckoo_lookup() returned null for id %u line %s\n", pid, line); return 0; } } s = strchr(s, ' '); if ((s == NULL) || (sscanf(++s, "%u", &fid) < 1)) { LOG_ERR("Parsing fid failed for line %s\n", line); return 0; } s = strchr(s, ' '); if ((s == NULL) || (sscanf(++s, "%llu", &size) < 1)) { LOG_ERR("Parsing size failed for line %s\n", line); return 0; } s = strchr(s, ' '); if ((s == NULL) || (sscanf(++s, "%u", &id) < 1)) { LOG_ERR("Parsing id failed for line %s\n", line); return 0; } s = strchr(s, ' '); if ((s == NULL) || (sscanf(++s, "%u", &items) < 1)) { LOG_ERR("Parsing items failed for line %s\n", line); return 0; } s = strchr(s, ' '); if ((s == NULL) || ((name = strdup(++s))== NULL)) { LOG_ERR("Parsing name failed for line %s\n", line); return 0; } if (id == 0) { /* file */ LOG_ASSERT(pid != 0, "File with parent id=0 " "(only root dir has parent id=0). Line %s\n", line); if ((d = dt_alloc()) == NULL) { free(name); return 0; } d->type = DT_FILE; d->fid = fid; d->size = size; d->name = name; d->parent = drp->de; if (drp->file_child) drp->file_child->sibling = d; else drp->de->file_child = d; drp->file_child = d; } else { /* directory */ dr = (struct dtread_data *) cuckoo_lookup(cu, id); if (dr == NULL) { LOG_ERR("cuckoo_lookup() returned null for id %u\n", id); return 0; } d = dr->de; d->type = DT_DIR; d->fid = fid; d->size = size; d->name = name; d->items = items; if (pid != 0){ if (drp->child) drp->child->sibling = d; else drp->de->child = d; drp->child = d; d->parent = drp->de; cuckoo_delete(cu, id); free(dr); } } break; case '+': case '-': case '*': return 1; default: LOG_ERR("Unknown line format: %s\n", line); return 0; } return 1; }
struct dt_dentry * dtread_readfile(FILE *file, unsigned int *maxid, char *md5buf) { int c; char ch; struct buf_str *bs; struct cuckoo_ctx *cu; struct umd5_ctx md5; struct dtread_data *dr; struct dt_dentry *root = NULL; LOG_ASSERT(file != NULL, "Bad arguments\n"); if ((bs = buf_alloc()) == NULL) return NULL; if ((cu = cuckoo_alloc(0)) == NULL) goto clear_bs; umd5_init(&md5); while ((c = fgetc(file)) != EOF) { if (c == '\n') { if (buf_error(bs)) goto clear_cu; umd5_update(&md5, buf_string(bs), buf_strlen(bs)); umd5_update(&md5, "\n", 1); if (!dtread_readline(buf_string(bs), cu, maxid)) goto clear_cu; buf_clear(bs); } else { ch = c; buf_appendn(bs, &ch, 1); } } if (cuckoo_items(cu) != 1) { LOG_ERR("Some directories are left in cockoo tables\n"); goto clear_cu; } if ((dr = cuckoo_lookup(cu, 1)) == NULL) { LOG_ERR("No root node in cuckoo table\n"); goto clear_cu; } root = dr->de; cuckoo_delete(cu, 1); free(dr); umd5_finish(&md5); umd5_value(&md5, md5buf); clear_cu: cuckoo_rfree(cu, dtread_data_free); clear_bs: buf_free(bs); return root; }