Use the file string pool when merging directories.
2 * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3 * Copyright (C) 2008 Red Hat, Inc
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
23 #include "razor-internal.h"
26 array_init(struct array *array)
28 memset(array, 0, sizeof *array);
32 array_release(struct array *array)
38 array_add(struct array *array, int size)
48 while (alloc < array->size + size)
51 if (array->alloc < alloc) {
52 data = realloc(array->data, alloc);
59 p = array->data + array->size;
65 /* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
66 #define RAZOR_ENTRY_LAST 0x80
67 #define RAZOR_IMMEDIATE 0x80
68 #define RAZOR_EMPTY_LIST 0xff
71 list_set_empty(struct list_head *head)
74 head->flags = RAZOR_EMPTY_LIST;
78 list_set_ptr(struct list_head *head, uint32_t ptr)
85 list_set_array(struct list_head *head, struct array *pool,
86 struct array *items, int force_indirect)
90 if (!force_indirect) {
91 if (items->size == 0) {
94 } else if (items->size == sizeof (uint32_t)) {
95 head->list_ptr = *(uint32_t *) items->data;
96 head->flags = RAZOR_IMMEDIATE;
101 p = array_add(pool, items->size);
102 memcpy(p, items->data, items->size);
103 p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
104 list_set_ptr(head, p - (struct list *) pool->data);
108 list_first(struct list_head *head, struct array *pool)
110 if (head->flags == RAZOR_EMPTY_LIST)
112 else if (head->flags == RAZOR_IMMEDIATE)
113 return (struct list *) head;
115 return (struct list *) pool->data + head->list_ptr;
119 list_next(struct list *list)
127 list_remap_pool(struct array *pool, uint32_t *map)
129 struct list *p, *end;
131 end = pool->data + pool->size;
132 for (p = pool->data; p < end; p++)
133 p->data = map[p->data];
137 list_remap_head(struct list_head *head, uint32_t *map)
139 if (head->flags == RAZOR_IMMEDIATE)
140 head->list_ptr = map[head->list_ptr];
145 hashtable_init(struct hashtable *table, struct array *pool)
147 array_init(&table->buckets);
152 hashtable_release(struct hashtable *table)
154 array_release(&table->buckets);
158 hash_string(const char *key)
161 unsigned int hash = 0;
163 for (p = key; *p; p++)
164 hash = (hash * 617) ^ *p;
170 hashtable_lookup(struct hashtable *table, const char *key)
172 unsigned int mask, start, i;
176 pool = table->pool->data;
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);
186 if (strcmp(key, &pool[*b]) == 0)
194 do_insert(struct hashtable *table, uint32_t value)
196 unsigned int mask, start, i;
200 key = (char *) table->pool->data + value;
201 mask = table->buckets.alloc - 1;
202 start = hash_string(key) * sizeof(uint32_t);
204 for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
205 b = table->buckets.data + ((start + i) & mask);
214 add_to_string_pool(struct hashtable *table, const char *key)
219 len = strlen(key) + 1;
220 p = array_add(table->pool, len);
223 return p - (char *) table->pool->data;
227 hashtable_insert(struct hashtable *table, const char *key)
229 uint32_t value, *buckets, *b, *end;
232 alloc = table->buckets.alloc;
233 array_add(&table->buckets, 4 * sizeof *buckets);
234 if (alloc != table->buckets.alloc) {
235 end = table->buckets.data + alloc;
236 memset(end, 0, table->buckets.alloc - alloc);
237 for (b = table->buckets.data; b < end; b++) {
241 do_insert(table, value);
246 value = add_to_string_pool(table, key);
247 do_insert (table, value);
253 hashtable_tokenize(struct hashtable *table, const char *string)
260 token = hashtable_lookup(table, string);
264 return hashtable_insert(table, string);