示例#1
0
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;
}
示例#2
0
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;
}
示例#3
0
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);
}
示例#4
0
/**
 * 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;
}
示例#5
0
/**
 * 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;
}