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