return err;
}
-struct hashtable_header {
+static void *
+zalloc(size_t size)
+{
+ void *p;
+
+ p = malloc(size);
+ memset(p, 0, size);
+
+ return p;
+}
+
+struct razor_set_header {
unsigned int magic;
unsigned int version;
struct { unsigned int type, offset; } sections[0];
};
-#define HASHTABLE_MAGIC 0x7a7a7a7a
-#define HASHTABLE_VERSION 1
-#define HASHTABLE_BUCKETS 1
-#define HASHTABLE_STRINGS 2
-#define HASHTABLE_PACKAGES 3
+#define RAZOR_MAGIC 0x7a7a7a7a
+#define RAZOR_VERSION 1
+#define RAZOR_BUCKETS 1
+#define RAZOR_STRINGS 2
+#define RAZOR_PACKAGES 3
-struct package {
+struct razor_package {
unsigned long name;
unsigned long version;
};
-struct hashtable {
+struct razor_set {
unsigned long *buckets;
int bucket_count, bucket_alloc;
char *string_pool;
int pool_size, pool_alloc;
- struct hashtable_header *header;
+ struct razor_set_header *header;
- struct package *packages;
+ struct razor_package *packages;
int package_count, package_alloc;
};
-static void *
-zalloc(size_t size)
+struct razor_set *
+razor_set_create(void)
{
- void *p;
+ struct razor_set *set;
- p = malloc(size);
- memset(p, 0, size);
+ set = zalloc(sizeof *set);
+ set->buckets = zalloc(4096 * sizeof *set->buckets);
+ set->bucket_count = 0;
+ set->bucket_alloc = 4096;
- return p;
-}
-
-struct hashtable *
-hashtable_create(void)
-{
- struct hashtable *ht;
+ set->string_pool = zalloc(4096);
+ set->pool_size = 1;
+ set->pool_alloc = 4096;
- ht = zalloc(sizeof *ht);
- ht->buckets = zalloc(4096 * sizeof *ht->buckets);
- ht->bucket_count = 0;
- ht->bucket_alloc = 4096;
+ set->packages = zalloc(4096 * sizeof *set->packages);
+ set->package_count = 0;
+ set->package_alloc = 4096;
- ht->string_pool = zalloc(4096);
- ht->pool_size = 1;
- ht->pool_alloc = 4096;
-
- ht->packages = zalloc(4096 * sizeof *ht->packages);
- ht->package_count = 0;
- ht->package_alloc = 4096;
-
- return ht;
+ return set;
}
-struct hashtable *
-hashtable_create_from_file(const char *filename)
+struct razor_set *
+razor_set_open(const char *filename)
{
- struct hashtable *ht;
+ struct razor_set *set;
struct stat stat;
unsigned int size, offset;
int fd, i;
- ht = zalloc(sizeof *ht);
+ set = zalloc(sizeof *set);
fd = open(filename, O_RDONLY);
if (fstat(fd, &stat) < 0)
return NULL;
- ht->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
- if (ht->header == MAP_FAILED) {
- free(ht);
+ set->header = mmap(NULL, stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
+ if (set->header == MAP_FAILED) {
+ free(set);
return NULL;
}
- for (i = 0; i < ht->header->sections[i].type; i++) {
- offset = ht->header->sections[i].offset;
- size = ht->header->sections[i + 1].offset - offset;
+ for (i = 0; i < set->header->sections[i].type; i++) {
+ offset = set->header->sections[i].offset;
+ size = set->header->sections[i + 1].offset - offset;
- switch (ht->header->sections[i].type) {
- case HASHTABLE_BUCKETS:
- ht->buckets = (void *) ht->header + offset;
- ht->bucket_count = size / sizeof *ht->buckets;
- ht->bucket_alloc = ht->bucket_count;
+ switch (set->header->sections[i].type) {
+ case RAZOR_BUCKETS:
+ set->buckets = (void *) set->header + offset;
+ set->bucket_count = size / sizeof *set->buckets;
+ set->bucket_alloc = set->bucket_count;
break;
- case HASHTABLE_STRINGS:
- ht->string_pool = (void *) ht->header + offset;
- ht->pool_size = size;
- ht->pool_alloc = size;
+ case RAZOR_STRINGS:
+ set->string_pool = (void *) set->header + offset;
+ set->pool_size = size;
+ set->pool_alloc = size;
break;
- case HASHTABLE_PACKAGES:
- ht->packages = (void *) ht->header + offset;
- ht->package_count = size / sizeof *ht->packages;
- ht->package_alloc = size / sizeof *ht->packages;
+ case RAZOR_PACKAGES:
+ set->packages = (void *) set->header + offset;
+ set->package_count = size / sizeof *set->packages;
+ set->package_alloc = size / sizeof *set->packages;
break;
}
}
close(fd);
- return ht;
+ return set;
}
void
-hashtable_destroy(struct hashtable *ht)
+razor_set_destroy(struct razor_set *set)
{
unsigned int size;
int i;
- if (ht->header) {
- for (i = 0; ht->header->sections[i].type; i++)
+ if (set->header) {
+ for (i = 0; set->header->sections[i].type; i++)
;
- size = ht->header->sections[i].type;
- munmap(ht->header, size);
+ size = set->header->sections[i].type;
+ munmap(set->header, size);
} else {
- free(ht->buckets);
- free(ht->string_pool);
+ free(set->buckets);
+ free(set->string_pool);
}
- free(ht);
+ free(set);
}
static int
-hashtable_write(struct hashtable *ht, const char *filename)
+razor_set_write(struct razor_set *set, const char *filename)
{
char data[4096];
- struct hashtable_header *header = (struct hashtable_header *) data;
+ struct razor_set_header *header = (struct razor_set_header *) data;
int fd, pool_size, package_size;
/* Align these to pages sizes */
- pool_size = (ht->pool_size + 4095) & ~4095;
+ pool_size = (set->pool_size + 4095) & ~4095;
package_size =
- (ht->package_alloc * sizeof *ht->packages + 4095) & ~4095;
+ (set->package_alloc * sizeof *set->packages + 4095) & ~4095;
memset(data, 0, sizeof data);
- header->magic = HASHTABLE_MAGIC;
- header->version = HASHTABLE_VERSION;
+ header->magic = RAZOR_MAGIC;
+ header->version = RAZOR_VERSION;
- header->sections[0].type = HASHTABLE_BUCKETS;
+ header->sections[0].type = RAZOR_BUCKETS;
header->sections[0].offset = sizeof data;
- header->sections[1].type = HASHTABLE_STRINGS;
+ header->sections[1].type = RAZOR_STRINGS;
header->sections[1].offset = header->sections[0].offset +
- ht->bucket_alloc * sizeof *ht->buckets;
+ set->bucket_alloc * sizeof *set->buckets;
- header->sections[2].type = HASHTABLE_PACKAGES;
+ header->sections[2].type = RAZOR_PACKAGES;
header->sections[2].offset = header->sections[1].offset + pool_size;
header->sections[3].type = 0;
return -1;
write_to_fd(fd, data, sizeof data);
- write_to_fd(fd, ht->buckets, ht->bucket_alloc * sizeof *ht->buckets);
- write_to_fd(fd, ht->string_pool, pool_size);
- write_to_fd(fd, ht->packages, package_size);
+ write_to_fd(fd, set->buckets, set->bucket_alloc * sizeof *set->buckets);
+ write_to_fd(fd, set->string_pool, pool_size);
+ write_to_fd(fd, set->packages, package_size);
return 0;
}
}
unsigned long
-hashtable_lookup(struct hashtable *ht, const char *key)
+razor_set_lookup(struct razor_set *set, const char *key)
{
unsigned int start;
unsigned int mask;
unsigned long value;
int i;
- mask = ht->bucket_alloc - 1;
+ mask = set->bucket_alloc - 1;
start = hash_string(key) & mask;
i = start;
do {
- value = ht->buckets[i];
+ value = set->buckets[i];
if (value == 0)
return 0;
- if (strcmp(key, &ht->string_pool[value]) == 0)
+ if (strcmp(key, &set->string_pool[value]) == 0)
return value;
i = (i + 1) & mask;
}
static unsigned long
-add_to_string_pool(struct hashtable *ht, const char *key)
+add_to_string_pool(struct razor_set *set, const char *key)
{
int len, alloc;
char *pool;
unsigned long value;
len = strlen(key) + 1;
- alloc = ht->pool_alloc;
- while (alloc < ht->pool_size + len)
+ alloc = set->pool_alloc;
+ while (alloc < set->pool_size + len)
alloc *= 2;
- if (ht->pool_alloc < alloc) {
- pool = realloc(ht->string_pool, alloc);
+ if (set->pool_alloc < alloc) {
+ pool = realloc(set->string_pool, alloc);
if (pool == NULL)
return 0;
- ht->string_pool = pool;
- ht->pool_alloc = alloc;
+ set->string_pool = pool;
+ set->pool_alloc = alloc;
}
- memcpy(ht->string_pool + ht->pool_size, key, len);
- value = ht->pool_size;
- ht->pool_size += len;
+ memcpy(set->string_pool + set->pool_size, key, len);
+ value = set->pool_size;
+ set->pool_size += len;
return value;
}
static void
-do_insert(struct hashtable *ht, unsigned long value)
+do_insert(struct razor_set *set, unsigned long value)
{
unsigned int mask;
const char *key;
int i, start;
- key = &ht->string_pool[value];
- mask = ht->bucket_alloc - 1;
+ key = &set->string_pool[value];
+ mask = set->bucket_alloc - 1;
start = hash_string(key) & mask;
i = start;
do {
- if (ht->buckets[i] == 0) {
- ht->buckets[i] = value;
+ if (set->buckets[i] == 0) {
+ set->buckets[i] = value;
break;
}
i = (i + 1) & mask;
}
unsigned long
-hashtable_insert(struct hashtable *ht, const char *key)
+razor_set_insert(struct razor_set *set, const char *key)
{
unsigned long value, *buckets, *old_buckets;
int i, alloc, old_alloc;
- alloc = ht->bucket_alloc;
- while (alloc < 4 * ht->bucket_count)
+ alloc = set->bucket_alloc;
+ while (alloc < 4 * set->bucket_count)
alloc *= 2;
- if (alloc != ht->bucket_alloc) {
- buckets = zalloc(alloc * sizeof *ht->buckets);
+ if (alloc != set->bucket_alloc) {
+ buckets = zalloc(alloc * sizeof *set->buckets);
if (buckets == NULL)
return 0;
- old_buckets = ht->buckets;
- ht->buckets = buckets;
- old_alloc = ht->bucket_alloc;
- ht->bucket_alloc = alloc;
+ old_buckets = set->buckets;
+ set->buckets = buckets;
+ old_alloc = set->bucket_alloc;
+ set->bucket_alloc = alloc;
for (i = 0; i < old_alloc; i++) {
value = old_buckets[i];
if (value != 0)
- do_insert(ht, value);
+ do_insert(set, value);
}
free(old_buckets);
}
- value = add_to_string_pool(ht, key);
- do_insert (ht, value);
- ht->bucket_count++;
+ value = add_to_string_pool(set, key);
+ do_insert (set, value);
+ set->bucket_count++;
return value;
}
static unsigned long
-hashtable_add_package(struct hashtable *ht,
+razor_set_add_package(struct razor_set *set,
unsigned long name, unsigned long version)
{
- struct package *packages;
+ struct razor_package *packages;
int alloc;
- alloc = ht->package_alloc;
- while (alloc < ht->package_count + 1)
+ /* FIXME: make 0 an illegal pkgs number. */
+ alloc = set->package_alloc;
+ while (alloc < set->package_count + 1)
alloc *= 2;
- if (ht->package_alloc < alloc) {
- packages = realloc(ht->packages, alloc * sizeof ht->packages);
+ if (set->package_alloc < alloc) {
+ packages = realloc(set->packages, alloc * sizeof set->packages);
if (packages == NULL)
return 0;
- ht->packages = packages;
- ht->package_alloc = alloc;
+ set->packages = packages;
+ set->package_alloc = alloc;
}
- ht->packages[ht->package_count].name = name;
- ht->packages[ht->package_count].version = version;
- ht->package_count++;
-
- return 0;
-}
-
+ set->packages[set->package_count].name = name;
+ set->packages[set->package_count].version = version;
-struct razor_context {
- struct hashtable *global_ht;
-};
-
-struct razor_context *
-razor_context_create (void)
-{
- struct razor_context *ctx;
-
- ctx = malloc(sizeof *ctx);
- ctx->global_ht = hashtable_create();
-
- return ctx;
-}
-
-struct razor_context *
-razor_context_create_from_file (const char *filename)
-{
- struct razor_context *ctx;
-
- ctx = malloc(sizeof *ctx);
- ctx->global_ht = hashtable_create_from_file(filename);
-
- return ctx;
+ return set->package_count++;
}
unsigned long
-razor_context_tokenize(struct razor_context *ctx, const char *string)
+razor_set_tokenize(struct razor_set *set, const char *string)
{
unsigned long token;
- token = hashtable_lookup(ctx->global_ht, string);
+ token = razor_set_lookup(set, string);
if (token != 0)
return token;
- return hashtable_insert(ctx->global_ht, string);
+ return razor_set_insert(set, string);
}
-static struct hashtable *qsort_ht;
+static struct razor_set *qsort_set;
static int
compare_packages(const void *p1, const void *p2)
{
- const struct package *pkg1 = p1, *pkg2 = p2;
+ const struct razor_package *pkg1 = p1, *pkg2 = p2;
- return strcmp(&qsort_ht->string_pool[pkg1->name],
- &qsort_ht->string_pool[pkg2->name]);
+ return strcmp(&qsort_set->string_pool[pkg1->name],
+ &qsort_set->string_pool[pkg2->name]);
}
static void
-razor_context_sort(struct razor_context *ctx)
+razor_set_sort(struct razor_set *set)
{
- struct hashtable *ht = ctx->global_ht;
-
- qsort_ht = ht;
- qsort(ht->packages, ht->package_count, sizeof *ht->packages,
+ qsort_set = set;
+ qsort(set->packages, set->package_count, sizeof *set->packages,
compare_packages);
}
-struct razor_set {
- struct razor_context *ctx;
-};
-
struct parsing_context {
- struct razor_context *ctx;
+ struct razor_set *set;
+ int pkg_id;
};
static void
for (i = 0; atts[i]; i += 2) {
if (strcmp(atts[i], "name") == 0)
- name = razor_context_tokenize(ctx->ctx, atts[i + 1]);
+ name = razor_set_tokenize(ctx->set, atts[i + 1]);
else if (strcmp(atts[i], "version") == 0)
- version = razor_context_tokenize(ctx->ctx, atts[i + 1]);
+ version = razor_set_tokenize(ctx->set, atts[i + 1]);
}
if (name == 0 || version == 0) {
return;
}
- hashtable_add_package(ctx->ctx->global_ht, name, version);
+ ctx->pkg_id = razor_set_add_package(ctx->set, name, version);
+
+ return;
}
static void
parse_package(ctx, atts);
for (i = 0; atts[i]; i += 2)
- razor_context_tokenize(ctx->ctx, atts[i + 1]);
+ razor_set_tokenize(ctx->set, atts[i + 1]);
}
static void
end_element (void *data, const char *name)
{
+ struct parsing_context *ctx = data;
+
+ if (strcmp(name, "package") == 0)
+ ctx->pkg_id = 0;
}
static char *
}
static int
-razor_context_read_file(struct razor_context *ctx, const char *filename)
+razor_set_import(struct razor_set *set, const char *filename)
{
SHA_CTX sha1;
XML_Parser parser;
- struct parsing_context pctx;
+ struct parsing_context ctx;
int fd;
void *p;
struct stat stat;
return -1;
parser = XML_ParserCreate(NULL);
- pctx.ctx = ctx;
- XML_SetUserData(parser, &pctx);
+ ctx.set = set;
+ XML_SetUserData(parser, &ctx);
XML_SetElementHandler(parser, start_element, end_element);
if (XML_Parse(parser, p, stat.st_size, 1) == XML_STATUS_ERROR) {
fprintf(stderr,
return 0;
}
-int
-razor_context_write(struct razor_context *ctx, const char *filename)
-{
- return hashtable_write(ctx->global_ht, filename);
-}
-
void
-razor_context_list_packages(struct razor_context *ctx)
+razor_set_list(struct razor_set *set)
{
int i;
- struct hashtable *ht = ctx->global_ht;
- struct package *p;
+ struct razor_package *p;
- p = ht->packages;
- for (i = 0; i < ht->package_count && p->name; i++, p++) {
+ p = set->packages;
+ for (i = 0; i < set->package_count && p->name; i++, p++) {
printf("%s %s\n",
- &ht->string_pool[p->name],
- &ht->string_pool[p->version]);
+ &set->string_pool[p->name],
+ &set->string_pool[p->version]);
}
}
void
-razor_context_info(struct razor_context *ctx)
+razor_set_info(struct razor_set *set)
{
- struct hashtable *ht = ctx->global_ht;
unsigned int offset, size;
int i;
- for (i = 0; i < ht->header->sections[i].type; i++) {
- offset = ht->header->sections[i].offset;
- size = ht->header->sections[i + 1].offset - offset;
+ for (i = 0; i < set->header->sections[i].type; i++) {
+ offset = set->header->sections[i].offset;
+ size = set->header->sections[i + 1].offset - offset;
- switch (ht->header->sections[i].type) {
- case HASHTABLE_BUCKETS:
+ switch (set->header->sections[i].type) {
+ case RAZOR_BUCKETS:
printf("bucket section:\t\t%dkb\n", size / 1024);
break;
- case HASHTABLE_STRINGS:
+ case RAZOR_STRINGS:
printf("string pool:\t\t%dkb\n", size / 1024);
break;
- case HASHTABLE_PACKAGES:
+ case RAZOR_PACKAGES:
printf("package section:\t%dkb\n", size / 1024);
break;
}
}
-
-}
-
-void
-razor_context_destroy(struct razor_context *ctx)
-{
- hashtable_destroy(ctx->global_ht);
- free(ctx);
}
static int
main(int argc, char *argv[])
{
int i;
- struct razor_context *ctx;
+ struct razor_set *set;
struct stat statbuf;
if (argc < 2) {
exit(-1);
}
- ctx = razor_context_create();
+ set = razor_set_create();
for (i = 2; i < argc; i++) {
- if (razor_context_read_file(ctx, argv[i]) < 0) {
+ if (razor_set_import(set, argv[i]) < 0) {
fprintf(stderr, "failed to import %s\n",
argv[i]);
exit(-1);
}
}
- razor_context_sort(ctx);
+ razor_set_sort(set);
printf("number of buckets: %d\n",
- ctx->global_ht->bucket_count);
+ set->bucket_count);
printf("bucket allocation: %d\n",
- ctx->global_ht->bucket_alloc);
- printf("pool size: %d\n", ctx->global_ht->pool_size);
- printf("pool allocation: %d\n", ctx->global_ht->pool_alloc);
+ set->bucket_alloc);
+ printf("pool size: %d\n", set->pool_size);
+ printf("pool allocation: %d\n", set->pool_alloc);
- razor_context_write(ctx, repo_filename);
+ razor_set_write(set, repo_filename);
- razor_context_destroy(ctx);
+ razor_set_destroy(set);
} else if (strcmp(argv[1], "lookup") == 0) {
- ctx = razor_context_create_from_file(repo_filename);
+ set = razor_set_open(repo_filename);
printf("%s is %lu\n", argv[2],
- hashtable_lookup(ctx->global_ht, argv[2]));
- razor_context_destroy(ctx);
+ razor_set_lookup(set, argv[2]));
+ razor_set_destroy(set);
} else if (strcmp(argv[1], "list") == 0) {
- ctx = razor_context_create_from_file(repo_filename);
- razor_context_list_packages(ctx);
- razor_context_destroy(ctx);
+ set = razor_set_open(repo_filename);
+ razor_set_list(set);
+ razor_set_destroy(set);
} else if (strcmp(argv[1], "info") == 0) {
- ctx = razor_context_create_from_file(repo_filename);
- razor_context_info(ctx);
- razor_context_destroy(ctx);
+ set = razor_set_open(repo_filename);
+ razor_set_info(set);
+ razor_set_destroy(set);
} else {
usage();
}