struct snapraid_disk* disk_alloc(const char* name, const char* dir, uint64_t dev, int skip) { struct snapraid_disk* disk; disk = malloc_nofail(sizeof(struct snapraid_disk)); pathcpy(disk->name, sizeof(disk->name), name); pathimport(disk->dir, sizeof(disk->dir), dir); /* ensure that the dir terminate with "/" if it isn't empty */ pathslash(disk->dir, sizeof(disk->dir)); disk->smartctl[0] = 0; disk->device = dev; disk->tick = 0; disk->total_blocks = 0; disk->free_blocks = 0; disk->first_free_block = 0; disk->has_volatile_inodes = 0; disk->has_unreliable_physical = 0; disk->has_different_uuid = 0; disk->has_unsupported_uuid = 0; disk->had_empty_uuid = 0; disk->mapping_idx = -1; disk->skip_access = skip; tommy_list_init(&disk->filelist); tommy_list_init(&disk->deletedlist); tommy_hashdyn_init(&disk->inodeset); tommy_hashdyn_init(&disk->pathset); tommy_hashdyn_init(&disk->stampset); tommy_list_init(&disk->linklist); tommy_hashdyn_init(&disk->linkset); tommy_list_init(&disk->dirlist); tommy_hashdyn_init(&disk->dirset); tommy_tree_init(&disk->fs_parity, chunk_parity_compare); tommy_tree_init(&disk->fs_file, chunk_file_compare); disk->fs_last = 0; return disk; }
phash_pool pcore_hash_init(const puint8 type) { plog_dbg("%s(): Инициализация пула типа %d", __PRETTY_FUNCTION__, type); phash_pool pool = pmalloc_check(__PRETTY_FUNCTION__, sizeof(struct s_phash_pool)); if (!pool) { return NULL; } pool->type = type; tommy_list *list = pmalloc_check(__PRETTY_FUNCTION__, sizeof(tommy_list)); if (!list) { free(pool); return NULL; } void *hash_struct; switch (type) { case PHASH_FAST_SEARCH: hash_struct = pmalloc_check(__PRETTY_FUNCTION__, sizeof(tommy_hashdyn)); if (!hash_struct) { free(pool); free(list); return NULL; } tommy_hashdyn_init(hash_struct); break; case PHASH_FAST_INSERT: default: hash_struct = pmalloc_check(__PRETTY_FUNCTION__, sizeof(tommy_hashtable)); if (!hash_struct) { free(pool); free(list); return NULL; } tommy_hashtable_init(hash_struct, 1024); break; } tommy_list_init(list); pool->list = list; pool->hash_struct = hash_struct; plog_dbg("%s(): Пул 0x%08X успешно создан", __PRETTY_FUNCTION__, pool); return pool; }
void _init_entry_index_hashmap() { tommy_hashdyn_init(&entry_hash); }
static void test_tommy(void) { tommy_array array; tommy_arrayblk arrayblk; tommy_arrayblkof arrayblkof; tommy_hashdyn hashdyn; tommy_hashdyn_node node[TOMMY_SIZE]; unsigned i; tommy_array_init(&array); tommy_arrayblk_init(&arrayblk); tommy_arrayblkof_init(&arrayblkof, sizeof(unsigned)); for(i=0;i<TOMMY_SIZE;++i) { tommy_array_insert(&array, &node[i]); tommy_arrayblk_insert(&arrayblk, &node[i]); tommy_arrayblkof_grow(&arrayblkof, i + 1); *(unsigned*)tommy_arrayblkof_ref(&arrayblkof, i) = i; } if (tommy_array_memory_usage(&array) < TOMMY_SIZE * sizeof(void*)) goto bail; if (tommy_arrayblk_memory_usage(&arrayblk) < TOMMY_SIZE * sizeof(void*)) goto bail; if (tommy_arrayblkof_memory_usage(&arrayblkof) < TOMMY_SIZE * sizeof(unsigned)) goto bail; for(i=0;i<TOMMY_SIZE;++i) { if (tommy_array_get(&array, i) != &node[i]) goto bail; if (tommy_arrayblk_get(&arrayblk, i) != &node[i]) goto bail; if (*(unsigned*)tommy_arrayblkof_ref(&arrayblkof, i) != i) goto bail; } tommy_arrayblkof_done(&arrayblkof); tommy_arrayblk_done(&arrayblk); tommy_array_done(&array); tommy_hashdyn_init(&hashdyn); for(i=0;i<TOMMY_SIZE;++i) tommy_hashdyn_insert(&hashdyn, &node[i], &node[i], i % 64); if (tommy_hashdyn_count(&hashdyn) != TOMMY_SIZE) goto bail; if (tommy_hashdyn_memory_usage(&hashdyn) < TOMMY_SIZE * sizeof(void*)) goto bail; for(i=0;i<TOMMY_SIZE/2;++i) tommy_hashdyn_remove_existing(&hashdyn, &node[i]); for(i=0;i<TOMMY_SIZE/2;++i) if (tommy_hashdyn_remove(&hashdyn, tommy_test_search, &node[i], i % 64) != 0) goto bail; for(i=TOMMY_SIZE/2;i<TOMMY_SIZE;++i) if (tommy_hashdyn_remove(&hashdyn, tommy_test_search, &node[i], i % 64) == 0) goto bail; if (tommy_hashdyn_count(&hashdyn) != 0) goto bail; tommy_hashdyn_done(&hashdyn); return; bail: /* LCOV_EXCL_START */ fprintf(stderr, "Failed tommy test\n"); exit(EXIT_FAILURE); /* LCOV_EXCL_STOP */ }
void test_hashdyn(void) { tommy_list list; tommy_hashdyn hashdyn; struct object_hash* HASH; unsigned i, n; tommy_node* p; unsigned limit; unsigned count; HASH = malloc(MAX * sizeof(struct object_hash)); for(i=0;i<MAX;++i) { HASH[i].value = i; } START("hashdyn stack"); limit = 10 * sqrt(MAX); for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashdyn_init(&hashdyn); /* insert */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashdyn_insert(&hashdyn, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashdyn_foreach_arg(&hashdyn, count_arg, &count); if (count != n) abort(); /* remove */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashdyn_remove_existing(&hashdyn, &obj->hashnode); } tommy_hashdyn_done(&hashdyn); } STOP(); START("hashdyn queue"); limit = sqrt(MAX) / 8; for(n=0;n<limit;++n) { tommy_list_init(&list); tommy_hashdyn_init(&hashdyn); /* insert first run */ for(i=0;i<n;++i) { tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashdyn_insert(&hashdyn, &HASH[i].hashnode, &HASH[i], HASH[i].value); } count = 0; tommy_hashdyn_foreach_arg(&hashdyn, count_arg, &count); if (count != n) abort(); /* insert all the others */ for(;i<MAX;++i) { struct object_hash* obj; /* insert one */ tommy_list_insert_head(&list, &HASH[i].node, &HASH[i]); tommy_hashdyn_insert(&hashdyn, &HASH[i].hashnode, &HASH[i], HASH[i].value); /* remove one */ p = tommy_list_head(&list); obj = p->data; tommy_list_remove_existing(&list, p); tommy_hashdyn_remove_existing(&hashdyn, &obj->hashnode); } /* remove remaining */ p = tommy_list_head(&list); while (p) { struct object_hash* obj = p->data; p = p->next; tommy_hashdyn_remove_existing(&hashdyn, &obj->hashnode); } tommy_hashdyn_done(&hashdyn); } STOP(); }