Exemplo n.º 1
0
/* This function returns the key in the hash corresponding to the key, or NULL
 * if it is not in the hash. This function is useful when the key you supplied
 * is dynamically allocated and you don't have a pointer to it anywhere except
 * in the hash itself.
 * Arguments:
 * Key to look for.
 */
void * khash_get_key(khash *self, void *key) {
    int index = khash_locate_key(self, key);

    if (index == -1)
        return NULL;
    
    return self->cell_array[index].key;
}
Exemplo n.º 2
0
/* This function removes the key / value pair from the hash (if any).
 * Arguments:
 * Key to remove.
 */
void khash_remove(khash *self, void *key) {
    int index = khash_locate_key(self, key);
    int gap_position = index;
    int scanned_pos = index;
    
    /* Key is not present in the hash. */
    if(index == -1)
        return;
    
    /* We must ensure that other keys remain contiguous when we remove a key.
     * The situation where we need to move a key up is when the position of the
     * key given by key_func() is farther than the actual position of the key in
     * the hash, counting  from the position of the gap. Picture:
     *
     * The key wants to be here. (Distance between gap and pos wanted is far.)
     * A gap is here.            (So we move the key here.)
     * The key is here.          (Distance between gap and key is close.)
     *
     * In this situation, we don't move:
     * The gap is here.        
     * The key wants to be here. (Distance between gap and pos wanted is short.)
     * The key is here.          (Distance between gap and key is far.)
     *
     * If the gap position matches the wanted pos, we must move the key to fill
     * the gap.
     *
     * So here's the plan:
     * First we locate the key to remove. Removing it causes a gap. We start
     * scanning the keys coming next. If we meet a NULL, we're done. If we meet
     * a key, we check where it wants to be. If it wants to be before the gap,
     * we move it there. Then the gap is now at the position of the key we
     * moved, and we continue at the next position. Otherwise, we just continue 
     * with the next position.
     */
    while (1) {
    	int wanted_pos_dist;
	int key_dist;
	
        /* Scan the next position. */
        scanned_pos = (scanned_pos + 1) % self->alloc_size;

        /* We're done. Just set the gap to NULL. */
        if (self->cell_array[scanned_pos].key == NULL) {
            self->cell_array[gap_position].key = NULL;
            break;
    	}

        /* Calculate the distances. */
        wanted_pos_dist = khash_dist(gap_position,
	    	    	    	     self->key_func(self->cell_array[scanned_pos].key) % self->alloc_size,
				     self->alloc_size);
        key_dist = khash_dist(gap_position, scanned_pos, self->alloc_size);    

        /* Situations where we must move key (and value). */
        if (wanted_pos_dist > key_dist || wanted_pos_dist == 0) {
            self->cell_array[gap_position].key = self->cell_array[scanned_pos].key;
            self->cell_array[gap_position].value = self->cell_array[scanned_pos].value;
            gap_position = scanned_pos;
    	}
    }

    /* Decrement the usage count. */
    self->size--;
}
Exemplo n.º 3
0
Arquivo: khash.c Projeto: miraeye/f265
/* This function returns true if the key is in the hash.
 * Arguments:
 * Key to look for.
 */
int khash_exist(khash *self, void *key) {
    return (khash_locate_key(self, key) != -1);
}