librazor/types.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 21:56:43 2008 -0400 (2008-06-20)
changeset 254 ccb1c11968ab
parent 241 c3eb520e2219
child 300 455eaa569767
permissions -rw-r--r--
Introduce install/remove iterators.

These iterator constructors lets you pass in two sets and creates
an iterator for the packages to remove or the packages to install.
The iterators will step through the packages in a sequence that respects
the pre, post, preun and postun modifiers.

Right now, the install order isn't actually implemented, this patch just
implements the API changes and updates the applications.
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
}