7 array_init(struct array *array)
9 memset(array, 0, sizeof *array);
13 array_release(struct array *array)
19 array_add(struct array *array, int size)
29 while (alloc < array->size + size)
32 if (array->alloc < alloc) {
33 data = realloc(array->data, alloc);
40 p = array->data + array->size;
46 /* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
47 #define RAZOR_ENTRY_LAST 0x80
48 #define RAZOR_IMMEDIATE 0x80
49 #define RAZOR_EMPTY_LIST 0xff
52 list_set_empty(struct list_head *head)
55 head->flags = RAZOR_EMPTY_LIST;
59 list_set_ptr(struct list_head *head, uint32_t ptr)
66 list_set_array(struct list_head *head, struct array *pool, struct array *items)
70 if (items->size == 0) {
72 } else if (items->size == sizeof (uint32_t)) {
73 head->list_ptr = *(uint32_t *) items->data;
74 head->flags = RAZOR_IMMEDIATE;
76 p = array_add(pool, items->size);
77 memcpy(p, items->data, items->size);
78 p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
79 list_set_ptr(head, p - (struct list *) pool->data);
84 list_first(struct list_head *head, struct array *pool)
86 if (head->flags == RAZOR_EMPTY_LIST)
88 else if (head->flags == RAZOR_IMMEDIATE)
89 return (struct list *) head;
91 return (struct list *) pool->data + head->list_ptr;
95 list_next(struct list *list)
103 list_remap_pool(struct array *pool, uint32_t *map)
105 struct list *p, *end;
107 end = pool->data + pool->size;
108 for (p = pool->data; p < end; p++)
109 p->data = map[p->data];
113 list_remap_head(struct list_head *head, uint32_t *map)
115 if (head->flags == RAZOR_IMMEDIATE)
116 head->list_ptr = map[head->list_ptr];
121 hashtable_init(struct hashtable *table, struct array *pool)
123 array_init(&table->buckets);
128 hashtable_release(struct hashtable *table)
130 array_release(&table->buckets);
134 hash_string(const char *key)
137 unsigned int hash = 0;
139 for (p = key; *p; p++)
140 hash = (hash * 617) ^ *p;
146 hashtable_lookup(struct hashtable *table, const char *key)
148 unsigned int mask, start, i;
152 pool = table->pool->data;
153 mask = table->buckets.alloc - 1;
154 start = hash_string(key) * sizeof(uint32_t);
156 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
157 b = table->buckets.data + ((start + i) & mask);
162 if (strcmp(key, &pool[*b]) == 0)
170 do_insert(struct hashtable *table, uint32_t value)
172 unsigned int mask, start, i;
176 key = (char *) table->pool->data + value;
177 mask = table->buckets.alloc - 1;
178 start = hash_string(key) * sizeof(uint32_t);
180 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
181 b = table->buckets.data + ((start + i) & mask);
190 add_to_string_pool(struct hashtable *table, const char *key)
195 len = strlen(key) + 1;
196 p = array_add(table->pool, len);
199 return p - (char *) table->pool->data;
203 hashtable_insert(struct hashtable *table, const char *key)
205 uint32_t value, *buckets, *b, *end;
208 alloc = table->buckets.alloc;
209 array_add(&table->buckets, 4 * sizeof *buckets);
210 if (alloc != table->buckets.alloc) {
211 end = table->buckets.data + alloc;
212 memset(end, 0, table->buckets.alloc - alloc);
213 for (b = table->buckets.data; b < end; b++) {
217 do_insert(table, value);
222 value = add_to_string_pool(table, key);
223 do_insert (table, value);
229 hashtable_tokenize(struct hashtable *table, const char *string)
236 token = hashtable_lookup(table, string);
240 return hashtable_insert(table, string);