2 * Copyright (C) 2000, Matias Atria
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 /* simple hash tables for MDVI */
25 struct _DviHashBucket {
32 static Ulong hash_string(DviHashKey key)
37 for(h = 0, p = (Uchar *)key; *p; p++) {
39 if((g = h & 0xf0000000L) != 0) {
48 static int hash_compare(DviHashKey k1, DviHashKey k2)
50 return strcmp((char *)k1, (char *)k2);
53 void mdvi_hash_init(DviHashTable *hash)
58 hash->hash_func = NULL;
59 hash->hash_comp = NULL;
60 hash->hash_free = NULL;
63 void mdvi_hash_create(DviHashTable *hash, int size)
68 hash->buckets = xnalloc(DviHashBucket *, size);
69 for(i = 0; i < size; i++)
70 hash->buckets[i] = NULL;
71 hash->hash_func = hash_string;
72 hash->hash_comp = hash_compare;
73 hash->hash_free = NULL;
77 static DviHashBucket *hash_find(DviHashTable *hash, DviHashKey key)
82 hval = (hash->hash_func(key) % hash->nbucks);
84 for(buck = hash->buckets[hval]; buck; buck = buck->next)
85 if(hash->hash_comp(buck->key, key) == 0)
90 /* Neither keys nor data are duplicated */
91 int mdvi_hash_add(DviHashTable *hash, DviHashKey key, void *data, int rep)
93 DviHashBucket *buck = NULL;
96 if(rep != MDVI_HASH_UNCHECKED) {
97 buck = hash_find(hash, key);
99 if(buck->data == data)
101 if(rep == MDVI_HASH_UNIQUE)
103 if(hash->hash_free != NULL)
104 hash->hash_free(buck->key, buck->data);
108 buck = xalloc(DviHashBucket);
109 buck->hvalue = hash->hash_func(key);
110 hval = (buck->hvalue % hash->nbucks);
111 buck->next = hash->buckets[hval];
112 hash->buckets[hval] = buck;
116 /* save key and data */
123 void *mdvi_hash_lookup(DviHashTable *hash, DviHashKey key)
125 DviHashBucket *buck = hash_find(hash, key);
127 return buck ? buck->data : NULL;
130 static DviHashBucket *hash_remove(DviHashTable *hash, DviHashKey key)
132 DviHashBucket *buck, *last;
135 hval = hash->hash_func(key);
136 hval %= hash->nbucks;
138 for(last = NULL, buck = hash->buckets[hval]; buck; buck = buck->next) {
139 if(hash->hash_comp(buck->key, key) == 0)
146 last->next = buck->next;
148 hash->buckets[hval] = buck->next;
153 void *mdvi_hash_remove(DviHashTable *hash, DviHashKey key)
155 DviHashBucket *buck = hash_remove(hash, key);
165 void *mdvi_hash_remove_ptr(DviHashTable *hash, DviHashKey key)
167 DviHashBucket *buck, *last;
171 hval = hash->hash_func(key);
172 hval %= hash->nbucks;
174 for(last = NULL, buck = hash->buckets[hval]; buck; buck = buck->next) {
182 last->next = buck->next;
184 hash->buckets[hval] = buck->next;
186 /* destroy the bucket */
192 int mdvi_hash_destroy_key(DviHashTable *hash, DviHashKey key)
194 DviHashBucket *buck = hash_remove(hash, key);
199 hash->hash_free(buck->key, buck->data);
204 void mdvi_hash_reset(DviHashTable *hash, int reuse)
209 /* remove all keys in the hash table */
210 for(i = 0; i < hash->nbucks; i++) {
211 for(; (buck = hash->buckets[i]); ) {
212 hash->buckets[i] = buck->next;
214 hash->hash_free(buck->key, buck->data);
219 if(!reuse && hash->buckets) {
220 mdvi_free(hash->buckets);
221 hash->buckets = NULL;
223 } /* otherwise, it is left empty, ready to be reused */