void prf_register_cmd(const char* name, pfn_ajax_cmd callback_fn) { struct prf_cmd_desc* c = (struct prf_cmd_desc*)arr_add(&g_prf.cmds); ASSERT(c); c->name = name; c->hash = hash_murmur32(name, strlen(name), HSEED); c->cmd_fn = callback_fn; }
pfn_ajax_cmd prf_find_cmd(const char* name) { uint hash = hash_murmur32(name, strlen(name), HSEED); struct prf_cmd_desc* cmds = (struct prf_cmd_desc*)g_prf.cmds.buffer; for (uint i = 0, cnt = g_prf.cmds.item_cnt; i < cnt; i++) { if (cmds[i].hash == hash) return cmds[i].cmd_fn; } return NULL; }
void test_freelist() { const uint item_cnt = 100000; const uint max_size = item_cnt * 1024; void** ptrs = (void**)ALLOC(item_cnt*sizeof(void*), 0); uint* h = (uint*)ALLOC(item_cnt*sizeof(uint), 0); size_t* sizes = (size_t*)ALLOC(item_cnt*sizeof(size_t), 0); uint free_cnt = 0; struct freelist_alloc freelist; struct allocator alloc; mem_freelist_create(mem_heap(), &freelist, max_size, 0); mem_freelist_bindalloc(&freelist, &alloc); uint64 t1 = timer_querytick(); log_printf(LOG_TEXT, "allocating %d items from freelist (with hash validation)...", item_cnt); for (uint i = 0; i < item_cnt; i++) { int s = rand_geti(8, 1024); ASSERT(s <= 1024); ptrs[i] = A_ALLOC(&alloc, s, 6); ASSERT(ptrs[i]); if (i > 0 && rand_flipcoin(50)) { uint idx_tofree = rand_geti(0, i-1); if (ptrs[idx_tofree] != NULL) { A_FREE(&alloc, ptrs[idx_tofree]); ptrs[idx_tofree] = NULL; } } // random fill the buffer memset(ptrs[i], 0x00, s); h[i] = hash_murmur32(ptrs[i], s, 100); sizes[i] = s; } // check if the remaining buffers are untouched for (uint i = 0; i < item_cnt; i++) { if (ptrs[i] != NULL) { #if defined(_DEBUG_) uint hh = hash_murmur32(ptrs[i], sizes[i], 100); ASSERT(h[i] == hh); #endif } } for (uint i = 0; i < item_cnt; i++) { //if (rand_flipcoin(50)) { if (ptrs[i] != NULL) { A_FREE(&alloc, ptrs[i]); free_cnt ++; ptrs[i] = NULL; } //} } /* report leaks */ uint leaks_cnt = mem_freelist_getleaks(&freelist, NULL); if (leaks_cnt > 0) log_printf(LOG_TEXT, "%d leaks found", leaks_cnt); mem_freelist_destroy(&freelist); log_print(LOG_TEXT, "done."); log_printf(LOG_TEXT, "took %f ms.", timer_calctm(t1, timer_querytick())*1000.0f); FREE(ptrs); FREE(h); FREE(sizes); }
/** * Verifies that we can read all of the data out of the storage tank correctly. * * @param check_collection The collection of sums to verify. * @return Returns true only if all of the objects in the linked list match the expected hash value. */ bool_t check_tokyo_tank_verify(inx_t *check_collection) { stringer_t *data; check_tank_obj_t *obj; inx_cursor_t *cursor; if (!(cursor = inx_cursor_alloc(check_collection))) { return false; } while (status() && (obj = inx_cursor_value_next(cursor))) { if (!(data = tank_load(TANK_CHECK_DATA_HNUM, obj->tnum, TANK_CHECK_DATA_UNUM, obj->onum))) { log_info("%lu - tank_get error", obj->onum); inx_cursor_free(cursor); return false; } if (obj->adler32 != hash_adler32(st_data_get(data), st_length_get(data))) { log_info("%lu - adler32 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } if (obj->fletcher32 != hash_fletcher32(st_data_get(data), st_length_get(data))) { log_info("%lu - fletcher32 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } if (obj->crc32 != hash_crc32(st_data_get(data), st_length_get(data))) { log_info("%lu - crc32 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } if (obj->crc64 != hash_crc64(st_data_get(data), st_length_get(data))) { log_info("%lu - crc64 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } if (obj->murmur32 != hash_murmur32(st_data_get(data), st_length_get(data))) { log_info("%lu - murmur32 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } if (obj->murmur64 != hash_murmur64(st_data_get(data), st_length_get(data))) { log_info("%lu - murmur64 error", obj->onum); inx_cursor_free(cursor); st_free(data); return false; } st_free(data); } inx_cursor_free(cursor); return true; }
/** * Recursively loads the files from a directory and stores them using the tank interface. * * @param location The directory path to search for files. * @return Returns false if an error occurs, otherwise true. */ bool_t check_tokyo_tank_load(char *location, inx_t *check_collection, check_tank_opt_t *opts) { int fd; multi_t key; DIR *working; struct stat info; check_tank_obj_t *obj; struct dirent *entry; char file[1024], *buffer; if (!(working = opendir(location))) { log_info("Unable to open the data path. {location = %s}", location); return false; } while (status() && (entry = readdir(working))) { // Reset. errno = 0; bzero(file, 1024); bzero(&info, sizeof(struct stat)); // Build an absolute path. snprintf(file, 1024, "%s%s%s", location, "/", entry->d_name); // If we hit a directory, recursively call the load function. if (entry->d_type == DT_DIR && *(entry->d_name) != '.') { if (!check_tokyo_tank_load(file, check_collection, opts)) { return false; } } // Otherwise if its a regular file try storing it. else if (entry->d_type == DT_REG && *(entry->d_name) != '.') { // Read the file. if ((fd = open(file, O_RDONLY)) < 0) { log_info("%s - open error", file); closedir(working); return false; } // How big is the file? if (fstat(fd, &info) != 0) { log_info("%s - stat error", file); closedir(working); close(fd); return false; } // Allocate a buffer. if (!(buffer = mm_alloc(info.st_size + 1))) { log_info("%s - malloc error", file); closedir(working); close(fd); return false; } // Clear the buffer. memset(buffer, 0, info.st_size + 1); // Read the file. if (read(fd, buffer, info.st_size) != info.st_size) { log_info("%s - read error", file); closedir(working); mm_free(buffer); close(fd); return false; } close(fd); // Data used for verification. if (!(obj = mm_alloc(sizeof(check_tank_obj_t)))) { log_info("check_tank allocation failed for the file %s", file); closedir(working); mm_free(buffer); return false; } obj->adler32 = hash_adler32(buffer, info.st_size); obj->fletcher32 = hash_fletcher32(buffer, info.st_size); obj->crc32 = hash_crc32(buffer, info.st_size); obj->crc64 = hash_crc64(buffer, info.st_size); obj->murmur32 = hash_murmur32(buffer, info.st_size); obj->murmur64 = hash_murmur64(buffer, info.st_size); // Request the next storage tank. obj->tnum = tank_cycle(); // Try storing the file data. if (!(obj->onum = tank_store(TANK_CHECK_DATA_HNUM, obj->tnum, TANK_CHECK_DATA_UNUM, PLACER(buffer, info.st_size), opts->engine))) { log_info("tank_store failed for the file %s", file); closedir(working); mm_free(buffer); mm_free(obj); return false; } mm_free(buffer); key = mt_set_type(key, M_TYPE_UINT64); key.val.u64 = obj->onum; if (!inx_insert(check_collection, key, obj)) { log_info("inx_insert failed for the file %s", file); closedir(working); mm_free(obj); return false; } } } closedir(working); return true; }