예제 #1
0
static int wb_cache_bd_write_block(BD_t * object, bdesc_t * block, uint32_t number)
{
	struct cache_info * info = (struct cache_info *) object;
	uint32_t index;
	
	/* make sure it's a valid block */
	assert(block->ddesc->length && number + block->ddesc->length / object->blocksize <= object->numblocks);
	
	index = (uint32_t) hash_map_find_val(info->block_map, (void *) number);
	if(index)
	{
		/* already have this block */
		assert(info->blocks[index].block->ddesc == block->ddesc);
		wb_touch_block(info, index);
		
		return 0;
	}
	else
	{
		if(hash_map_size(info->block_map) == info->size)
			if(wb_evict_block(object, 0) < 0)
				/* no room in cache, and can't evict anything... */
				return -EBUSY;
		assert(hash_map_size(info->block_map) < info->size);
		
		index = wb_push_block(info, block, number);
		if(index == INVALID_BLOCK)
			return -ENOMEM;
		
		return 0;
	}
}
예제 #2
0
static bdesc_t * wb_cache_bd_read_block(BD_t * object, uint32_t number, uint16_t count, page_t * page)
{
	struct cache_info * info = (struct cache_info *) object;
	bdesc_t * block;
	uint32_t index;
	
	/* make sure it's a valid block */
	assert(count && number + count <= object->numblocks);
	
	index = (uint32_t) hash_map_find_val(info->block_map, (void *) number);
	if(index)
	{
		/* in the cache, use it */
		block = info->blocks[index].block;
		assert(block->ddesc->length == count * object->blocksize);
		wb_touch_block(info, index);
		if(!block->ddesc->synthetic)
			return block;
	}
	else
	{
		if(hash_map_size(info->block_map) == info->size)
			if(wb_evict_block(object, 0) < 0)
				/* no room in cache, and can't evict anything... */
				return NULL;
		assert(hash_map_size(info->block_map) < info->size);
	}
	
	/* not in the cache, need to read it */
	block = CALL(info->bd, read_block, number, count, page);
	if(!block)
		return NULL;
	
	if(block->ddesc->synthetic)
		block->ddesc->synthetic = 0;
	else if(wb_push_block(info, block, number) == INVALID_BLOCK)
		/* kind of a waste of the read... but we have to do it */
		return NULL;
	
	return block;
}
예제 #3
0
void test_clear() {
	hash_map_put(map, "key", "value");
	hash_map_put(map, "key2", "value2");
	hash_map_put(map, "key3", "value3");

	hash_map_clear(map);

	TEST_ASSERT_EQUAL_UINT(0, hash_map_size(map));

	TEST_ASSERT_NULL(hash_map_get(map, "key"));
	TEST_ASSERT_NULL(hash_map_get(map, "key2"));
	TEST_ASSERT_NULL(hash_map_get(map, "key3"));
}
예제 #4
0
void test_size() {
	TEST_ASSERT_EQUAL_UINT(0, hash_map_size(map));

	hash_map_put(map, "key", "value");
	TEST_ASSERT_EQUAL_UINT(1, hash_map_size(map));

	hash_map_put(map, "key2", "value");
	TEST_ASSERT_EQUAL_UINT(2, hash_map_size(map));

	// if the same key was updated, size should not change
	hash_map_put(map, "key", "value2");
	TEST_ASSERT_EQUAL_UINT(2, hash_map_size(map));

	// if hashs collide, size should still work
	hash_map_put(map, "1234567890", "9090");
	hash_map_put(map, "1234567809", "0909");
	TEST_ASSERT_EQUAL_UINT(4, hash_map_size(map));

	hash_map_remove(map, "key");
	hash_map_remove(map, "key2");
	hash_map_remove(map, "1234567890");
	hash_map_remove(map, "1234567809");
	TEST_ASSERT_EQUAL_UINT(0, hash_map_size(map));
}
예제 #5
0
void test_remove_non_existent() {
	hash_map_remove(map, "not here");
	TEST_ASSERT_EQUAL_UINT(0, hash_map_size(map));
}