/* Simple dictionary implementation using a linked list.
 * FIXME: a skip list would be faster.
 *
 * Copyright 2005 Juan Lang
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */
#include <assert.h>
#include <stdarg.h>
#include "windef.h"
#include "winbase.h"
#include "dictionary.h"
#include "wine/debug.h"

WINE_DEFAULT_DEBUG_CHANNEL(storage);

struct dictionary_entry
{
    void *key;
    void *value;
    struct dictionary_entry *next;
};

struct dictionary
{
    comparefunc comp;
    destroyfunc destroy;
    void *extra;
    struct dictionary_entry *head;
    UINT num_entries;
};

struct dictionary *dictionary_create(comparefunc c, destroyfunc d, void *extra)
{
    struct dictionary *ret;

    TRACE("(%p, %p, %p)\n", c, d, extra);
    if (!c)
        return NULL;
    ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary));
    if (ret)
    {
        ret->comp = c;
        ret->destroy = d;
        ret->extra = extra;
        ret->head = NULL;
        ret->num_entries = 0;
    }
    TRACE("returning %p\n", ret);
    return ret;
}

void dictionary_destroy(struct dictionary *d)
{
    TRACE("(%p)\n", d);
    if (d)
    {
        struct dictionary_entry *p;

        for (p = d->head; p; )
        {
            struct dictionary_entry *next = p->next;

            if (d->destroy)
                d->destroy(p->key, p->value, d->extra);
            HeapFree(GetProcessHeap(), 0, p);
            p = next;
        }
        HeapFree(GetProcessHeap(), 0, d);
    }
}

UINT dictionary_num_entries(struct dictionary *d)
{
    return d ? d->num_entries : 0;
}

/* Returns the address of the pointer to the node containing k.  (It returns
 * the address of either h->head or the address of the next member of the
 * prior node.  It's useful when you want to delete.)
 * Assumes h and prev are not NULL.
 */
static struct dictionary_entry **dictionary_find_internal(struct dictionary *d,
 const void *k)
{
    struct dictionary_entry **ret = NULL;
    struct dictionary_entry *p;

    assert(d);
    /* special case for head containing the desired element */
    if (d->head && d->comp(k, d->head->key, d->extra) == 0)
        ret = &d->head;
    for (p = d->head; !ret && p && p->next; p = p->next)
    {
        if (d->comp(k, p->next->key, d->extra) == 0)
            ret = &p->next;
    }
    return ret;
}

void dictionary_insert(struct dictionary *d, const void *k, const void *v)
{
    struct dictionary_entry **prior;

    TRACE("(%p, %p, %p)\n", d, k, v);
    if (!d)
        return;
    if ((prior = dictionary_find_internal(d, k)))
    {
        if (d->destroy)
            d->destroy((*prior)->key, (*prior)->value, d->extra);
        (*prior)->key = (void *)k;
        (*prior)->value = (void *)v;
    }
    else
    {
        struct dictionary_entry *elem = (struct dictionary_entry *)
         HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary_entry));

        if (!elem)
            return;
        elem->key = (void *)k;
        elem->value = (void *)v;
        elem->next = d->head;
        d->head = elem;
        d->num_entries++;
    }
}

BOOL dictionary_find(struct dictionary *d, const void *k, void **value)
{
    struct dictionary_entry **prior;
    BOOL ret = FALSE;

    TRACE("(%p, %p, %p)\n", d, k, value);
    if (!d)
        return FALSE;
    if (!value)
        return FALSE;
    if ((prior = dictionary_find_internal(d, k)))
    {
        *value = (*prior)->value;
        ret = TRUE;
    }
    TRACE("returning %d (%p)\n", ret, *value);
    return ret;
}

void dictionary_remove(struct dictionary *d, const void *k)
{
    struct dictionary_entry **prior, *temp;

    TRACE("(%p, %p)\n", d, k);
    if (!d)
        return;
    if ((prior = dictionary_find_internal(d, k)))
    {
        temp = *prior;
        if (d->destroy)
            d->destroy((*prior)->key, (*prior)->value, d->extra);
        *prior = (*prior)->next;
        HeapFree(GetProcessHeap(), 0, temp);
        d->num_entries--;
    }
}

void dictionary_enumerate(struct dictionary *d, enumeratefunc e, void *closure)
{
    struct dictionary_entry *p;

    TRACE("(%p, %p, %p)\n", d, e, closure);
    if (!d)
        return;
    if (!e)
        return;
    for (p = d->head; p; p = p->next)
        if (!e(p->key, p->value, d->extra, closure))
            break;
}
