1*cc4ad7daSAndroid Build Coastguard Worker /*
2*cc4ad7daSAndroid Build Coastguard Worker * libkmod - interface to kernel module operations
3*cc4ad7daSAndroid Build Coastguard Worker *
4*cc4ad7daSAndroid Build Coastguard Worker * Copyright (C) 2011-2013 ProFUSION embedded systems
5*cc4ad7daSAndroid Build Coastguard Worker *
6*cc4ad7daSAndroid Build Coastguard Worker * This library is free software; you can redistribute it and/or
7*cc4ad7daSAndroid Build Coastguard Worker * modify it under the terms of the GNU Lesser General Public
8*cc4ad7daSAndroid Build Coastguard Worker * License as published by the Free Software Foundation; either
9*cc4ad7daSAndroid Build Coastguard Worker * version 2.1 of the License, or (at your option) any later version.
10*cc4ad7daSAndroid Build Coastguard Worker *
11*cc4ad7daSAndroid Build Coastguard Worker * This library is distributed in the hope that it will be useful,
12*cc4ad7daSAndroid Build Coastguard Worker * but WITHOUT ANY WARRANTY; without even the implied warranty of
13*cc4ad7daSAndroid Build Coastguard Worker * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14*cc4ad7daSAndroid Build Coastguard Worker * Lesser General Public License for more details.
15*cc4ad7daSAndroid Build Coastguard Worker *
16*cc4ad7daSAndroid Build Coastguard Worker * You should have received a copy of the GNU Lesser General Public
17*cc4ad7daSAndroid Build Coastguard Worker * License along with this library; if not, see <http://www.gnu.org/licenses/>.
18*cc4ad7daSAndroid Build Coastguard Worker */
19*cc4ad7daSAndroid Build Coastguard Worker
20*cc4ad7daSAndroid Build Coastguard Worker #include <errno.h>
21*cc4ad7daSAndroid Build Coastguard Worker #include <inttypes.h>
22*cc4ad7daSAndroid Build Coastguard Worker #include <stdlib.h>
23*cc4ad7daSAndroid Build Coastguard Worker #include <string.h>
24*cc4ad7daSAndroid Build Coastguard Worker
25*cc4ad7daSAndroid Build Coastguard Worker #include <shared/hash.h>
26*cc4ad7daSAndroid Build Coastguard Worker #include <shared/util.h>
27*cc4ad7daSAndroid Build Coastguard Worker
28*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry {
29*cc4ad7daSAndroid Build Coastguard Worker const char *key;
30*cc4ad7daSAndroid Build Coastguard Worker const void *value;
31*cc4ad7daSAndroid Build Coastguard Worker };
32*cc4ad7daSAndroid Build Coastguard Worker
33*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket {
34*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *entries;
35*cc4ad7daSAndroid Build Coastguard Worker unsigned int used;
36*cc4ad7daSAndroid Build Coastguard Worker unsigned int total;
37*cc4ad7daSAndroid Build Coastguard Worker };
38*cc4ad7daSAndroid Build Coastguard Worker
39*cc4ad7daSAndroid Build Coastguard Worker struct hash {
40*cc4ad7daSAndroid Build Coastguard Worker unsigned int count;
41*cc4ad7daSAndroid Build Coastguard Worker unsigned int step;
42*cc4ad7daSAndroid Build Coastguard Worker unsigned int n_buckets;
43*cc4ad7daSAndroid Build Coastguard Worker void (*free_value)(void *value);
44*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket buckets[];
45*cc4ad7daSAndroid Build Coastguard Worker };
46*cc4ad7daSAndroid Build Coastguard Worker
hash_new(unsigned int n_buckets,void (* free_value)(void * value))47*cc4ad7daSAndroid Build Coastguard Worker struct hash *hash_new(unsigned int n_buckets,
48*cc4ad7daSAndroid Build Coastguard Worker void (*free_value)(void *value))
49*cc4ad7daSAndroid Build Coastguard Worker {
50*cc4ad7daSAndroid Build Coastguard Worker struct hash *hash;
51*cc4ad7daSAndroid Build Coastguard Worker
52*cc4ad7daSAndroid Build Coastguard Worker n_buckets = ALIGN_POWER2(n_buckets);
53*cc4ad7daSAndroid Build Coastguard Worker hash = calloc(1, sizeof(struct hash) +
54*cc4ad7daSAndroid Build Coastguard Worker n_buckets * sizeof(struct hash_bucket));
55*cc4ad7daSAndroid Build Coastguard Worker if (hash == NULL)
56*cc4ad7daSAndroid Build Coastguard Worker return NULL;
57*cc4ad7daSAndroid Build Coastguard Worker hash->n_buckets = n_buckets;
58*cc4ad7daSAndroid Build Coastguard Worker hash->free_value = free_value;
59*cc4ad7daSAndroid Build Coastguard Worker hash->step = n_buckets / 32;
60*cc4ad7daSAndroid Build Coastguard Worker if (hash->step == 0)
61*cc4ad7daSAndroid Build Coastguard Worker hash->step = 4;
62*cc4ad7daSAndroid Build Coastguard Worker else if (hash->step > 64)
63*cc4ad7daSAndroid Build Coastguard Worker hash->step = 64;
64*cc4ad7daSAndroid Build Coastguard Worker return hash;
65*cc4ad7daSAndroid Build Coastguard Worker }
66*cc4ad7daSAndroid Build Coastguard Worker
hash_free(struct hash * hash)67*cc4ad7daSAndroid Build Coastguard Worker void hash_free(struct hash *hash)
68*cc4ad7daSAndroid Build Coastguard Worker {
69*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket *bucket, *bucket_end;
70*cc4ad7daSAndroid Build Coastguard Worker
71*cc4ad7daSAndroid Build Coastguard Worker if (hash == NULL)
72*cc4ad7daSAndroid Build Coastguard Worker return;
73*cc4ad7daSAndroid Build Coastguard Worker
74*cc4ad7daSAndroid Build Coastguard Worker bucket = hash->buckets;
75*cc4ad7daSAndroid Build Coastguard Worker bucket_end = bucket + hash->n_buckets;
76*cc4ad7daSAndroid Build Coastguard Worker for (; bucket < bucket_end; bucket++) {
77*cc4ad7daSAndroid Build Coastguard Worker if (hash->free_value) {
78*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *entry, *entry_end;
79*cc4ad7daSAndroid Build Coastguard Worker entry = bucket->entries;
80*cc4ad7daSAndroid Build Coastguard Worker entry_end = entry + bucket->used;
81*cc4ad7daSAndroid Build Coastguard Worker for (; entry < entry_end; entry++)
82*cc4ad7daSAndroid Build Coastguard Worker hash->free_value((void *)entry->value);
83*cc4ad7daSAndroid Build Coastguard Worker }
84*cc4ad7daSAndroid Build Coastguard Worker free(bucket->entries);
85*cc4ad7daSAndroid Build Coastguard Worker }
86*cc4ad7daSAndroid Build Coastguard Worker free(hash);
87*cc4ad7daSAndroid Build Coastguard Worker }
88*cc4ad7daSAndroid Build Coastguard Worker
hash_superfast(const char * key,unsigned int len)89*cc4ad7daSAndroid Build Coastguard Worker static inline unsigned int hash_superfast(const char *key, unsigned int len)
90*cc4ad7daSAndroid Build Coastguard Worker {
91*cc4ad7daSAndroid Build Coastguard Worker /* Paul Hsieh (http://www.azillionmonkeys.com/qed/hash.html)
92*cc4ad7daSAndroid Build Coastguard Worker * used by WebCore (http://webkit.org/blog/8/hashtables-part-2/)
93*cc4ad7daSAndroid Build Coastguard Worker * EFL's eina and possible others.
94*cc4ad7daSAndroid Build Coastguard Worker */
95*cc4ad7daSAndroid Build Coastguard Worker unsigned int tmp, hash = len, rem = len & 3;
96*cc4ad7daSAndroid Build Coastguard Worker
97*cc4ad7daSAndroid Build Coastguard Worker len /= 4;
98*cc4ad7daSAndroid Build Coastguard Worker
99*cc4ad7daSAndroid Build Coastguard Worker /* Main loop */
100*cc4ad7daSAndroid Build Coastguard Worker for (; len > 0; len--) {
101*cc4ad7daSAndroid Build Coastguard Worker hash += get_unaligned((uint16_t *) key);
102*cc4ad7daSAndroid Build Coastguard Worker tmp = (get_unaligned((uint16_t *)(key + 2)) << 11) ^ hash;
103*cc4ad7daSAndroid Build Coastguard Worker hash = (hash << 16) ^ tmp;
104*cc4ad7daSAndroid Build Coastguard Worker key += 4;
105*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 11;
106*cc4ad7daSAndroid Build Coastguard Worker }
107*cc4ad7daSAndroid Build Coastguard Worker
108*cc4ad7daSAndroid Build Coastguard Worker /* Handle end cases */
109*cc4ad7daSAndroid Build Coastguard Worker switch (rem) {
110*cc4ad7daSAndroid Build Coastguard Worker case 3:
111*cc4ad7daSAndroid Build Coastguard Worker hash += get_unaligned((uint16_t *) key);
112*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 16;
113*cc4ad7daSAndroid Build Coastguard Worker hash ^= key[2] << 18;
114*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 11;
115*cc4ad7daSAndroid Build Coastguard Worker break;
116*cc4ad7daSAndroid Build Coastguard Worker
117*cc4ad7daSAndroid Build Coastguard Worker case 2:
118*cc4ad7daSAndroid Build Coastguard Worker hash += get_unaligned((uint16_t *) key);
119*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 11;
120*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 17;
121*cc4ad7daSAndroid Build Coastguard Worker break;
122*cc4ad7daSAndroid Build Coastguard Worker
123*cc4ad7daSAndroid Build Coastguard Worker case 1:
124*cc4ad7daSAndroid Build Coastguard Worker hash += *key;
125*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 10;
126*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 1;
127*cc4ad7daSAndroid Build Coastguard Worker }
128*cc4ad7daSAndroid Build Coastguard Worker
129*cc4ad7daSAndroid Build Coastguard Worker /* Force "avalanching" of final 127 bits */
130*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 3;
131*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 5;
132*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 4;
133*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 17;
134*cc4ad7daSAndroid Build Coastguard Worker hash ^= hash << 25;
135*cc4ad7daSAndroid Build Coastguard Worker hash += hash >> 6;
136*cc4ad7daSAndroid Build Coastguard Worker
137*cc4ad7daSAndroid Build Coastguard Worker return hash;
138*cc4ad7daSAndroid Build Coastguard Worker }
139*cc4ad7daSAndroid Build Coastguard Worker
140*cc4ad7daSAndroid Build Coastguard Worker /*
141*cc4ad7daSAndroid Build Coastguard Worker * add or replace key in hash map.
142*cc4ad7daSAndroid Build Coastguard Worker *
143*cc4ad7daSAndroid Build Coastguard Worker * none of key or value are copied, just references are remembered as is,
144*cc4ad7daSAndroid Build Coastguard Worker * make sure they are live while pair exists in hash!
145*cc4ad7daSAndroid Build Coastguard Worker */
hash_add(struct hash * hash,const char * key,const void * value)146*cc4ad7daSAndroid Build Coastguard Worker int hash_add(struct hash *hash, const char *key, const void *value)
147*cc4ad7daSAndroid Build Coastguard Worker {
148*cc4ad7daSAndroid Build Coastguard Worker unsigned int keylen = strlen(key);
149*cc4ad7daSAndroid Build Coastguard Worker unsigned int hashval = hash_superfast(key, keylen);
150*cc4ad7daSAndroid Build Coastguard Worker unsigned int pos = hashval & (hash->n_buckets - 1);
151*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket *bucket = hash->buckets + pos;
152*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *entry, *entry_end;
153*cc4ad7daSAndroid Build Coastguard Worker
154*cc4ad7daSAndroid Build Coastguard Worker if (bucket->used + 1 >= bucket->total) {
155*cc4ad7daSAndroid Build Coastguard Worker unsigned new_total = bucket->total + hash->step;
156*cc4ad7daSAndroid Build Coastguard Worker size_t size = new_total * sizeof(struct hash_entry);
157*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *tmp = realloc(bucket->entries, size);
158*cc4ad7daSAndroid Build Coastguard Worker if (tmp == NULL)
159*cc4ad7daSAndroid Build Coastguard Worker return -errno;
160*cc4ad7daSAndroid Build Coastguard Worker bucket->entries = tmp;
161*cc4ad7daSAndroid Build Coastguard Worker bucket->total = new_total;
162*cc4ad7daSAndroid Build Coastguard Worker }
163*cc4ad7daSAndroid Build Coastguard Worker
164*cc4ad7daSAndroid Build Coastguard Worker entry = bucket->entries;
165*cc4ad7daSAndroid Build Coastguard Worker entry_end = entry + bucket->used;
166*cc4ad7daSAndroid Build Coastguard Worker for (; entry < entry_end; entry++) {
167*cc4ad7daSAndroid Build Coastguard Worker int c = strcmp(key, entry->key);
168*cc4ad7daSAndroid Build Coastguard Worker if (c == 0) {
169*cc4ad7daSAndroid Build Coastguard Worker if (hash->free_value)
170*cc4ad7daSAndroid Build Coastguard Worker hash->free_value((void *)entry->value);
171*cc4ad7daSAndroid Build Coastguard Worker entry->key = key;
172*cc4ad7daSAndroid Build Coastguard Worker entry->value = value;
173*cc4ad7daSAndroid Build Coastguard Worker return 0;
174*cc4ad7daSAndroid Build Coastguard Worker } else if (c < 0) {
175*cc4ad7daSAndroid Build Coastguard Worker memmove(entry + 1, entry,
176*cc4ad7daSAndroid Build Coastguard Worker (entry_end - entry) * sizeof(struct hash_entry));
177*cc4ad7daSAndroid Build Coastguard Worker break;
178*cc4ad7daSAndroid Build Coastguard Worker }
179*cc4ad7daSAndroid Build Coastguard Worker }
180*cc4ad7daSAndroid Build Coastguard Worker
181*cc4ad7daSAndroid Build Coastguard Worker entry->key = key;
182*cc4ad7daSAndroid Build Coastguard Worker entry->value = value;
183*cc4ad7daSAndroid Build Coastguard Worker bucket->used++;
184*cc4ad7daSAndroid Build Coastguard Worker hash->count++;
185*cc4ad7daSAndroid Build Coastguard Worker return 0;
186*cc4ad7daSAndroid Build Coastguard Worker }
187*cc4ad7daSAndroid Build Coastguard Worker
188*cc4ad7daSAndroid Build Coastguard Worker /* similar to hash_add(), but fails if key already exists */
hash_add_unique(struct hash * hash,const char * key,const void * value)189*cc4ad7daSAndroid Build Coastguard Worker int hash_add_unique(struct hash *hash, const char *key, const void *value)
190*cc4ad7daSAndroid Build Coastguard Worker {
191*cc4ad7daSAndroid Build Coastguard Worker unsigned int keylen = strlen(key);
192*cc4ad7daSAndroid Build Coastguard Worker unsigned int hashval = hash_superfast(key, keylen);
193*cc4ad7daSAndroid Build Coastguard Worker unsigned int pos = hashval & (hash->n_buckets - 1);
194*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket *bucket = hash->buckets + pos;
195*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *entry, *entry_end;
196*cc4ad7daSAndroid Build Coastguard Worker
197*cc4ad7daSAndroid Build Coastguard Worker if (bucket->used + 1 >= bucket->total) {
198*cc4ad7daSAndroid Build Coastguard Worker unsigned new_total = bucket->total + hash->step;
199*cc4ad7daSAndroid Build Coastguard Worker size_t size = new_total * sizeof(struct hash_entry);
200*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *tmp = realloc(bucket->entries, size);
201*cc4ad7daSAndroid Build Coastguard Worker if (tmp == NULL)
202*cc4ad7daSAndroid Build Coastguard Worker return -errno;
203*cc4ad7daSAndroid Build Coastguard Worker bucket->entries = tmp;
204*cc4ad7daSAndroid Build Coastguard Worker bucket->total = new_total;
205*cc4ad7daSAndroid Build Coastguard Worker }
206*cc4ad7daSAndroid Build Coastguard Worker
207*cc4ad7daSAndroid Build Coastguard Worker entry = bucket->entries;
208*cc4ad7daSAndroid Build Coastguard Worker entry_end = entry + bucket->used;
209*cc4ad7daSAndroid Build Coastguard Worker for (; entry < entry_end; entry++) {
210*cc4ad7daSAndroid Build Coastguard Worker int c = strcmp(key, entry->key);
211*cc4ad7daSAndroid Build Coastguard Worker if (c == 0)
212*cc4ad7daSAndroid Build Coastguard Worker return -EEXIST;
213*cc4ad7daSAndroid Build Coastguard Worker else if (c < 0) {
214*cc4ad7daSAndroid Build Coastguard Worker memmove(entry + 1, entry,
215*cc4ad7daSAndroid Build Coastguard Worker (entry_end - entry) * sizeof(struct hash_entry));
216*cc4ad7daSAndroid Build Coastguard Worker break;
217*cc4ad7daSAndroid Build Coastguard Worker }
218*cc4ad7daSAndroid Build Coastguard Worker }
219*cc4ad7daSAndroid Build Coastguard Worker
220*cc4ad7daSAndroid Build Coastguard Worker entry->key = key;
221*cc4ad7daSAndroid Build Coastguard Worker entry->value = value;
222*cc4ad7daSAndroid Build Coastguard Worker bucket->used++;
223*cc4ad7daSAndroid Build Coastguard Worker hash->count++;
224*cc4ad7daSAndroid Build Coastguard Worker return 0;
225*cc4ad7daSAndroid Build Coastguard Worker }
226*cc4ad7daSAndroid Build Coastguard Worker
hash_entry_cmp(const void * pa,const void * pb)227*cc4ad7daSAndroid Build Coastguard Worker static int hash_entry_cmp(const void *pa, const void *pb)
228*cc4ad7daSAndroid Build Coastguard Worker {
229*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry *a = pa;
230*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry *b = pb;
231*cc4ad7daSAndroid Build Coastguard Worker return strcmp(a->key, b->key);
232*cc4ad7daSAndroid Build Coastguard Worker }
233*cc4ad7daSAndroid Build Coastguard Worker
hash_find(const struct hash * hash,const char * key)234*cc4ad7daSAndroid Build Coastguard Worker void *hash_find(const struct hash *hash, const char *key)
235*cc4ad7daSAndroid Build Coastguard Worker {
236*cc4ad7daSAndroid Build Coastguard Worker unsigned int keylen = strlen(key);
237*cc4ad7daSAndroid Build Coastguard Worker unsigned int hashval = hash_superfast(key, keylen);
238*cc4ad7daSAndroid Build Coastguard Worker unsigned int pos = hashval & (hash->n_buckets - 1);
239*cc4ad7daSAndroid Build Coastguard Worker const struct hash_bucket *bucket = hash->buckets + pos;
240*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry se = {
241*cc4ad7daSAndroid Build Coastguard Worker .key = key,
242*cc4ad7daSAndroid Build Coastguard Worker .value = NULL
243*cc4ad7daSAndroid Build Coastguard Worker };
244*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry *entry;
245*cc4ad7daSAndroid Build Coastguard Worker
246*cc4ad7daSAndroid Build Coastguard Worker if (!bucket->entries)
247*cc4ad7daSAndroid Build Coastguard Worker return NULL;
248*cc4ad7daSAndroid Build Coastguard Worker
249*cc4ad7daSAndroid Build Coastguard Worker entry = bsearch(&se, bucket->entries, bucket->used,
250*cc4ad7daSAndroid Build Coastguard Worker sizeof(struct hash_entry), hash_entry_cmp);
251*cc4ad7daSAndroid Build Coastguard Worker
252*cc4ad7daSAndroid Build Coastguard Worker return entry ? (void *)entry->value : NULL;
253*cc4ad7daSAndroid Build Coastguard Worker }
254*cc4ad7daSAndroid Build Coastguard Worker
hash_del(struct hash * hash,const char * key)255*cc4ad7daSAndroid Build Coastguard Worker int hash_del(struct hash *hash, const char *key)
256*cc4ad7daSAndroid Build Coastguard Worker {
257*cc4ad7daSAndroid Build Coastguard Worker unsigned int keylen = strlen(key);
258*cc4ad7daSAndroid Build Coastguard Worker unsigned int hashval = hash_superfast(key, keylen);
259*cc4ad7daSAndroid Build Coastguard Worker unsigned int pos = hashval & (hash->n_buckets - 1);
260*cc4ad7daSAndroid Build Coastguard Worker unsigned int steps_used, steps_total;
261*cc4ad7daSAndroid Build Coastguard Worker struct hash_bucket *bucket = hash->buckets + pos;
262*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *entry, *entry_end;
263*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry se = {
264*cc4ad7daSAndroid Build Coastguard Worker .key = key,
265*cc4ad7daSAndroid Build Coastguard Worker .value = NULL
266*cc4ad7daSAndroid Build Coastguard Worker };
267*cc4ad7daSAndroid Build Coastguard Worker
268*cc4ad7daSAndroid Build Coastguard Worker entry = bsearch(&se, bucket->entries, bucket->used,
269*cc4ad7daSAndroid Build Coastguard Worker sizeof(struct hash_entry), hash_entry_cmp);
270*cc4ad7daSAndroid Build Coastguard Worker if (entry == NULL)
271*cc4ad7daSAndroid Build Coastguard Worker return -ENOENT;
272*cc4ad7daSAndroid Build Coastguard Worker
273*cc4ad7daSAndroid Build Coastguard Worker if (hash->free_value)
274*cc4ad7daSAndroid Build Coastguard Worker hash->free_value((void *)entry->value);
275*cc4ad7daSAndroid Build Coastguard Worker
276*cc4ad7daSAndroid Build Coastguard Worker entry_end = bucket->entries + bucket->used;
277*cc4ad7daSAndroid Build Coastguard Worker memmove(entry, entry + 1,
278*cc4ad7daSAndroid Build Coastguard Worker (entry_end - entry) * sizeof(struct hash_entry));
279*cc4ad7daSAndroid Build Coastguard Worker
280*cc4ad7daSAndroid Build Coastguard Worker bucket->used--;
281*cc4ad7daSAndroid Build Coastguard Worker hash->count--;
282*cc4ad7daSAndroid Build Coastguard Worker
283*cc4ad7daSAndroid Build Coastguard Worker steps_used = bucket->used / hash->step;
284*cc4ad7daSAndroid Build Coastguard Worker steps_total = bucket->total / hash->step;
285*cc4ad7daSAndroid Build Coastguard Worker if (steps_used + 1 < steps_total) {
286*cc4ad7daSAndroid Build Coastguard Worker size_t size = (steps_used + 1) *
287*cc4ad7daSAndroid Build Coastguard Worker hash->step * sizeof(struct hash_entry);
288*cc4ad7daSAndroid Build Coastguard Worker struct hash_entry *tmp = realloc(bucket->entries, size);
289*cc4ad7daSAndroid Build Coastguard Worker if (tmp) {
290*cc4ad7daSAndroid Build Coastguard Worker bucket->entries = tmp;
291*cc4ad7daSAndroid Build Coastguard Worker bucket->total = (steps_used + 1) * hash->step;
292*cc4ad7daSAndroid Build Coastguard Worker }
293*cc4ad7daSAndroid Build Coastguard Worker }
294*cc4ad7daSAndroid Build Coastguard Worker
295*cc4ad7daSAndroid Build Coastguard Worker return 0;
296*cc4ad7daSAndroid Build Coastguard Worker }
297*cc4ad7daSAndroid Build Coastguard Worker
hash_get_count(const struct hash * hash)298*cc4ad7daSAndroid Build Coastguard Worker unsigned int hash_get_count(const struct hash *hash)
299*cc4ad7daSAndroid Build Coastguard Worker {
300*cc4ad7daSAndroid Build Coastguard Worker return hash->count;
301*cc4ad7daSAndroid Build Coastguard Worker }
302*cc4ad7daSAndroid Build Coastguard Worker
hash_iter_init(const struct hash * hash,struct hash_iter * iter)303*cc4ad7daSAndroid Build Coastguard Worker void hash_iter_init(const struct hash *hash, struct hash_iter *iter)
304*cc4ad7daSAndroid Build Coastguard Worker {
305*cc4ad7daSAndroid Build Coastguard Worker iter->hash = hash;
306*cc4ad7daSAndroid Build Coastguard Worker iter->bucket = 0;
307*cc4ad7daSAndroid Build Coastguard Worker iter->entry = -1;
308*cc4ad7daSAndroid Build Coastguard Worker }
309*cc4ad7daSAndroid Build Coastguard Worker
hash_iter_next(struct hash_iter * iter,const char ** key,const void ** value)310*cc4ad7daSAndroid Build Coastguard Worker bool hash_iter_next(struct hash_iter *iter, const char **key,
311*cc4ad7daSAndroid Build Coastguard Worker const void **value)
312*cc4ad7daSAndroid Build Coastguard Worker {
313*cc4ad7daSAndroid Build Coastguard Worker const struct hash_bucket *b = iter->hash->buckets + iter->bucket;
314*cc4ad7daSAndroid Build Coastguard Worker const struct hash_entry *e;
315*cc4ad7daSAndroid Build Coastguard Worker
316*cc4ad7daSAndroid Build Coastguard Worker iter->entry++;
317*cc4ad7daSAndroid Build Coastguard Worker
318*cc4ad7daSAndroid Build Coastguard Worker if (iter->entry >= b->used) {
319*cc4ad7daSAndroid Build Coastguard Worker iter->entry = 0;
320*cc4ad7daSAndroid Build Coastguard Worker
321*cc4ad7daSAndroid Build Coastguard Worker for (iter->bucket++; iter->bucket < iter->hash->n_buckets;
322*cc4ad7daSAndroid Build Coastguard Worker iter->bucket++) {
323*cc4ad7daSAndroid Build Coastguard Worker b = iter->hash->buckets + iter->bucket;
324*cc4ad7daSAndroid Build Coastguard Worker
325*cc4ad7daSAndroid Build Coastguard Worker if (b->used > 0)
326*cc4ad7daSAndroid Build Coastguard Worker break;
327*cc4ad7daSAndroid Build Coastguard Worker }
328*cc4ad7daSAndroid Build Coastguard Worker
329*cc4ad7daSAndroid Build Coastguard Worker if (iter->bucket >= iter->hash->n_buckets)
330*cc4ad7daSAndroid Build Coastguard Worker return false;
331*cc4ad7daSAndroid Build Coastguard Worker }
332*cc4ad7daSAndroid Build Coastguard Worker
333*cc4ad7daSAndroid Build Coastguard Worker e = b->entries + iter->entry;
334*cc4ad7daSAndroid Build Coastguard Worker
335*cc4ad7daSAndroid Build Coastguard Worker if (value != NULL)
336*cc4ad7daSAndroid Build Coastguard Worker *value = e->value;
337*cc4ad7daSAndroid Build Coastguard Worker if (key != NULL)
338*cc4ad7daSAndroid Build Coastguard Worker *key = e->key;
339*cc4ad7daSAndroid Build Coastguard Worker
340*cc4ad7daSAndroid Build Coastguard Worker return true;
341*cc4ad7daSAndroid Build Coastguard Worker }
342