Beispiel #1
0
bool
hashtable_remove(hashtable_t *table, void *key)
{
    bool res = false;
    hash_entry_t *e, *prev_e;
    uint hindex = hash_key(table, key);
    if (table->synch)
        dr_mutex_lock(table->lock);
    for (e = table->table[hindex], prev_e = NULL; e != NULL; prev_e = e, e = e->next) {
        if (keys_equal(table, e->key, key)) {
            if (prev_e == NULL)
                table->table[hindex] = e->next;
            else
                prev_e->next = e->next;
            if (table->str_dup)
                hash_free(e->key, strlen((const char *)e->key) + 1);
            if (table->free_payload_func != NULL)
                (table->free_payload_func)(e->payload);
            hash_free(e, sizeof(*e));
            res = true;
            table->entries--;
            break;
        }
    }
    if (table->synch)
        dr_mutex_unlock(table->lock);
    return res;
}
Beispiel #2
0
bool
hashtable_add(hashtable_t *table, void *key, void *payload)
{
    uint hindex = hash_key(table, key);
    hash_entry_t *e;
    /* if payload is null can't tell from lookup miss */
    ASSERT(payload != NULL, "hashtable_add internal error");
    if (table->synch)
        dr_mutex_lock(table->lock);
    for (e = table->table[hindex]; e != NULL; e = e->next) {
        if (keys_equal(table, e->key, key)) {
            /* we have a use where payload != existing entry so we don't assert on that */
            if (table->synch)
                dr_mutex_unlock(table->lock);
            return false;
        }
    }
    e = (hash_entry_t *) hash_alloc(sizeof(*e));
    if (table->str_dup) {
        const char *s = (const char *) key;
        e->key = hash_alloc(strlen(s)+1);
        strncpy((char *)e->key, s, strlen(s)+1);
    } else
        e->key = key;
    e->payload = payload;
    e->next = table->table[hindex];
    table->table[hindex] = e;
    table->entries++;
    hashtable_check_for_resize(table);
    if (table->synch)
        dr_mutex_unlock(table->lock);
    return true;
}
Beispiel #3
0
static rc_t loop_until_key_found( struct lookup_reader * reader, uint64_t key_to_find,
        uint64_t *key_found , uint64_t *offset )
{
    rc_t rc = 0;
    bool done = false;
    uint64_t curr = *offset;
    while ( !done && rc == 0 )
    {
        size_t found_len;
        rc = read_key_and_len( reader, curr, key_found, &found_len );
        if ( keys_equal( key_to_find, *key_found ) )
        {
            done = true;
            *offset = curr;
        }
        else if ( key_to_find > *key_found )
            curr += found_len;
        else
        {
            done = true;
            rc = SILENT_RC( rcVDB, rcNoTarg, rcReading, rcId, rcNotFound );
        }
    }
    return rc;
}
Beispiel #4
0
static rc_t indexed_seek( struct lookup_reader * reader, uint64_t key_to_find, uint64_t * key_found, bool exactly )
{
    /* we have a index! find set pos to the found offset */
    uint64_t offset = 0;
    uint64_t max_key;
    rc_t rc = get_max_key( reader->index, &max_key );
    if ( rc == 0 )
    {
        if ( key_to_find > max_key )
            rc = RC( rcVDB, rcNoTarg, rcReading, rcId, rcTooBig );
        else
        {
            rc = get_nearest_offset( reader->index, key_to_find, key_found, &offset ); /* in index.c */
            if ( rc == 0 )
            {
                if ( keys_equal( key_to_find, *key_found ) )
                    reader->pos = offset;
                else
                {
                    if ( exactly )
                    {
                        rc = loop_until_key_found( reader, key_to_find, key_found, &offset );
                        if ( rc == 0 )
                        {
                            if ( keys_equal( key_to_find, *key_found ) )
                                reader->pos = offset;
                            else
                                rc = RC( rcVDB, rcNoTarg, rcReading, rcId, rcNotFound );
                        }
                        else
                            rc = RC( rcVDB, rcNoTarg, rcReading, rcId, rcNotFound );
                    }
                    else
                    {
                        reader->pos = offset;
                        rc = RC( rcVDB, rcNoTarg, rcReading, rcId, rcNotFound );
                    }
                }
            }
        }
    }
    return rc;
}
Beispiel #5
0
static struct dm_bio_prison_cell *__search_bucket(struct hlist_head *bucket,
						  struct dm_cell_key *key)
{
	struct dm_bio_prison_cell *cell;

	hlist_for_each_entry(cell, bucket, list)
		if (keys_equal(&cell->key, key))
			return cell;

	return NULL;
}
Beispiel #6
0
static rc_t full_table_seek( struct lookup_reader * reader, uint64_t key_to_find, uint64_t * key_found )
{
    /* we have no index! search the whole thing... */
    uint64_t offset = 0;
    rc_t rc = loop_until_key_found( reader, key_to_find, key_found, &offset );
    if ( rc == 0 )
    {
        if ( keys_equal( key_to_find, *key_found ) )
            reader->pos = offset;
        else
        {
            rc = RC( rcVDB, rcNoTarg, rcReading, rcId, rcNotFound );
            ErrMsg( "seek_lookup_reader( key: %ld ) -> %R", key_to_find, rc );
        }
    }
    return rc;
}
Beispiel #7
0
/* Lookup an entry by key and return a pointer to the corresponding entry 
 * Returns NULL if no such entry exists */
void *
hashtable_lookup(hashtable_t *table, void *key)
{
    void *res = NULL;
    hash_entry_t *e;
    uint hindex = hash_key(table, key);
    if (table->synch)
        dr_mutex_lock(table->lock);
    for (e = table->table[hindex]; e != NULL; e = e->next) {
        if (keys_equal(table, e->key, key)) {
            res = e->payload;
            break;
        }
    }
    if (table->synch)
        dr_mutex_unlock(table->lock);
    return res;
}
Beispiel #8
0
void *
hashtable_add_replace(hashtable_t *table, void *key, void *payload)
{
    void *old_payload = NULL;
    uint hindex = hash_key(table, key);
    hash_entry_t *e, *new_e, *prev_e;
    /* if payload is null can't tell from lookup miss */
    ASSERT(payload != NULL, "hashtable_add_replace internal error");
    new_e = (hash_entry_t *) hash_alloc(sizeof(*new_e));
    if (table->str_dup) {
        const char *s = (const char *) key;
        new_e->key = hash_alloc(strlen(s)+1);
        strncpy((char *)new_e->key, s, strlen(s)+1);
    } else
        new_e->key = key;
    new_e->payload = payload;
    if (table->synch)
        dr_mutex_lock(table->lock);
    for (e = table->table[hindex], prev_e = NULL; e != NULL; prev_e = e, e = e->next) {
        if (keys_equal(table, e->key, key)) {
            if (prev_e == NULL)
                table->table[hindex] = new_e;
            else
                prev_e->next = new_e;
            new_e->next = e->next;
            if (table->str_dup)
                hash_free(e->key, strlen((const char *)e->key) + 1);
            /* up to caller to free payload */
            old_payload = e->payload;
            hash_free(e, sizeof(*e));
            break;
        }
    }
    if (old_payload == NULL) {
        new_e->next = table->table[hindex];
        table->table[hindex] = new_e;
        table->entries++;
        hashtable_check_for_resize(table);
    }
    if (table->synch)
        dr_mutex_unlock(table->lock);
    return old_payload;
}