From: Kristian Høgsberg Date: Thu, 1 Nov 2007 02:41:27 +0000 (-0400) Subject: Store requires and provides in the same list. X-Git-Tag: 0.1~294 X-Git-Url: http://project.juiblex.co.uk/git/?a=commitdiff_plain;h=2c05e4490bf9a3cde6129cb074eebbb0be904030;p=razor.git Store requires and provides in the same list. --- diff --git a/TODO b/TODO index 55be233..0db625e 100644 --- a/TODO +++ b/TODO @@ -20,6 +20,8 @@ Towards replacing rpm + yum (0.1): Misc ideas: +- eliminate duplicate entries in package property lists. + - keep history of installed packages/journal of package transaction, so we can roll back to yesterday, or see what got installed in the latest yum update. diff --git a/import.c b/import.c index d8a720f..0d8d682 100644 --- a/import.c +++ b/import.c @@ -60,10 +60,12 @@ parse_property(struct razor_importer *importer, const char **atts, void *data) switch ((int) data) { case RZR_REQUIRES: - razor_importer_add_requires(importer, name, version); + razor_importer_add_property(importer, name, version, + RAZOR_PROPERTY_REQUIRES); break; case RZR_PROVIDES: - razor_importer_add_provides(importer, name, version); + razor_importer_add_property(importer, name, version, + RAZOR_PROPERTY_PROVIDES); break; } } @@ -229,10 +231,12 @@ yum_start_element(void *data, const char *name, const char **atts) switch (ctx->state) { case YUM_STATE_REQUIRES: - razor_importer_add_requires(ctx->importer, n, buffer); + razor_importer_add_property(ctx->importer, n, buffer, + RAZOR_PROPERTY_REQUIRES); break; case YUM_STATE_PROVIDES: - razor_importer_add_provides(ctx->importer, n, buffer); + razor_importer_add_property(ctx->importer, n, buffer, + RAZOR_PROPERTY_PROVIDES); break; } } else if (strcmp(name, "file") == 0) { @@ -352,18 +356,20 @@ razor_set_create_from_rpmdb(void) headerGetEntry(h, RPMTAG_REQUIREFLAGS, &type, &property_flags.p, &count); for (i = 0; i < count; i++) - razor_importer_add_requires(importer, + razor_importer_add_property(importer, property_names.list[i], - property_versions.list[i]); + property_versions.list[i], + RAZOR_PROPERTY_REQUIRES); headerGetEntry(h, RPMTAG_PROVIDENAME, &type, &property_names.p, &count); headerGetEntry(h, RPMTAG_PROVIDEVERSION, &type, &property_versions.p, &count); for (i = 0; i < count; i++) - razor_importer_add_provides(importer, + razor_importer_add_property(importer, property_names.list[i], - property_versions.list[i]); + property_versions.list[i], + RAZOR_PROPERTY_PROVIDES); headerGetEntry(h, RPMTAG_BASENAMES, &type, &basenames.p, &count); diff --git a/main.c b/main.c index 48db52e..f29e302 100644 --- a/main.c +++ b/main.c @@ -28,7 +28,7 @@ command_list_requires(int argc, const char *argv[]) struct razor_set *set; set = razor_set_open(repo_filename); - razor_set_list_requires(set, argv[0]); + razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_REQUIRES); razor_set_destroy(set); return 0; @@ -40,7 +40,7 @@ command_list_provides(int argc, const char *argv[]) struct razor_set *set; set = razor_set_open(repo_filename); - razor_set_list_provides(set, argv[0]); + razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_PROVIDES); razor_set_destroy(set); return 0; @@ -94,7 +94,8 @@ command_what_requires(int argc, const char *argv[]) struct razor_set *set; set = razor_set_open(repo_filename); - razor_set_list_requires_packages(set, argv[0], argv[1]); + razor_set_list_property_packages(set, argv[0], argv[1], + RAZOR_PROPERTY_REQUIRES); razor_set_destroy(set); return 0; @@ -106,7 +107,8 @@ command_what_provides(int argc, const char *argv[]) struct razor_set *set; set = razor_set_open(repo_filename); - razor_set_list_provides_packages(set, argv[0], argv[1]); + razor_set_list_property_packages(set, argv[0], argv[1], + RAZOR_PROPERTY_PROVIDES); razor_set_destroy(set); return 0; diff --git a/razor.c b/razor.c index e0b452d..d7e7b46 100644 --- a/razor.c +++ b/razor.c @@ -39,21 +39,18 @@ struct razor_set_header { #define RAZOR_IMMEDIATE 0x80000000ul #define RAZOR_ENTRY_MASK 0x00fffffful -#define RAZOR_STRING_POOL 0 -#define RAZOR_PACKAGES 1 -#define RAZOR_REQUIRES 2 -#define RAZOR_PROVIDES 3 -#define RAZOR_FILES 4 -#define RAZOR_PACKAGE_POOL 5 -#define RAZOR_REQUIRES_POOL 6 -#define RAZOR_PROVIDES_POOL 7 -#define RAZOR_FILE_POOL 8 +#define RAZOR_STRING_POOL 0 +#define RAZOR_PACKAGES 1 +#define RAZOR_PROPERTIES 2 +#define RAZOR_FILES 3 +#define RAZOR_PACKAGE_POOL 4 +#define RAZOR_PROPERTY_POOL 5 +#define RAZOR_FILE_POOL 6 struct razor_package { unsigned long name; unsigned long version; - unsigned long requires; - unsigned long provides; + unsigned long properties; unsigned long files; }; @@ -72,12 +69,10 @@ struct razor_entry { struct razor_set { struct array string_pool; struct array packages; - struct array requires; - struct array provides; + struct array properties; struct array files; struct array package_pool; - struct array requires_pool; - struct array provides_pool; + struct array property_pool; struct array file_pool; struct razor_set_header *header; }; @@ -94,17 +89,11 @@ struct import_directory { struct import_directory *last; }; -struct import_property_context { - struct array *all; - struct array package; -}; - struct razor_importer { struct razor_set *set; struct array buckets; - struct import_property_context requires; - struct import_property_context provides; struct razor_package *package; + struct array properties; struct array files; }; @@ -178,12 +167,10 @@ zalloc(size_t size) struct razor_set_section razor_sections[] = { { RAZOR_STRING_POOL, offsetof(struct razor_set, string_pool) }, { RAZOR_PACKAGES, offsetof(struct razor_set, packages) }, - { RAZOR_REQUIRES, offsetof(struct razor_set, requires) }, - { RAZOR_PROVIDES, offsetof(struct razor_set, provides) }, + { RAZOR_PROPERTIES, offsetof(struct razor_set, properties) }, { RAZOR_FILES, offsetof(struct razor_set, files) }, { RAZOR_PACKAGE_POOL, offsetof(struct razor_set, package_pool) }, - { RAZOR_REQUIRES_POOL, offsetof(struct razor_set, requires_pool) }, - { RAZOR_PROVIDES_POOL, offsetof(struct razor_set, provides_pool) }, + { RAZOR_PROPERTY_POOL, offsetof(struct razor_set, property_pool) }, { RAZOR_FILE_POOL, offsetof(struct razor_set, file_pool) }, }; @@ -427,8 +414,7 @@ razor_importer_begin_package(struct razor_importer *importer, p->version = razor_importer_tokenize(importer, version); importer->package = p; - array_init(&importer->requires.package); - array_init(&importer->provides.package); + array_init(&importer->properties); } void @@ -437,47 +423,28 @@ razor_importer_finish_package(struct razor_importer *importer) struct razor_package *p; p = importer->package; - p->requires = add_to_property_pool(&importer->set->requires_pool, - &importer->requires.package); - p->provides = add_to_property_pool(&importer->set->provides_pool, - &importer->provides.package); + p->properties = add_to_property_pool(&importer->set->property_pool, + &importer->properties); - array_release(&importer->requires.package); - array_release(&importer->provides.package); + array_release(&importer->properties); } -static void +void razor_importer_add_property(struct razor_importer *importer, - struct import_property_context *pctx, - const char *name, const char *version) + const char *name, const char *version, + enum razor_property_type type) { struct razor_property *p; unsigned long *r; - p = array_add(pctx->all, sizeof *p); - p->name = razor_importer_tokenize(importer, name); + p = array_add(&importer->set->properties, sizeof *p); + p->name = razor_importer_tokenize(importer, name) | (type << 30); p->version = razor_importer_tokenize(importer, version); p->packages = importer->package - (struct razor_package *) importer->set->packages.data; - r = array_add(&pctx->package, sizeof *r); - *r = p - (struct razor_property *) pctx->all->data; -} - -void -razor_importer_add_requires(struct razor_importer *importer, - const char *name, const char *version) -{ - razor_importer_add_property(importer, - &importer->requires, name, version); -} - -void -razor_importer_add_provides(struct razor_importer *importer, - const char *name, const char *version) -{ - razor_importer_add_property(importer, - &importer->provides, name, version); + r = array_add(&importer->properties, sizeof *r); + *r = p - (struct razor_property *) importer->set->properties.data; } void @@ -499,8 +466,6 @@ razor_importer_new(void) importer = zalloc(sizeof *importer); importer->set = razor_set_create(); - importer->requires.all = &importer->set->requires; - importer->provides.all = &importer->set->provides; return importer; } @@ -658,37 +623,41 @@ compare_properties(const void *p1, const void *p2, void *data) char *pool = set->string_pool.data; if (prop1->name == prop2->name) - return versioncmp(&pool[prop1->version], &pool[prop2->version]); + return versioncmp(&pool[prop1->version], + &pool[prop2->version]); + else if ((prop1->name & RAZOR_ENTRY_MASK) == (prop2->name & RAZOR_ENTRY_MASK)) + return (prop1->name >> 30) - (prop2->name >> 30); else - return strcmp(&pool[prop1->name], &pool[prop2->name]); + return strcmp(&pool[prop1->name & RAZOR_ENTRY_MASK], + &pool[prop2->name & RAZOR_ENTRY_MASK]); } static unsigned long * -uniqueify_properties(struct razor_set *set, struct array *properties) +uniqueify_properties(struct razor_set *set) { struct razor_property *rp, *up, *rp_end; struct array *pkgs, *p; unsigned long *map, *rmap, *r; int i, count, unique; - count = properties->size / sizeof(struct razor_property); - map = qsort_with_data(properties->data, + count = set->properties.size / sizeof(struct razor_property); + map = qsort_with_data(set->properties.data, count, sizeof(struct razor_property), compare_properties, set); - rp_end = properties->data + properties->size; + rp_end = set->properties.data + set->properties.size; rmap = malloc(count * sizeof *map); pkgs = zalloc(count * sizeof *pkgs); - for (rp = properties->data, up = rp, i = 0; rp < rp_end; rp++, i++) { + for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) { if (rp->name != up->name || rp->version != up->version) { up++; up->name = rp->name; up->version = rp->version; } - unique = up - (struct razor_property *) properties->data; + unique = up - (struct razor_property *) set->properties.data; rmap[map[i]] = unique; r = array_add(&pkgs[unique], sizeof *r); *r = rp->packages; @@ -696,9 +665,9 @@ uniqueify_properties(struct razor_set *set, struct array *properties) free(map); up++; - properties->size = (void *) up - properties->data; + set->properties.size = (void *) up - set->properties.data; rp_end = up; - for (rp = properties->data, p = pkgs; rp < rp_end; rp++, p++) { + for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) { if (p->size / sizeof *r == 1) { r = p->data; rp->packages = *r | RAZOR_IMMEDIATE; @@ -920,12 +889,8 @@ razor_importer_finish(struct razor_importer *importer) unsigned long *map, *rmap; int i, count; - map = uniqueify_properties(importer->set, &importer->set->requires); - remap_links(&importer->set->requires_pool, map); - free(map); - - map = uniqueify_properties(importer->set, &importer->set->provides); - remap_links(&importer->set->provides_pool, map); + map = uniqueify_properties(importer->set); + remap_links(&importer->set->property_pool, map); free(map); count = importer->set->packages.size / sizeof(struct razor_package); @@ -943,8 +908,7 @@ razor_importer_finish(struct razor_importer *importer) build_file_tree(importer); remap_links(&importer->set->package_pool, rmap); build_package_file_lists(importer->set, rmap); - remap_property_package_links(&importer->set->requires, rmap); - remap_property_package_links(&importer->set->provides, rmap); + remap_property_package_links(&importer->set->properties, rmap); free(rmap); set = importer->set; @@ -1003,93 +967,80 @@ compare_property_name(const void *key, const void *data) pool = bsearch_set->string_pool.data; - return strcmp(key, &pool[p->name]); + return strcmp(key, &pool[p->name & RAZOR_ENTRY_MASK]); } struct razor_property * -razor_set_get_property(struct razor_set *set, - struct array *properties, - const char *property) +razor_set_get_property(struct razor_set *set, const char *property) { struct razor_property *p, *start; bsearch_set = set; - p = bsearch(property, properties->data, - properties->size / sizeof(struct razor_property), + p = bsearch(property, set->properties.data, + set->properties.size / sizeof(struct razor_property), sizeof(struct razor_property), compare_property_name); - start = properties->data; - while (p > start && (p - 1)->name == p->name) + start = set->properties.data; + while (p > start && + ((p - 1)->name & RAZOR_ENTRY_MASK) == + (p->name & RAZOR_ENTRY_MASK)) p--; return p; } -static void -razor_set_list_all_properties(struct razor_set *set, struct array *properties) -{ - struct razor_property *p, *end; - char *pool; - - pool = set->string_pool.data; - end = properties->data + properties->size; - for (p = properties->data; p < end; p++) - printf("%s-%s\n", &pool[p->name], &pool[p->version]); -} - void -razor_set_list_requires(struct razor_set *set, const char *name) +razor_set_list_properties(struct razor_set *set, const char *name, + enum razor_property_type type) { - struct razor_property *p, *requires; + struct razor_property *p, *properties, *end; struct razor_package *package; unsigned long *r; char *pool; - if (name) { - package = razor_set_get_package(set, name); - r = (unsigned long *) set->requires_pool.data + - package->requires; - requires = set->requires.data; - pool = set->string_pool.data; - while (1) { - p = &requires[*r & RAZOR_ENTRY_MASK]; - printf("%s-%s\n", &pool[p->name], &pool[p->version]); - if (*r++ & RAZOR_IMMEDIATE) - break; - } - } else - razor_set_list_all_properties(set, &set->requires); -} - -void -razor_set_list_provides(struct razor_set *set, const char *name) -{ - struct razor_property *p, *provides; - struct razor_package *package; - unsigned long *r; - char *pool; + pool = set->string_pool.data; if (name) { package = razor_set_get_package(set, name); - r = (unsigned long *) set->provides_pool.data + - package->provides; - provides = set->provides.data; - pool = set->string_pool.data; + r = (unsigned long *) set->property_pool.data + + package->properties; + properties = set->properties.data; while (1) { - p = &provides[*r & RAZOR_ENTRY_MASK]; - printf("%s-%s\n", &pool[p->name], &pool[p->version]); + p = &properties[*r & RAZOR_ENTRY_MASK]; + if ((p->name >> 30) != type) + goto next; + if (pool[p->version] == '\0') + printf("%s\n", + &pool[p->name & RAZOR_ENTRY_MASK]); + else + printf("%s-%s\n", + &pool[p->name & RAZOR_ENTRY_MASK], + &pool[p->version]); + next: if (*r++ & RAZOR_IMMEDIATE) break; } - } else - razor_set_list_all_properties(set, &set->provides); + } else { + end = set->properties.data + set->properties.size; + for (p = set->properties.data; p < end; p++) { + if ((p->name >> 30) != type) + continue; + if (pool[p->version] == '\0') + printf("%s\n", + &pool[p->name & RAZOR_ENTRY_MASK]); + else + printf("%s-%s\n", + &pool[p->name & RAZOR_ENTRY_MASK], + &pool[p->version]); + } + } } -static void +void razor_set_list_property_packages(struct razor_set *set, - struct array *properties, const char *name, - const char *version) + const char *version, + enum razor_property_type type) { struct razor_property *property, *end; struct razor_package *p, *packages; @@ -1099,12 +1050,16 @@ razor_set_list_property_packages(struct razor_set *set, if (name == NULL) return; - property = razor_set_get_property(set, properties, name); + property = razor_set_get_property(set, name); packages = set->packages.data; pool = set->string_pool.data; - end = properties->data + properties->size; - while (property < end && strcmp(name, &pool[property->name]) == 0) { - if (version && versioncmp(version, &pool[property->version]) != 0) + end = set->properties.data + set->properties.size; + while (property < end && + strcmp(name, &pool[property->name & RAZOR_ENTRY_MASK]) == 0) { + if (version && + versioncmp(version, &pool[property->version]) != 0) + goto next; + if (type != (property->name >> 30)) goto next; if (property->packages & RAZOR_IMMEDIATE) @@ -1114,7 +1069,9 @@ razor_set_list_property_packages(struct razor_set *set, set->package_pool.data + property->packages; while (1) { p = &packages[*r & RAZOR_ENTRY_MASK]; - printf("%s-%s\n", &pool[p->name], &pool[p->version]); + printf("%s-%s\n", + &pool[p->name & RAZOR_ENTRY_MASK], + &pool[p->version]); if (*r++ & RAZOR_IMMEDIATE) break; } @@ -1123,22 +1080,6 @@ razor_set_list_property_packages(struct razor_set *set, } } -void -razor_set_list_requires_packages(struct razor_set *set, - const char *name, - const char *version) -{ - razor_set_list_property_packages(set, &set->requires, name, version); -} - -void -razor_set_list_provides_packages(struct razor_set *set, - const char *name, - const char *version) -{ - razor_set_list_property_packages(set, &set->provides, name, version); -} - static struct razor_entry * find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern) { @@ -1305,22 +1246,30 @@ razor_set_list_package_files(struct razor_set *set, const char *name) static void razor_set_validate(struct razor_set *set, struct array *unsatisfied) { - struct razor_property *r, *p, *rend, *pend; + struct razor_property *r, *p, *end; unsigned long *u; char *pool; - p = set->provides.data; - rend = set->requires.data + set->requires.size; - pend = set->provides.data + set->provides.size; + end = set->properties.data + set->properties.size; pool = set->string_pool.data; - for (r = set->requires.data; r < rend; r++) { - while (p < pend && strcmp(&pool[r->name], &pool[p->name]) > 0) - p++; + for (r = set->properties.data, p = r; r < end; r++) { + if (r->name >> 30 != RAZOR_PROPERTY_REQUIRES) + continue; + + if ((r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK)) { + p = r; + while (p < end && p->name == r->name) + p++; + } /* If there is more than one version of a provides, * seek to the end for the highest version. */ - while (p + 1 < pend && p->name == (p + 1)->name) + /* FIXME: This doesn't work if we have a series of + * requires a = 1, provides a = 1, requires a = 2, + * provides a = 2, as the kernel and kernel-devel + * does.*/ + while (p + 1 < end && p->name == (p + 1)->name) p++; /* FIXME: We need to track property flags (<, <=, = @@ -1328,13 +1277,15 @@ razor_set_validate(struct razor_set *set, struct array *unsatisfied) * satisfied. The current code doesn't track that the * requires a = 1 isn't satisfied by a = 2 provides. */ - if (p == pend || strcmp(&pool[r->name], &pool[p->name]) != 0 || + if (p == end || + (p->name >> 30) != RAZOR_PROPERTY_PROVIDES || + (r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK) || versioncmp(&pool[r->version], &pool[p->version]) > 0) { /* FIXME: We ignore file requires for now. */ - if (pool[r->name] == '/') + if (pool[r->name & RAZOR_ENTRY_MASK] == '/') continue; u = array_add(unsatisfied, sizeof *u); - *u = r - (struct razor_property *) set->requires.data; + *u = r - (struct razor_property *) set->properties.data; } } } @@ -1343,7 +1294,7 @@ void razor_set_list_unsatisfied(struct razor_set *set) { struct array unsatisfied; - struct razor_property *requires, *r; + struct razor_property *properties, *r; unsigned long *u, *end; char *pool; @@ -1351,13 +1302,18 @@ razor_set_list_unsatisfied(struct razor_set *set) razor_set_validate(set, &unsatisfied); end = unsatisfied.data + unsatisfied.size; - requires = set->requires.data; + properties = set->properties.data; pool = set->string_pool.data; for (u = unsatisfied.data; u < end; u++) { - r = requires + *u; - printf("%s-%s not satisfied\n", - &pool[r->name], &pool[r->version]); + r = properties + *u; + if (pool[r->version] == '\0') + printf("%ss not satisfied\n", + &pool[r->name & RAZOR_ENTRY_MASK]); + else + printf("%s-%s not satisfied\n", + &pool[r->name & RAZOR_ENTRY_MASK], + &pool[r->version]); } array_release(&unsatisfied); @@ -1368,8 +1324,7 @@ razor_set_list_unsatisfied(struct razor_set *set) struct source { struct razor_set *set; - unsigned long *requires_map; - unsigned long *provides_map; + unsigned long *property_map; }; static void @@ -1380,13 +1335,9 @@ prepare_source(struct source *source, struct razor_set *set) source->set = set; - count = set->requires.size / sizeof (struct razor_property); - size = count * sizeof *source->requires_map; - source->requires_map = zalloc(size); - - count = set->provides.size / sizeof (struct razor_property); - size = count * sizeof *source->provides_map; - source->provides_map = zalloc(size); + count = set->properties.size / sizeof (struct razor_property); + size = count * sizeof *source->property_map; + source->property_map = zalloc(size); } static void @@ -1404,27 +1355,15 @@ add_package(struct razor_importer *importer, p->name |= flags; p->version = razor_importer_tokenize(importer, &pool[package->version]); - p->requires = package->requires; - p->provides = package->provides; + p->properties = package->properties; - if (package->requires & RAZOR_IMMEDIATE) - r = &package->requires; + if (package->properties & RAZOR_IMMEDIATE) + r = &package->properties; else r = (unsigned long *) - source->set->requires_pool.data + package->requires; + source->set->property_pool.data + package->properties; while (1) { - source->requires_map[*r & RAZOR_ENTRY_MASK] = 1; - if (*r++ & RAZOR_IMMEDIATE) - break; - } - - if (package->provides & RAZOR_IMMEDIATE) - r = &package->requires; - else - r = (unsigned long *) - source->set->provides_pool.data + package->provides; - while (1) { - source->provides_map[*r & RAZOR_ENTRY_MASK] = 1; + source->property_map[*r & RAZOR_ENTRY_MASK] = 1; if (*r++ & RAZOR_IMMEDIATE) break; } @@ -1474,26 +1413,23 @@ merge_packages(struct razor_importer *importer, } static unsigned long -add_property(struct razor_importer *importer, struct array *properties, +add_property(struct razor_importer *importer, const char *name, const char *version) { struct razor_property *p; - p = array_add(properties, sizeof *p); + p = array_add(&importer->set->properties, sizeof *p); p->name = razor_importer_tokenize(importer, name); p->version = razor_importer_tokenize(importer, version); - return p - (struct razor_property *) properties->data; + return p - (struct razor_property *) importer->set->properties.data; } static void -merge_properties(struct array *properties, - struct razor_importer *importer, +merge_properties(struct razor_importer *importer, struct razor_set *set1, - struct array *properties1, unsigned long *map1, struct razor_set *set2, - struct array *properties2, unsigned long *map2) { struct razor_property *p1, *p2; @@ -1505,8 +1441,8 @@ merge_properties(struct array *properties, pool1 = set1->string_pool.data; pool2 = set2->string_pool.data; - count1 = properties1->size / sizeof *p1; - count2 = properties2->size / sizeof *p2; + count1 = set1->properties.size / sizeof *p1; + count2 = set2->properties.size / sizeof *p2; while (i < count1 || j < count2) { if (i < count1 && map1[i] == 0) { i++; @@ -1516,10 +1452,11 @@ merge_properties(struct array *properties, j++; continue; } - p1 = (struct razor_property *) properties1->data + i; - p2 = (struct razor_property *) properties2->data + j; + p1 = (struct razor_property *) set1->properties.data + i; + p2 = (struct razor_property *) set2->properties.data + j; if (i < count1 && j < count2) - cmp = strcmp(&pool1[p1->name], &pool2[p2->name]); + cmp = strcmp(&pool1[p1->name & RAZOR_ENTRY_MASK], + &pool2[p2->name & RAZOR_ENTRY_MASK]); else if (i < count1) cmp = -1; else @@ -1529,18 +1466,15 @@ merge_properties(struct array *properties, &pool2[p2->version]); if (cmp < 0) { map1[i++] = add_property(importer, - properties, - &pool1[p1->name], + &pool1[p1->name & RAZOR_ENTRY_MASK], &pool1[p1->version]); } else if (cmp > 0) { map2[j++] = add_property(importer, - properties, - &pool2[p2->name], + &pool2[p2->name & RAZOR_ENTRY_MASK], &pool2[p2->version]); } else { map1[i++] = map2[j++] = add_property(importer, - properties, - &pool1[p1->name], + &pool1[p1->name & RAZOR_ENTRY_MASK], &pool1[p1->version]); } } @@ -1571,62 +1505,39 @@ emit_properties(struct array *source_pool, unsigned long index, static void rebuild_package_lists(struct razor_set *set) { - int requires_count, provides_count; - struct array *requires_pkgs, *provides_pkgs, *a; + struct array *pkgs, *a; struct razor_package *pkg, *pkg_end; struct razor_property *prop, *prop_end; - unsigned long *r, *q, *rpool, *ppool; + unsigned long *r, *q, *pool; + int count; - requires_count = set->requires.size / sizeof (struct razor_property); - provides_count = set->provides.size / sizeof (struct razor_property); - requires_pkgs = zalloc(requires_count * sizeof *requires_pkgs); - provides_pkgs = zalloc(provides_count * sizeof *provides_pkgs); + count = set->properties.size / sizeof (struct razor_property); + pkgs = zalloc(count * sizeof *pkgs); pkg_end = set->packages.data + set->packages.size; - rpool = set->requires_pool.data; - ppool = set->provides_pool.data; + pool = set->property_pool.data; for (pkg = set->packages.data; pkg < pkg_end; pkg++) { - for (r = &rpool[pkg->requires]; ; r++) { - q = array_add(&requires_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q); - *q = pkg - (struct razor_package *) set->packages.data; - if (*r & RAZOR_IMMEDIATE) - break; - } - for (r = &ppool[pkg->provides]; ; r++) { - q = array_add(&provides_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q); + for (r = &pool[pkg->properties]; ; r++) { + q = array_add(&pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q); *q = pkg - (struct razor_package *) set->packages.data; if (*r & RAZOR_IMMEDIATE) break; } } - prop_end = set->requires.data + set->requires.size; - a = requires_pkgs; - for (prop = set->requires.data; prop < prop_end; prop++, a++) { - if (a->size / sizeof *r == 1) { - r = a->data; - prop->packages = *r | RAZOR_IMMEDIATE; - } else { - prop->packages = - add_to_property_pool(&set->requires_pool, a); - } - array_release(a); - } - free(requires_pkgs); - - prop_end = set->provides.data + set->provides.size; - a = provides_pkgs; - for (prop = set->provides.data; prop < prop_end; prop++, a++) { + prop_end = set->properties.data + set->properties.size; + a = pkgs; + for (prop = set->properties.data; prop < prop_end; prop++, a++) { if (a->size / sizeof *r == 1) { r = a->data; prop->packages = *r | RAZOR_IMMEDIATE; } else { prop->packages = - add_to_property_pool(&set->provides_pool, a); + add_to_property_pool(&set->property_pool, a); } array_release(a); } - free(provides_pkgs); + free(pkgs); } /* Add packages from 'upstream' to 'set'. The packages to add are @@ -1663,14 +1574,9 @@ razor_set_add(struct razor_set *set, struct razor_set *upstream, * indices in the old property list to indices in the new * property list for both sets. */ - merge_properties(&importer->set->requires, importer, - set, &set->requires, source.requires_map, - upstream, &upstream->requires, - upstream_source.requires_map); - merge_properties(&importer->set->provides, importer, - set, &set->provides, source.provides_map, - upstream, &upstream->provides, - upstream_source.provides_map); + merge_properties(importer, + set, source.property_map, + upstream, upstream_source.property_map); /* Now we loop through the packages again and emit the * property lists, remapped to point to the new properties. */ @@ -1684,14 +1590,10 @@ razor_set_add(struct razor_set *set, struct razor_set *upstream, else src = &source; - p->requires = emit_properties(&src->set->requires_pool, - p->requires, - src->requires_map, - &importer->set->requires_pool); - p->provides = emit_properties(&src->set->provides_pool, - p->provides, - src->provides_map, - &importer->set->provides_pool); + p->properties = emit_properties(&src->set->property_pool, + p->properties, + src->property_map, + &importer->set->property_pool); p->name &= INDEX_MASK; } @@ -1714,18 +1616,21 @@ razor_set_satisfy(struct razor_set *set, struct array *unsatisfied, char *pool, *upool; end = unsatisfied->data + unsatisfied->size; - requires = set->requires.data; + requires = set->properties.data; pool = set->string_pool.data; - p = upstream->provides.data; - pend = upstream->provides.data + upstream->provides.size; + p = upstream->properties.data; + pend = upstream->properties.data + upstream->properties.size; upool = upstream->string_pool.data; package_pool = upstream->package_pool.data; for (u = unsatisfied->data; u < end; u++) { r = requires + *u; - while (p < pend && strcmp(&pool[r->name], &upool[p->name]) > 0) + while (p < pend && + strcmp(&pool[r->name & RAZOR_ENTRY_MASK], + &upool[p->name & RAZOR_ENTRY_MASK]) > 0 && + (p->name >> 30) != RAZOR_PROPERTY_PROVIDES) p++; /* If there is more than one version of a provides, * seek to the end for the highest version. */ @@ -1733,7 +1638,8 @@ razor_set_satisfy(struct razor_set *set, struct array *unsatisfied, p++; if (p == pend || - strcmp(&pool[r->name], &upool[p->name]) != 0 || + strcmp(&pool[r->name & RAZOR_ENTRY_MASK], + &upool[p->name & RAZOR_ENTRY_MASK]) != 0 || versioncmp(&pool[r->version], &upool[p->version]) > 0) { /* Do we need to track unsatisfiable requires * as we go, or should we just do a diff --git a/razor.h b/razor.h index 4fbafa9..1b13311 100644 --- a/razor.h +++ b/razor.h @@ -5,19 +5,24 @@ struct razor_set; +enum razor_property_type { + RAZOR_PROPERTY_REQUIRES, + RAZOR_PROPERTY_PROVIDES, + RAZOR_PROPERTY_CONFLICTS, + RAZOR_PROPERTY_OBSOLETES +}; + struct razor_set *razor_set_open(const char *filename); void razor_set_destroy(struct razor_set *set); int razor_set_write(struct razor_set *set, const char *filename); void razor_set_list(struct razor_set *set, const char *pattern); -void razor_set_list_requires(struct razor_set *set, const char *name); -void razor_set_list_provides(struct razor_set *set, const char *name); -void razor_set_list_requires_packages(struct razor_set *set, - const char *name, - const char *version); -void razor_set_list_provides_packages(struct razor_set *set, +void razor_set_list_properties(struct razor_set *set, const char *name, + enum razor_property_type type); +void razor_set_list_property_packages(struct razor_set *set, const char *name, - const char *version); + const char *version, + enum razor_property_type type); void razor_set_list_files(struct razor_set *set, const char *prefix); void razor_set_list_file_packages(struct razor_set *set, const char *filename); void razor_set_list_package_files(struct razor_set *set, const char *name); @@ -44,10 +49,9 @@ struct razor_importer; struct razor_importer *razor_importer_new(void); void razor_importer_begin_package(struct razor_importer *importer, const char *name, const char *version); -void razor_importer_add_requires(struct razor_importer *importer, - const char *name, const char *version); -void razor_importer_add_provides(struct razor_importer *importer, - const char *name, const char *version); +void razor_importer_add_property(struct razor_importer *importer, + const char *name, const char *version, + enum razor_property_type type); void razor_importer_add_file(struct razor_importer *importer, const char *name); void razor_importer_finish_package(struct razor_importer *importer);