Esempio n. 1
0
static void bucket_erase_existed( bucket_t *bucket, const hashmap_key_t key, unsigned int * const existed )
{
	entry_t *prev;
	entry_t *iter;

	assert( NULL != bucket );
	assert( NULL != key );
	assert( NULL != existed );

	iter = bucket_find_entry( bucket, key, &prev );

	if( NULL != iter )
	{
		if( NULL == prev )
		{
			bucket->entries = iter->next;
		}
		else
		{
			prev->next = iter->next;
		}

		entry_destroy( iter );

		--bucket->stats.num_entries;
		*existed = 1;
	}
	else
	{
		*existed = 0;
	}
}
Esempio n. 2
0
void lruhash_remove(struct lruhash *table, hashvalue_t hash, void *key)
{
    struct lruhash_entry *entry;
    struct lruhash_bucket *bucket;
    void *d;

    lock_basic_lock(&table->lock);
    bucket = &table->array[hash & table->size_mask];
    if((entry=bucket_find_entry(table, bucket, hash, key))) {
        bucket_overflow_remove(bucket, entry);
        lru_remove(table, entry);
    } else {
        lock_basic_unlock(&table->lock);
        return;
    }

    table->num--;
    lock_basic_lock(&entry->lock);
    table->space_used -= (*table->sizefunc)(entry->key, entry->data);
    lock_basic_unlock(&entry->lock);
    lock_basic_unlock(&table->lock);

    //del key data
    d = entry->data;
    (*table->delkeyfunc)(entry->key);
    (*table->deldatafunc)(d);
}
Esempio n. 3
0
struct lruhash_entry *lruhash_lookup(struct lruhash *table,
    hashvalue_t hash, void *key)
{
    struct lruhash_entry *entry;
    struct lruhash_bucket *bucket;

    lock_basic_lock(&table->lock);
    bucket = &table->array[hash & table->size_mask];
    if((entry=bucket_find_entry(table, bucket, hash, key))) {
        lru_touch(table, entry);
        lock_basic_lock(&entry->lock);
    }
    lock_basic_unlock(&table->lock);
    return entry;
}
Esempio n. 4
0
void lruhash_insert(struct lruhash *table, hashvalue_t hash,
    struct lruhash_entry *entry, void *data)
{
    struct lruhash_bucket *bucket;
    struct lruhash_entry *found, *reclaimlist=NULL;
    size_t need_size;
    need_size = table->sizefunc(entry->key, data);

    //find bucket
    lock_basic_lock(&table->lock);
    bucket = &table->array[hash & table->size_mask];

    //see if entry exists
    if(!(found=bucket_find_entry(table, bucket, hash, entry->key))) {
        //if not found: add to bucket
        entry->overflow_next = bucket->overflow_list;
        bucket->overflow_list = entry;
        lru_front(table, entry);
        table->num++;
        table->space_used += need_size;
    } else {
        //if found: update data
        table->space_used += need_size -
            (*table->sizefunc)(found->key, found->data);
        (*table->delkeyfunc)(entry->key);
        lru_touch(table, found);
        lock_basic_lock(&found->lock);
        (*table->deldatafunc)(found->data);
        found->data = data;
        lock_basic_unlock(&found->lock);
    }
    if(table->space_used > table->space_max)
        reclaim_space(table, &reclaimlist);
    if(table->num >= table->size)
        table_grow(table);
    lock_basic_unlock(&table->lock);

    //del reclaim without lock
    while(reclaimlist) {
        struct lruhash_entry *n = reclaimlist->overflow_next;
        void *d = reclaimlist->data;
        (*table->delkeyfunc)(reclaimlist->key);
        (*table->deldatafunc)(d);
        reclaimlist = n;
    }
}
Esempio n. 5
0
static unsigned int bucket_find( bucket_t *bucket, hashmap_key_t key, hashmap_value_t * const value )
{
	unsigned int found = 0;
	entry_t *entry = bucket_find_entry( bucket, key, NULL );

	if( NULL != entry )
	{
		found = 1;

		if( NULL != value )
		{
			*value = entry->value;
		}
	}

	return found;
}
Esempio n. 6
0
static int bucket_insert_existed( bucket_t *bucket, const hashmap_key_t key, const hashmap_value_t value, unsigned int * const existed )
{
	entry_t *entry;
	int err = 0;

	assert( NULL != bucket );
	assert( NULL != key );
	assert( NULL != existed );

	entry = bucket_find_entry( bucket, key, NULL );
	if( NULL != entry )
	{
		/* Key exists in this bucket, update the value. */
		entry->value = value;
		*existed = 1;
	}
	else
	{
		/* Key doesn't exist in this bucket, add it. */
		entry_t *new_entry = entry_create( key, value );

		if( NULL != new_entry )
		{
			new_entry->next = bucket->entries;
			bucket->entries = new_entry;

			++bucket->stats.num_entries;
			*existed = 0;
		}
		else
		{
			err = -1;
		}
	}

	return err;
}
Esempio n. 7
0
//test bucket_find_entry and bucket_overflow_remove
static void test_bucket_find_entry(struct lruhash *table)
{
    testkey *k1 = newkey(12);
    testkey *k2 = newkey(12 + 1024);
    testkey *k3 = newkey(14);
    testkey *k4 = newkey(12 + 1024*2);
    hashvalue_t h = simplehash(12);
    struct lruhash_bucket bucket;
    memset(&bucket, 0, sizeof(bucket));

    //remove from empty list
    bucket_overflow_remove(&bucket, &k1->entry);

    //find in empty list
    unit_assert(bucket_find_entry(table, &bucket, h, k1) == NULL);

    //insert
    bucket.overflow_list = &k1->entry;
    unit_assert(bucket_find_entry(table, &bucket, simplehash(13), k1) == NULL);
    unit_assert(k1->entry.hash == k2->entry.hash);
    unit_assert(bucket_find_entry(table, &bucket, h, k2) == NULL);
    unit_assert(bucket_find_entry(table, &bucket, h, k1) == &k1->entry);

    //remove
    bucket_overflow_remove(&bucket, &k1->entry);
    unit_assert(bucket_find_entry(table, &bucket, h, k1) == NULL);

    //insert multi
    unit_assert(k1->entry.hash == k4->entry.hash);
    k4->entry.overflow_next = &k1->entry;
    k3->entry.overflow_next = &k4->entry;
    bucket.overflow_list = &k3->entry;
    unit_assert(bucket_find_entry(table, &bucket, simplehash(13), k1) == NULL);
    unit_assert(k1->entry.hash == k2->entry.hash);
    unit_assert(bucket_find_entry(table, &bucket, h, k2) == NULL);
    unit_assert(bucket_find_entry(table, &bucket, h, k1) == &k1->entry);

    //remove mid
    unit_assert(bucket_find_entry(table, &bucket, k4->entry.hash, k4) == &k4->entry);
    bucket_overflow_remove(&bucket, &k4->entry);
    unit_assert(bucket_find_entry(table, &bucket, k4->entry.hash, k4) == NULL);

    //remove last
    bucket_overflow_remove(&bucket, &k1->entry);
    unit_assert(bucket_find_entry(table, &bucket, h, k1) == NULL);

    delkey(k1);
    delkey(k2);
    delkey(k3);
    delkey(k4);
}