Listing 2

/** array_add. Adds a new element to the array, or replaces
 * an element with another one having the same key
 **/
void array_add (PARRAY array, void *key, long key_length, 
                    void *value, ARRAY_DESTROY_FUNCTION destroy_function)
{
    unsigned long   hash;
    PELEMENT        el, new_el;
    el = array_find_element (array, key, key_length);
    if (el)
    {
        // Replace existing value with new one
        free (el->value);
        el->value = value;
    }
    else
    {
        hash = sdbm_hash (key, key_length);
        el = malloc (sizeof (ELEMENT));
        memset (el, 0, sizeof (ELEMENT));
        CHECK_MEM_FAIL (el);

        el->key = malloc (key_length);
        CHECK_MEM_FAIL (el->key);

        memcpy (el->key, key, key_length);

        el->key_length = key_length;

        el->value = value;

        el->hash_next = array->elements[hash % ARRAY_BUCKET_SIZE];

        if (el->hash_next)
            el->hash_next->hash_prev = el;
        array->elements[hash % ARRAY_BUCKET_SIZE] = el;
        el->hash = hash;
        el->prev = array->last;
        if (el->prev)
            el->prev->next = el;
        el->destroy_function = destroy_function;
        array->last = el;
        array->count++;
        if (!array->first)
            array->first = el;
    }
}