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
);