1 /* Simple dictionary implementation using a linked list.
2 * FIXME: a skip list would be faster.
4 * Copyright 2005 Juan Lang
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
24 #include "dictionary.h"
26 struct dictionary_entry
30 struct dictionary_entry *next;
38 struct dictionary_entry *head;
41 struct dictionary *dictionary_create(comparefunc c, destroyfunc d, void *extra)
43 struct dictionary *ret;
47 ret = HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary));
58 void dictionary_destroy(struct dictionary *d)
62 struct dictionary_entry *p;
64 for (p = d->head; p; )
66 struct dictionary_entry *next = p->next;
69 d->destroy(p->key, p->value, d->extra);
70 HeapFree(GetProcessHeap(), 0, p);
73 HeapFree(GetProcessHeap(), 0, d);
77 /* Returns the address of the pointer to the node containing k. (It returns
78 * the address of either h->head or the address of the next member of the
79 * prior node. It's useful when you want to delete.)
80 * Assumes h and prev are not NULL.
82 static struct dictionary_entry **dictionary_find_internal(struct dictionary *d,
85 struct dictionary_entry **ret = NULL;
86 struct dictionary_entry *p;
89 /* special case for head containing the desired element */
90 if (d->head && d->comp(k, d->head->key, d->extra) == 0)
92 for (p = d->head; !ret && p && p->next; p = p->next)
94 if (d->comp(k, p->next->key, d->extra) == 0)
100 void dictionary_insert(struct dictionary *d, const void *k, const void *v)
102 struct dictionary_entry **prior;
106 if ((prior = dictionary_find_internal(d, k)))
109 d->destroy((*prior)->key, (*prior)->value, d->extra);
110 (*prior)->key = (void *)k;
111 (*prior)->value = (void *)v;
115 struct dictionary_entry *elem = (struct dictionary_entry *)
116 HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary_entry));
120 elem->key = (void *)k;
121 elem->value = (void *)v;
122 elem->next = d->head;
127 BOOL dictionary_find(struct dictionary *d, const void *k, void **value)
129 struct dictionary_entry **prior;
136 if ((prior = dictionary_find_internal(d, k)))
138 *value = (*prior)->value;
144 void dictionary_remove(struct dictionary *d, const void *k)
146 struct dictionary_entry **prior, *temp;
150 if ((prior = dictionary_find_internal(d, k)))
154 d->destroy((*prior)->key, (*prior)->value, d->extra);
155 *prior = (*prior)->next;
156 HeapFree(GetProcessHeap(), 0, temp);
160 void dictionary_enumerate(struct dictionary *d, enumeratefunc e)
162 struct dictionary_entry *p;
168 for (p = d->head; p; p = p->next)
169 e(p->key, p->value, d->extra);