librazor/types.c
author Kristian H?gsberg <krh@redhat.com>
Sat Jun 28 20:34:29 2008 -0400 (2008-06-28)
changeset 299 d4f7f167b8bb
parent 241 c3eb520e2219
child 300 455eaa569767
permissions -rw-r--r--
Remove a couple of done TODO items.
rhughes@241
     1
#include <stdlib.h>
rhughes@241
     2
#include <string.h>
rhughes@241
     3
krh@248
     4
#include "razor-internal.h"
rhughes@241
     5
rhughes@241
     6
void
rhughes@241
     7
array_init(struct array *array)
rhughes@241
     8
{
rhughes@241
     9
	memset(array, 0, sizeof *array);
rhughes@241
    10
}
rhughes@241
    11
rhughes@241
    12
void
rhughes@241
    13
array_release(struct array *array)
rhughes@241
    14
{
rhughes@241
    15
	free(array->data);
rhughes@241
    16
}
rhughes@241
    17
rhughes@241
    18
void *
rhughes@241
    19
array_add(struct array *array, int size)
rhughes@241
    20
{
rhughes@241
    21
	int alloc;
rhughes@241
    22
	void *data, *p;
rhughes@241
    23
rhughes@241
    24
	if (array->alloc > 0)
rhughes@241
    25
		alloc = array->alloc;
rhughes@241
    26
	else
rhughes@241
    27
		alloc = 16;
rhughes@241
    28
rhughes@241
    29
	while (alloc < array->size + size)
rhughes@241
    30
		alloc *= 2;
rhughes@241
    31
rhughes@241
    32
	if (array->alloc < alloc) {
rhughes@241
    33
		data = realloc(array->data, alloc);
rhughes@241
    34
		if (data == NULL)
rhughes@241
    35
			return 0;
rhughes@241
    36
		array->data = data;
rhughes@241
    37
		array->alloc = alloc;
rhughes@241
    38
	}
rhughes@241
    39
rhughes@241
    40
	p = array->data + array->size;
rhughes@241
    41
	array->size += size;
rhughes@241
    42
rhughes@241
    43
	return p;
rhughes@241
    44
}
rhughes@241
    45
rhughes@241
    46
/* RAZOR_IMMEDIATE and RAZOR_ENTRY_LAST must have the same value */
rhughes@241
    47
#define RAZOR_ENTRY_LAST 0x80
rhughes@241
    48
#define RAZOR_IMMEDIATE  0x80
rhughes@241
    49
#define RAZOR_EMPTY_LIST 0xff
rhughes@241
    50
rhughes@241
    51
void
rhughes@241
    52
list_set_empty(struct list_head *head)
rhughes@241
    53
{
rhughes@241
    54
	head->list_ptr = ~0;
rhughes@241
    55
	head->flags = RAZOR_EMPTY_LIST;
rhughes@241
    56
}
rhughes@241
    57
rhughes@241
    58
void
rhughes@241
    59
list_set_ptr(struct list_head *head, uint32_t ptr)
rhughes@241
    60
{
rhughes@241
    61
	head->list_ptr = ptr;
rhughes@241
    62
	head->flags = 0;
rhughes@241
    63
}
rhughes@241
    64
rhughes@241
    65
void
rhughes@241
    66
list_set_array(struct list_head *head, struct array *pool,
rhughes@241
    67
	       struct array *items, int force_indirect)
rhughes@241
    68
{
rhughes@241
    69
	struct list *p;
rhughes@241
    70
rhughes@241
    71
	if (!force_indirect) {
rhughes@241
    72
		if (items->size == 0) {
rhughes@241
    73
			list_set_empty(head);
rhughes@241
    74
			return;
rhughes@241
    75
		} else if (items->size == sizeof (uint32_t)) {
rhughes@241
    76
			head->list_ptr = *(uint32_t *) items->data;
rhughes@241
    77
			head->flags = RAZOR_IMMEDIATE;
rhughes@241
    78
			return;
rhughes@241
    79
		}
rhughes@241
    80
	}
rhughes@241
    81
rhughes@241
    82
	p = array_add(pool, items->size);
rhughes@241
    83
	memcpy(p, items->data, items->size);
rhughes@241
    84
	p[items->size / sizeof *p - 1].flags = RAZOR_ENTRY_LAST;
rhughes@241
    85
	list_set_ptr(head, p - (struct list *) pool->data);
rhughes@241
    86
}
rhughes@241
    87
rhughes@241
    88
struct list *
rhughes@241
    89
list_first(struct list_head *head, struct array *pool)
rhughes@241
    90
{
rhughes@241
    91
	if (head->flags == RAZOR_EMPTY_LIST)
rhughes@241
    92
		return NULL;
rhughes@241
    93
	else if (head->flags == RAZOR_IMMEDIATE)
rhughes@241
    94
		return (struct list *) head;
rhughes@241
    95
	else
rhughes@241
    96
		return (struct list *) pool->data + head->list_ptr;
rhughes@241
    97
}
rhughes@241
    98
rhughes@241
    99
struct list *
rhughes@241
   100
list_next(struct list *list)
rhughes@241
   101
{
rhughes@241
   102
	if (list->flags)
rhughes@241
   103
		return NULL;
rhughes@241
   104
	return ++list;
rhughes@241
   105
}
rhughes@241
   106
rhughes@241
   107
void
rhughes@241
   108
list_remap_pool(struct array *pool, uint32_t *map)
rhughes@241
   109
{
rhughes@241
   110
	struct list *p, *end;
rhughes@241
   111
rhughes@241
   112
	end = pool->data + pool->size;
rhughes@241
   113
	for (p = pool->data; p < end; p++)
rhughes@241
   114
		p->data = map[p->data];
rhughes@241
   115
}
rhughes@241
   116
rhughes@241
   117
void
rhughes@241
   118
list_remap_head(struct list_head *head, uint32_t *map)
rhughes@241
   119
{
rhughes@241
   120
	if (head->flags == RAZOR_IMMEDIATE)
rhughes@241
   121
		head->list_ptr = map[head->list_ptr];
rhughes@241
   122
}
rhughes@241
   123
rhughes@241
   124
rhughes@241
   125
void
rhughes@241
   126
hashtable_init(struct hashtable *table, struct array *pool)
rhughes@241
   127
{
rhughes@241
   128
	array_init(&table->buckets);
rhughes@241
   129
	table->pool = pool;
rhughes@241
   130
}
rhughes@241
   131
rhughes@241
   132
void
rhughes@241
   133
hashtable_release(struct hashtable *table)
rhughes@241
   134
{
rhughes@241
   135
	array_release(&table->buckets);
rhughes@241
   136
}
rhughes@241
   137
rhughes@241
   138
static unsigned int
rhughes@241
   139
hash_string(const char *key)
rhughes@241
   140
{
rhughes@241
   141
	const char *p;
rhughes@241
   142
	unsigned int hash = 0;
rhughes@241
   143
rhughes@241
   144
	for (p = key; *p; p++)
rhughes@241
   145
		hash = (hash * 617) ^ *p;
rhughes@241
   146
rhughes@241
   147
	return hash;
rhughes@241
   148
}
rhughes@241
   149
rhughes@241
   150
uint32_t
rhughes@241
   151
hashtable_lookup(struct hashtable *table, const char *key)
rhughes@241
   152
{
rhughes@241
   153
	unsigned int mask, start, i;
rhughes@241
   154
	uint32_t *b;
rhughes@241
   155
	char *pool;
rhughes@241
   156
rhughes@241
   157
	pool = table->pool->data;
rhughes@241
   158
	mask = table->buckets.alloc - 1;
rhughes@241
   159
	start = hash_string(key) * sizeof(uint32_t);
rhughes@241
   160
rhughes@241
   161
	for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
rhughes@241
   162
		b = table->buckets.data + ((start + i) & mask);
rhughes@241
   163
rhughes@241
   164
		if (*b == 0)
rhughes@241
   165
			return 0;
rhughes@241
   166
rhughes@241
   167
		if (strcmp(key, &pool[*b]) == 0)
rhughes@241
   168
			return *b;
rhughes@241
   169
	}
rhughes@241
   170
rhughes@241
   171
	return 0;
rhughes@241
   172
}
rhughes@241
   173
rhughes@241
   174
static void
rhughes@241
   175
do_insert(struct hashtable *table, uint32_t value)
rhughes@241
   176
{
rhughes@241
   177
	unsigned int mask, start, i;
rhughes@241
   178
	uint32_t *b;
rhughes@241
   179
	const char *key;
rhughes@241
   180
rhughes@241
   181
	key = (char *) table->pool->data + value;
rhughes@241
   182
	mask = table->buckets.alloc - 1;
rhughes@241
   183
	start = hash_string(key) * sizeof(uint32_t);
rhughes@241
   184
rhughes@241
   185
	for (i = 0; i < table->buckets.alloc; i += sizeof *b) {
rhughes@241
   186
		b = table->buckets.data + ((start + i) & mask);
rhughes@241
   187
		if (*b == 0) {
rhughes@241
   188
			*b = value;
rhughes@241
   189
			break;
rhughes@241
   190
		}
rhughes@241
   191
	}
rhughes@241
   192
}
rhughes@241
   193
rhughes@241
   194
static uint32_t
rhughes@241
   195
add_to_string_pool(struct hashtable *table, const char *key)
rhughes@241
   196
{
rhughes@241
   197
	int len;
rhughes@241
   198
	char *p;
rhughes@241
   199
rhughes@241
   200
	len = strlen(key) + 1;
rhughes@241
   201
	p = array_add(table->pool, len);
rhughes@241
   202
	memcpy(p, key, len);
rhughes@241
   203
rhughes@241
   204
	return p - (char *) table->pool->data;
rhughes@241
   205
}
rhughes@241
   206
rhughes@241
   207
uint32_t
rhughes@241
   208
hashtable_insert(struct hashtable *table, const char *key)
rhughes@241
   209
{
rhughes@241
   210
	uint32_t value, *buckets, *b, *end;
rhughes@241
   211
	int alloc;
rhughes@241
   212
rhughes@241
   213
	alloc = table->buckets.alloc;
rhughes@241
   214
	array_add(&table->buckets, 4 * sizeof *buckets);
rhughes@241
   215
	if (alloc != table->buckets.alloc) {
rhughes@241
   216
		end = table->buckets.data + alloc;
rhughes@241
   217
		memset(end, 0, table->buckets.alloc - alloc);
rhughes@241
   218
		for (b = table->buckets.data; b < end; b++) {
rhughes@241
   219
			value = *b;
rhughes@241
   220
			if (value != 0) {
rhughes@241
   221
				*b = 0;
rhughes@241
   222
				do_insert(table, value);
rhughes@241
   223
			}
rhughes@241
   224
		}
rhughes@241
   225
	}
rhughes@241
   226
rhughes@241
   227
	value = add_to_string_pool(table, key);
rhughes@241
   228
	do_insert (table, value);
rhughes@241
   229
rhughes@241
   230
	return value;
rhughes@241
   231
}
rhughes@241
   232
rhughes@241
   233
uint32_t
rhughes@241
   234
hashtable_tokenize(struct hashtable *table, const char *string)
rhughes@241
   235
{
rhughes@241
   236
	uint32_t token;
rhughes@241
   237
rhughes@241
   238
	if (string == NULL)
rhughes@241
   239
		string = "";
rhughes@241
   240
rhughes@241
   241
	token = hashtable_lookup(table, string);
rhughes@241
   242
	if (token != 0)
rhughes@241
   243
		return token;
rhughes@241
   244
rhughes@241
   245
	return hashtable_insert(table, string);
rhughes@241
   246
}