isl_tab.h: fix typo in comment
[isl.git] / isl_hash.c
blobf751f46e59392b45537491c8f1889813af2da234
1 #include <stdlib.h>
2 #include "isl_hash.h"
3 #include "isl_ctx.h"
5 uint32_t isl_hash_string(uint32_t hash, const char *s)
7 for (; *s; s++)
8 isl_hash_byte(hash, *s);
9 return hash;
12 static unsigned int round_up(unsigned int v)
14 int old_v = v;
16 while (v) {
17 old_v = v;
18 v ^= v & -v;
20 return old_v << 1;
23 int isl_hash_table_init(struct isl_ctx *ctx, struct isl_hash_table *table,
24 int min_size)
26 size_t size;
28 if (!table)
29 return -1;
31 if (min_size < 2)
32 min_size = 2;
33 table->bits = ffs(round_up(4 * (min_size + 1) / 3 - 1)) - 1;
34 table->n = 0;
36 size = 2 << table->bits;
37 table->entries = isl_calloc_array(ctx, struct isl_hash_table_entry,
38 size);
39 if (!table->entries)
40 return -1;
42 return 0;
45 struct isl_hash_table *isl_hash_table_alloc(struct isl_ctx *ctx, int min_size)
47 struct isl_hash_table *table = NULL;
49 table = isl_alloc_type(ctx, struct isl_hash_table);
50 if (isl_hash_table_init(ctx, table, min_size))
51 goto error;
52 return table;
53 error:
54 isl_hash_table_free(ctx, table);
55 return NULL;
58 void isl_hash_table_clear(struct isl_hash_table *table)
60 if (!table)
61 return;
62 free(table->entries);
65 void isl_hash_table_free(struct isl_ctx *ctx, struct isl_hash_table *table)
67 if (!table)
68 return;
69 isl_hash_table_clear(table);
70 free(table);
73 struct isl_hash_table_entry *isl_hash_table_find(struct isl_ctx *ctx,
74 struct isl_hash_table *table,
75 uint32_t key_hash,
76 int (*eq)(const void *entry, const void *val),
77 const void *val, int reserve)
79 size_t size;
80 uint32_t h, key_bits;
82 key_bits = isl_hash_bits(key_hash, table->bits);
83 size = 2 << table->bits;
84 for (h = key_bits; table->entries[h].data; h = (h+1) % size)
85 if (table->entries[h].hash == key_hash &&
86 eq(table->entries[h].data, val))
87 return &table->entries[h];
89 if (!reserve)
90 return NULL;
92 assert(4 * table->n < 3 * size); /* XXX */
93 table->n++;
94 table->entries[h].hash = key_hash;
96 return &table->entries[h];
99 void isl_hash_table_remove(struct isl_ctx *ctx,
100 struct isl_hash_table *table,
101 struct isl_hash_table_entry *entry)
103 int h, h2, last_h;
104 size_t size;
106 if (!table || !entry)
107 return;
109 size = 2 << table->bits;
110 h = entry - table->entries;
111 isl_assert(ctx, h >= 0 && h < size, return);
113 for (h2 = h+1; table->entries[h2 % size].data; h2++) {
114 uint32_t bits = isl_hash_bits(table->entries[h2 % size].hash,
115 table->bits);
116 uint32_t offset = (size + bits - (h+1)) % size;
117 if (offset <= h2 - (h+1))
118 continue;
119 *entry = table->entries[h2 % size];
120 h = h2;
121 entry = &table->entries[h % size];
124 entry->hash = 0;
125 entry->data = NULL;
126 table->n--;