99574a4d78862e7aac699911a45f64e85425647a
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 #define WIN32_NO_STATUS
25 //#include "winbase.h"
26 #include "dictionary.h"
27 #include <wine/debug.h>
29 WINE_DEFAULT_DEBUG_CHANNEL(storage
);
31 struct dictionary_entry
35 struct dictionary_entry
*next
;
43 struct dictionary_entry
*head
;
47 struct dictionary
*dictionary_create(comparefunc c
, destroyfunc d
, void *extra
)
49 struct dictionary
*ret
;
51 TRACE("(%p, %p, %p)\n", c
, d
, extra
);
54 ret
= HeapAlloc(GetProcessHeap(), 0, sizeof(struct dictionary
));
63 TRACE("returning %p\n", ret
);
67 void dictionary_destroy(struct dictionary
*d
)
72 struct dictionary_entry
*p
;
74 for (p
= d
->head
; p
; )
76 struct dictionary_entry
*next
= p
->next
;
79 d
->destroy(p
->key
, p
->value
, d
->extra
);
80 HeapFree(GetProcessHeap(), 0, p
);
83 HeapFree(GetProcessHeap(), 0, d
);
87 UINT
dictionary_num_entries(struct dictionary
*d
)
89 return d
? d
->num_entries
: 0;
92 /* Returns the address of the pointer to the node containing k. (It returns
93 * the address of either h->head or the address of the next member of the
94 * prior node. It's useful when you want to delete.)
95 * Assumes h and prev are not NULL.
97 static struct dictionary_entry
**dictionary_find_internal(struct dictionary
*d
,
100 struct dictionary_entry
**ret
= NULL
;
101 struct dictionary_entry
*p
;
104 /* special case for head containing the desired element */
105 if (d
->head
&& d
->comp(k
, d
->head
->key
, d
->extra
) == 0)
107 for (p
= d
->head
; !ret
&& p
&& p
->next
; p
= p
->next
)
109 if (d
->comp(k
, p
->next
->key
, d
->extra
) == 0)
115 void dictionary_insert(struct dictionary
*d
, const void *k
, const void *v
)
117 struct dictionary_entry
**prior
;
119 TRACE("(%p, %p, %p)\n", d
, k
, v
);
122 if ((prior
= dictionary_find_internal(d
, k
)))
125 d
->destroy((*prior
)->key
, (*prior
)->value
, d
->extra
);
126 (*prior
)->key
= (void *)k
;
127 (*prior
)->value
= (void *)v
;
131 struct dictionary_entry
*elem
= HeapAlloc(GetProcessHeap(), 0,
132 sizeof(struct dictionary_entry
));
136 elem
->key
= (void *)k
;
137 elem
->value
= (void *)v
;
138 elem
->next
= d
->head
;
144 BOOL
dictionary_find(struct dictionary
*d
, const void *k
, void **value
)
146 struct dictionary_entry
**prior
;
149 TRACE("(%p, %p, %p)\n", d
, k
, value
);
154 if ((prior
= dictionary_find_internal(d
, k
)))
156 *value
= (*prior
)->value
;
159 TRACE("returning %d (%p)\n", ret
, *value
);
163 void dictionary_remove(struct dictionary
*d
, const void *k
)
165 struct dictionary_entry
**prior
, *temp
;
167 TRACE("(%p, %p)\n", d
, k
);
170 if ((prior
= dictionary_find_internal(d
, k
)))
174 d
->destroy((*prior
)->key
, (*prior
)->value
, d
->extra
);
175 *prior
= (*prior
)->next
;
176 HeapFree(GetProcessHeap(), 0, temp
);
181 void dictionary_enumerate(struct dictionary
*d
, enumeratefunc e
, void *closure
)
183 struct dictionary_entry
*p
;
185 TRACE("(%p, %p, %p)\n", d
, e
, closure
);
190 for (p
= d
->head
; p
; p
= p
->next
)
191 if (!e(p
->key
, p
->value
, d
->extra
, closure
))