Polly 20.0.0git
isl_hash.c
Go to the documentation of this file.
1/*
2 * Copyright 2008-2009 Katholieke Universiteit Leuven
3 *
4 * Use of this software is governed by the MIT license
5 *
6 * Written by Sven Verdoolaege, K.U.Leuven, Departement
7 * Computerwetenschappen, Celestijnenlaan 200A, B-3001 Leuven, Belgium
8 */
9
10#include <stdlib.h>
11#include <isl_hash_private.h>
12#include <isl/ctx.h>
13#include "isl_config.h"
14
15uint32_t isl_hash_string(uint32_t hash, const char *s)
16{
17 for (; *s; s++)
18 isl_hash_byte(hash, *s);
19 return hash;
20}
21
22uint32_t isl_hash_mem(uint32_t hash, const void *p, size_t len)
23{
24 int i;
25 const char *s = p;
26 for (i = 0; i < len; ++i)
27 isl_hash_byte(hash, s[i]);
28 return hash;
29}
30
31static unsigned int round_up(unsigned int v)
32{
33 int old_v = v;
34
35 while (v) {
36 old_v = v;
37 v ^= v & -v;
38 }
39 return old_v << 1;
40}
41
42int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table,
43 int min_size)
44{
45 size_t size;
46
47 if (!table)
48 return -1;
49
50 if (min_size < 2)
51 min_size = 2;
52 table->bits = ffs(round_up(4 * (min_size + 1) / 3 - 1)) - 1;
53 table->n = 0;
54
55 size = 1 << table->bits;
57 size);
58 if (!table->entries)
59 return -1;
60
61 return 0;
62}
63
64/* Dummy comparison function that always returns false.
65 */
66static isl_bool no(const void *entry, const void *val)
67{
68 return isl_bool_false;
69}
70
71/* Extend "table" to twice its size.
72 * Return 0 on success and -1 on error.
73 *
74 * We reuse isl_hash_table_find to create entries in the extended table.
75 * Since all entries in the original table are assumed to be different,
76 * there is no need to compare them against each other.
77 */
78static int grow_table(struct isl_ctx *ctx, struct isl_hash_table *table)
79{
80 int n;
81 size_t old_size, size;
82 struct isl_hash_table_entry *entries;
83 uint32_t h;
84
85 entries = table->entries;
86 old_size = 1 << table->bits;
87 size = 2 * old_size;
89 size);
90 if (!table->entries) {
91 table->entries = entries;
92 return -1;
93 }
94
95 n = table->n;
96 table->n = 0;
97 table->bits++;
98
99 for (h = 0; h < old_size; ++h) {
100 struct isl_hash_table_entry *entry;
101
102 if (!entries[h].data)
103 continue;
104
105 entry = isl_hash_table_find(ctx, table, entries[h].hash,
106 &no, NULL, 1);
107 if (!entry) {
108 table->bits--;
109 free(table->entries);
110 table->entries = entries;
111 table->n = n;
112 return -1;
113 }
114
115 *entry = entries[h];
116 }
117
118 free(entries);
119
120 return 0;
121}
122
124{
125 struct isl_hash_table *table = NULL;
126
127 table = isl_alloc_type(ctx, struct isl_hash_table);
128 if (isl_hash_table_init(ctx, table, min_size))
129 goto error;
130 return table;
131error:
132 isl_hash_table_free(ctx, table);
133 return NULL;
134}
135
137{
138 if (!table)
139 return;
140 free(table->entries);
141}
142
143void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table)
144{
145 if (!table)
146 return;
148 free(table);
149}
150
151/* A dummy entry that is used by isl_hash_table_find
152 * to make a distinction between a missing entry and an error condition.
153 */
154static struct isl_hash_table_entry none = { 0, NULL };
156
158 struct isl_hash_table *table,
159 uint32_t key_hash,
160 isl_bool (*eq)(const void *entry, const void *val),
161 const void *val, int reserve)
162{
163 size_t size;
164 uint32_t h, key_bits;
165
166 key_bits = isl_hash_bits(key_hash, table->bits);
167 size = 1 << table->bits;
168 for (h = key_bits; table->entries[h].data; h = (h+1) % size) {
170
171 if (table->entries[h].hash != key_hash)
172 continue;
173 equal = eq(table->entries[h].data, val);
174 if (equal < 0)
175 return NULL;
176 if (equal)
177 return &table->entries[h];
178 }
179
180 if (!reserve)
182
183 if (4 * table->n >= 3 * size) {
184 if (grow_table(ctx, table) < 0)
185 return NULL;
186 return isl_hash_table_find(ctx, table, key_hash, eq, val, 1);
187 }
188
189 table->n++;
190 table->entries[h].hash = key_hash;
191
192 return &table->entries[h];
193}
194
195/* Return the first entry containing data in "table".
196 * Return isl_hash_table_entry_none is there is no such entry and
197 * NULL on error.
198 */
200{
201 size_t size;
202 uint32_t h;
203
204 if (!table->entries)
205 return NULL;
206
207 size = 1 << table->bits;
208 for (h = 0; h < size; ++ h)
209 if (table->entries[h].data)
210 return &table->entries[h];
211
213}
214
216 isl_stat (*fn)(void **entry, void *user), void *user)
217{
218 size_t size;
219 uint32_t h;
220
221 if (!table->entries)
222 return isl_stat_error;
223
224 size = 1 << table->bits;
225 for (h = 0; h < size; ++ h)
226 if (table->entries[h].data &&
227 fn(&table->entries[h].data, user) < 0)
228 return isl_stat_error;
229
230 return isl_stat_ok;
231}
232
233/* Does "test" succeed on every (non-empty) entry of "table"?
234 */
236 isl_bool (*test)(void **entry, void *user), void *user)
237{
238 size_t size;
239 uint32_t h;
240
241 if (!table->entries)
242 return isl_bool_error;
243
244 size = 1 << table->bits;
245 for (h = 0; h < size; ++ h) {
246 isl_bool r;
247
248 if (!table->entries[h].data)
249 continue;
250 r = test(&table->entries[h].data, user);
251 if (r < 0 || !r)
252 return r;
253 }
254
255 return isl_bool_true;
256}
257
259 struct isl_hash_table *table,
260 struct isl_hash_table_entry *entry)
261{
262 int h, h2;
263 size_t size;
264
265 if (!table || !entry)
266 return;
267
268 size = 1 << table->bits;
269 h = entry - table->entries;
270 isl_assert(ctx, h >= 0 && h < size, return);
271
272 for (h2 = h+1; table->entries[h2 % size].data; h2++) {
273 uint32_t bits = isl_hash_bits(table->entries[h2 % size].hash,
274 table->bits);
275 uint32_t offset = (size + bits - (h+1)) % size;
276 if (offset <= h2 - (h+1))
277 continue;
278 *entry = table->entries[h2 % size];
279 h = h2;
280 entry = &table->entries[h % size];
281 }
282
283 entry->hash = 0;
284 entry->data = NULL;
285 table->n--;
286}
isl_stat
Definition: ctx.h:84
@ isl_stat_error
Definition: ctx.h:85
@ isl_stat_ok
Definition: ctx.h:86
#define isl_assert(ctx, test, code)
Definition: ctx.h:152
#define isl_calloc_array(ctx, type, n)
Definition: ctx.h:132
#define isl_alloc_type(ctx, type)
Definition: ctx.h:128
isl_bool
Definition: ctx.h:89
@ isl_bool_false
Definition: ctx.h:91
@ isl_bool_true
Definition: ctx.h:92
@ isl_bool_error
Definition: ctx.h:90
#define isl_hash_bits(h, bits)
Definition: hash.h:33
#define isl_hash_byte(h, b)
Definition: hash.h:22
__isl_export __isl_give ISL_HMAP __isl_take ISL_KEY __isl_take ISL_VAL * val
Definition: hmap.h:32
isl_stat isl_stat(* fn)(__isl_take ISL_KEY *key, __isl_take ISL_VAL *val, void *user)
Definition: hmap.h:37
isl_stat isl_stat(*) void user)
Definition: hmap.h:39
__isl_constructor __isl_give ISL_HMAP int min_size
Definition: hmap.h:18
isl_bool isl_bool(* test)(__isl_keep ISL_KEY *key, __isl_keep ISL_VAL *val, void *user)
Definition: hmap.h:41
void isl_hash_table_clear(struct isl_hash_table *table)
Definition: isl_hash.c:136
isl_bool isl_hash_table_every(isl_ctx *ctx, struct isl_hash_table *table, isl_bool(*test)(void **entry, void *user), void *user)
Definition: isl_hash.c:235
static int grow_table(struct isl_ctx *ctx, struct isl_hash_table *table)
Definition: isl_hash.c:78
struct isl_hash_table_entry * isl_hash_table_entry_none
Definition: isl_hash.c:155
uint32_t isl_hash_string(uint32_t hash, const char *s)
Definition: isl_hash.c:15
static unsigned int round_up(unsigned int v)
Definition: isl_hash.c:31
uint32_t isl_hash_mem(uint32_t hash, const void *p, size_t len)
Definition: isl_hash.c:22
int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table, int min_size)
Definition: isl_hash.c:42
static isl_bool no(const void *entry, const void *val)
Definition: isl_hash.c:66
void isl_hash_table_remove(struct isl_ctx *ctx, struct isl_hash_table *table, struct isl_hash_table_entry *entry)
Definition: isl_hash.c:258
static struct isl_hash_table_entry none
Definition: isl_hash.c:154
void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table)
Definition: isl_hash.c:143
struct isl_hash_table_entry * isl_hash_table_first(struct isl_hash_table *table)
Definition: isl_hash.c:199
isl_stat isl_hash_table_foreach(isl_ctx *ctx, struct isl_hash_table *table, isl_stat(*fn)(void **entry, void *user), void *user)
Definition: isl_hash.c:215
struct isl_hash_table_entry * isl_hash_table_find(struct isl_ctx *ctx, struct isl_hash_table *table, uint32_t key_hash, isl_bool(*eq)(const void *entry, const void *val), const void *val, int reserve)
Definition: isl_hash.c:157
struct isl_hash_table * isl_hash_table_alloc(struct isl_ctx *ctx, int min_size)
Definition: isl_hash.c:123
int equal
Definition: isl_test.c:7868
const char * p
Definition: isl_test.c:8643
const char * offset
Definition: isl_test.c:1569
const char * size
Definition: isl_test.c:1570
Definition: hash.h:45
uint32_t hash
Definition: hash.h:46
void * data
Definition: hash.h:47
int bits
Definition: hash.h:51
struct isl_hash_table_entry * entries
Definition: hash.h:53
n
Definition: youcefn.c:8