2 * Copyright 2008-2009 Katholieke Universiteit Leuven
4 * Use of this software is governed by the MIT license
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
15 uint32_t isl_hash_string(uint32_t hash, const char *s)
18 isl_hash_byte(hash, *s);
22 uint32_t isl_hash_mem(uint32_t hash, const void *p, size_t len)
26 for (i = 0; i < len; ++i)
27 isl_hash_byte(hash, s[i]);
31 static unsigned int round_up(unsigned int v)
42 int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table,
52 table->bits = ffs(round_up(4 * (min_size + 1) / 3 - 1)) - 1;
55 size = 1 << table->bits;
56 table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry,
64 static int grow_table(struct isl_ctx *ctx, struct isl_hash_table *table,
65 int (*eq)(const void *entry, const void *val))
68 size_t old_size, size;
69 struct isl_hash_table_entry *entries;
72 entries = table->entries;
73 old_size = 1 << table->bits;
75 table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry,
77 if (!table->entries) {
78 table->entries = entries;
86 for (h = 0; h < old_size; ++h) {
87 struct isl_hash_table_entry *entry;
92 entry = isl_hash_table_find(ctx, table, entries[h].hash,
93 eq, entries[h].data, 1);
97 table->entries = entries;
110 struct isl_hash_table *isl_hash_table_alloc(struct isl_ctx *ctx, int min_size)
112 struct isl_hash_table *table = NULL;
114 table = isl_alloc_type(ctx, struct isl_hash_table);
115 if (isl_hash_table_init(ctx, table, min_size))
119 isl_hash_table_free(ctx, table);
123 void isl_hash_table_clear(struct isl_hash_table *table)
127 free(table->entries);
130 void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table)
134 isl_hash_table_clear(table);
138 struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx,
139 struct isl_hash_table *table,
141 int (*eq)(const void *entry, const void *val),
142 const void *val, int reserve)
145 uint32_t h, key_bits;
147 key_bits = isl_hash_bits(key_hash, table->bits);
148 size = 1 << table->bits;
149 for (h = key_bits; table->entries[h].data; h = (h+1) % size)
150 if (table->entries[h].hash == key_hash &&
151 eq(table->entries[h].data, val))
152 return &table->entries[h];
157 if (4 * table->n >= 3 * size) {
158 if (grow_table(ctx, table, eq) < 0)
160 return isl_hash_table_find(ctx, table, key_hash, eq, val, 1);
164 table->entries[h].hash = key_hash;
166 return &table->entries[h];
169 int isl_hash_table_foreach(struct isl_ctx *ctx,
170 struct isl_hash_table *table,
171 int (*fn)(void **entry, void *user), void *user)
176 size = 1 << table->bits;
177 for (h = 0; h < size; ++ h)
178 if (table->entries[h].data &&
179 fn(&table->entries[h].data, user) < 0)
185 void isl_hash_table_remove(struct isl_ctx *ctx,
186 struct isl_hash_table *table,
187 struct isl_hash_table_entry *entry)
192 if (!table || !entry)
195 size = 1 << table->bits;
196 h = entry - table->entries;
197 isl_assert(ctx, h >= 0 && h < size, return);
199 for (h2 = h+1; table->entries[h2 % size].data; h2++) {
200 uint32_t bits = isl_hash_bits(table->entries[h2 % size].hash,
202 uint32_t offset = (size + bits - (h+1)) % size;
203 if (offset <= h2 - (h+1))
205 *entry = table->entries[h2 % size];
207 entry = &table->entries[h % size];