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; } }
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; }
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")); }
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)); }
void test_remove_non_existent() { hash_map_remove(map, "not here"); TEST_ASSERT_EQUAL_UINT(0, hash_map_size(map)); }