Esempio n. 1
0
/**
 * hashmap_put:
 * puts key/value pair into hashmap if any bucket available
 * NOTE: overwrites any bucket with same key
 */
int hashmap_put(hashmap_ptr map, const any_key_t* key, const any_value_t* value) {
    if (map) {
        int index;
        hashmap_map* _map = (hashmap_map*) map;

        /* find a suitable bucket, if any */
        index = hashmap_hash(_map, key);
        while (HASHMAP_FULL == index) {
            int status = hashmap_rehash(_map);
            if (HASHMAP_OK == status) {
                index = hashmap_hash(_map, key);
            } else {
                return HASHMAP_FULL;
            }
        }

        /* fill the bucket */
        _map->_buckets[index]._key = (any_key_t*) key;
        _map->_buckets[index]._value = (any_value_t*) value;
        _map->_buckets[index]._in_use = 1;
        _map->_cur_size++;
        _map->_changed = 1;

        return HASHMAP_OK;
    }
    return HASHMAP_ERR;
}
Esempio n. 2
0
void mget_hashmap_sethashfunc(mget_hashmap_t *h, unsigned int (*hash)(const void *key))
{
	if (h) {
		h->hash = hash;

		hashmap_rehash(h, h->max, 1);
	}
}
Esempio n. 3
0
/**
 * Put a key into the hashmap or test for membership. The
 * destination bucket is decided by modding the hash by
 * the number of bucket slots available. This gives us up
 * to 4 billion buckets maximum.
 * @param map the hashmap to add to
 * @param key the key to put in there
 * @param value at the key
 * @param replace if 1 then replace any value already in the bucket
 * @return 1 if it was added, 0 otherwise (already there)
 */
int hashmap_put( hashmap *map, char *key, void *value )
{
	unsigned hashval,slot;
    struct bucket *d;
    if ( (float)map->num_keys/(float)map->num_buckets > MAX_RATIO )
	{
		if ( !hashmap_rehash(map) )
            return 0;
	}
    hashval = hash( key, strlen(key) );
	slot = hashval % map->num_buckets;
    d = bucket_create( key, value );
    if ( d != NULL )
    {
        if ( map->buckets[slot] == NULL )
        {
            map->num_keys++;
            map->buckets[slot] = d;
        }
        else 
        {
            struct bucket *prev = NULL;
            struct bucket *c = map->buckets[slot];
            do
            {
                if (strcmp(c->key,key)==0 )
                {
                    // key already present: replace
                    if ( prev != NULL )
                        prev->next = d;
                    else
                        map->buckets[slot] = d;
                    d->next = c->next;
                    free( c->key );
                    free( c );
                    break;
                }
                else if ( c->next == NULL )
                {
                    c->next = d;
                    map->num_keys++;
                    break;
                }
                prev = c;
                c = c->next;
            } while ( c != NULL );
        }
        return 1;
    }
    else
        return 0;
}
Esempio n. 4
0
static inline void G_GNUC_MGET_NONNULL((1,3)) hashmap_new_entry(mget_hashmap_t *h, unsigned int hash, const char *key, const char *value)
{
	ENTRY *entry;
	int pos = hash % h->max;

	entry = malloc(sizeof(ENTRY));
	entry->key = (void *)key;
	entry->value = (void *)value;
	entry->hash = hash;
	entry->next = h->entry[pos];
	h->entry[pos] = entry;

	if (++h->cur >= h->threshold) {
		if (h->off > 0) {
			hashmap_rehash(h, h->max + h->off, 0);
		} else if (h->off<-1) {
			hashmap_rehash(h, h->max * -h->off, 0);
		} else {
			// no resizing occurs
		}
	}
}
Esempio n. 5
0
/* Insert a data, key pair into our hashmap */
void hashmap_put(hashmap *h, void *data, void *key, const size_t len)
{
    /* Rehash and resize hashmap if load factor > 0.75 */
    if (h->bucket_count * 3 / 4 <= h->size)
        hashmap_rehash(h);

    /* Create a hnode to insert into bucket */
    hnode *n = malloc(sizeof(hnode));
    n->data = data;
    n->key  = key;
    n->len  = len;
    n->hash = hashmap_hashfn(key, len);
    n->next = NULL;

    /* Calculate the index we need to insert into */
    size_t index = n->hash % h->bucket_count;
    hnode *cur = h->buckets[index];

    /* If there exist some values in this bucket already, traverse it */
    if (cur != NULL) {
        /* Check for head of list being the same first */
        if (hashmap_keycmp(cur->key, cur->len, key, len)) {
            cur->data = n->data;
            free(n);
        }
        /* Else it may exist elewhere in this chain */
        else {
            /* Loop until we match keys */
            while (cur->next != NULL 
                    && hashmap_keycmp(cur->next->key, cur->next->len, key, len))
                cur = cur->next;

            /* We found a matching key, so replace data */
            if (cur->next) {
                cur->next->data = n->data;
                free(n);
            }
            /* End of chain, so put n as new value in this chain */
            else {
                cur->next = n;
                h->size++;
            }
        }
    }
    /* We do not have a value for this bucket so insert straight on */
    else {
        h->buckets[index] = n;
        h->size++;
    }
}
Esempio n. 6
0
//Add a pointer to the hashmap with some key
int hashmap_insert(hashmap_t hashmap, int key, hashmap_item_t value)
{
	int index = hashmap_hash(hashmap, key);

	while(index == -1)
	{
		if (hashmap_rehash(hashmap) == -1) 
			return -1;
		index = hashmap_hash(hashmap, key);
	}

	hashmap->data[index]->data = value;
	hashmap->data[index]->key = key;
	hashmap->data[index]->in_use = 1;
	hashmap->size++; 

	return 0;
}
Esempio n. 7
0
/*
 * Add a pointer to the hashmap with some key
 */
int hashmap_put(map_t in, char* key, any_t value){
	int index;
	hashmap_map* m;

	/* Cast the hashmap */
	m = (hashmap_map *) in;

	/* Find a place to put our value */
	index = hashmap_hash(in, key);
	while(index == MAP_FULL){
		if (hashmap_rehash(in) == MAP_OMEM) {
			return MAP_OMEM;
		}
		index = hashmap_hash(in, key);
	}

	/* Set the data */
        m->data[index].data = value;
	m->data[index].key = key;
	m->data[index].in_use = 1;
	m->size++; 

	return MAP_OK;
}