19static uint32_t ir_str_hash(
const char *str,
size_t len)
24 for (i = 0; i <
len; i++) {
25 h = ((h << 5) + h) + *str;
28 return h | 0x10000000;
31static uint32_t ir_strtab_hash_size(uint32_t
size)
43static void ir_strtab_resize(
ir_strtab *strtab)
45 uint32_t old_hash_size = (uint32_t)(-(int32_t)strtab->mask);
46 char *old_data = strtab->data;
47 uint32_t
size = strtab->size * 2;
48 uint32_t hash_size = ir_strtab_hash_size(
size);
54 strtab->data =
data + (hash_size *
sizeof(uint32_t));
55 strtab->mask = (uint32_t)(-(int32_t)hash_size);
59 ir_mem_free(old_data - (old_hash_size *
sizeof(uint32_t)));
65 uint32_t h =
p->h | strtab->mask;
66 p->next = ((uint32_t*)strtab->data)[(int32_t)h];
67 ((uint32_t*)strtab->data)[(int32_t)h] =
pos;
73static void ir_strtab_grow_buf(
ir_strtab *strtab, uint32_t
len)
75 intptr_t old = (intptr_t)strtab->buf;
78 strtab->buf_size *= 2;
79 }
while (
UNEXPECTED(strtab->buf_size - strtab->buf_top <
len + 1));
82 if ((intptr_t)strtab->buf != old) {
83 intptr_t
offset = (intptr_t)strtab->buf - old;
86 for (i = strtab->count; i > 0; i--) {
96 uint32_t hash_size = ir_strtab_hash_size(
size);
99 strtab->data = (
data + (hash_size *
sizeof(uint32_t)));
100 strtab->mask = (uint32_t)(-(int32_t)hash_size);
106 strtab->buf_size = buf_size;
110 strtab->buf_size = 0;
117 uint32_t h = ir_str_hash(str,
len);
118 const char *
data = (
const char*)strtab->data;
119 uint32_t
pos = ((uint32_t*)
data)[(int32_t)(h | strtab->mask)];
126 && memcmp(
p->str, str,
len) == 0) {
136 uint32_t h = ir_str_hash(str,
len);
137 char *
data = (
char*)strtab->data;
138 uint32_t
pos = ((uint32_t*)
data)[(int32_t)(h | strtab->mask)];
145 && memcmp(
p->str, str,
len) == 0) {
153 if (
UNEXPECTED(strtab->count >= strtab->size)) {
154 ir_strtab_resize(strtab);
159 if (
UNEXPECTED(strtab->buf_size - strtab->buf_top <
len + 1)) {
160 ir_strtab_grow_buf(strtab,
len + 1);
163 memcpy(strtab->buf + strtab->buf_top, str,
len);
164 strtab->buf[strtab->buf_top +
len] = 0;
165 str = (
const char*)strtab->buf + strtab->buf_top;
166 strtab->buf_top +=
len + 1;
177 p->next = ((uint32_t*)
data)[(int32_t)h];
178 ((uint32_t*)
data)[(int32_t)h] =
pos;
185 uint32_t h = ir_str_hash(str,
len);
186 char *
data = (
char*)strtab->data;
187 uint32_t
pos = ((uint32_t*)
data)[(int32_t)(h | strtab->mask)];
194 && memcmp(
p->str, str,
len) == 0) {
218 uint32_t hash_size = (uint32_t)(-(int32_t)strtab->mask);
219 char *
data = (
char*)strtab->data - (hash_size *
sizeof(uint32_t));
232 for (i = 0; i < strtab->count; i++) {
count(Countable|array $value, int $mode=COUNT_NORMAL)
memset(ptr, 0, type->size)
struct _ir_strtab ir_strtab
void(* ir_strtab_apply_t)(const char *str, uint32_t len, ir_ref val)
ir_ref ir_strtab_find(const ir_strtab *strtab, const char *str, uint32_t len)
const char * ir_strtab_strl(const ir_strtab *strtab, ir_ref idx, size_t *len)
void ir_strtab_apply(const ir_strtab *strtab, ir_strtab_apply_t func)
ir_ref ir_strtab_update(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val)
struct _ir_strtab_bucket ir_strtab_bucket
void ir_strtab_init(ir_strtab *strtab, uint32_t size, uint32_t buf_size)
const char * ir_strtab_str(const ir_strtab *strtab, ir_ref idx)
ir_ref ir_strtab_lookup(ir_strtab *strtab, const char *str, uint32_t len, ir_ref val)
void ir_strtab_free(ir_strtab *strtab)
unsigned const char * pos
#define UNEXPECTED(condition)