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
) {
172 void *pa_hashmap_iterate(struct pa_hashmap
*h
, void **state
) {
176 *state
= h
->first_entry
;
178 *state
= ((struct hashmap_entry
*) *state
)->next
;
183 return ((struct hashmap_entry
*) *state
)->value
;