4 This file is part of polypaudio.
6 polypaudio is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published
8 by the Free Software Foundation; either version 2 of the License,
9 or (at your option) any later version.
11 polypaudio is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with polypaudio; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
33 struct hashmap_entry {
34 struct hashmap_entry *next, *previous, *bucket_next, *bucket_previous;
42 struct hashmap_entry **data;
43 struct hashmap_entry *first_entry;
46 unsigned (*hash_func) (const void *p);
47 int (*compare_func) (const void*a, const void*b);
50 struct pa_hashmap *pa_hashmap_new(unsigned (*hash_func) (const void *p), int (*compare_func) (const void*a, const void*b)) {
52 h = malloc(sizeof(struct pa_hashmap));
54 h->data = malloc(sizeof(struct hashmap_entry*)*(h->size = 1023));
56 memset(h->data, 0, sizeof(struct hashmap_entry*)*(h->size = 1023));
57 h->first_entry = NULL;
59 h->hash_func = hash_func ? hash_func : pa_idxset_trivial_hash_func;
60 h->compare_func = compare_func ? compare_func : pa_idxset_trivial_compare_func;
64 static void remove(struct pa_hashmap *h, struct hashmap_entry *e) {
68 e->next->previous = e->previous;
70 e->previous->next = e->next;
72 h->first_entry = e->next;
75 e->bucket_next->bucket_previous = e->bucket_previous;
76 if (e->bucket_previous)
77 e->bucket_previous->bucket_next = e->bucket_next;
79 h->data[e->hash] = e->bucket_next;
85 void pa_hashmap_free(struct pa_hashmap*h, void (*free_func)(void *p, void *userdata), void *userdata) {
88 while (h->first_entry) {
90 free_func(h->first_entry->value, userdata);
91 remove(h, h->first_entry);
98 static struct hashmap_entry *get(struct pa_hashmap *h, unsigned hash, const void *key) {
99 struct hashmap_entry *e;
101 for (e = h->data[hash]; e; e = e->bucket_next)
102 if (h->compare_func(e->key, key) == 0)
108 int pa_hashmap_put(struct pa_hashmap *h, const void *key, void *value) {
109 struct hashmap_entry *e;
113 hash = h->hash_func(key) % h->size;
115 if ((e = get(h, hash, key)))
118 e = malloc(sizeof(struct hashmap_entry));
126 e->next = h->first_entry;
128 h->first_entry->previous = e;
131 e->bucket_previous = NULL;
132 e->bucket_next = h->data[hash];
134 h->data[hash]->bucket_previous = e;
141 void* pa_hashmap_get(struct pa_hashmap *h, const void *key) {
143 struct hashmap_entry *e;
146 hash = h->hash_func(key) % h->size;
148 if (!(e = get(h, hash, key)))
154 int pa_hashmap_remove(struct pa_hashmap *h, const void *key) {
155 struct hashmap_entry *e;
159 hash = h->hash_func(key) % h->size;
161 if (!(e = get(h, hash, key)))
168 unsigned pa_hashmap_ncontents(struct pa_hashmap *h) {