1.1 --- a/librazor/razor.c Fri Jun 20 14:18:52 2008 -0400
1.2 +++ b/librazor/razor.c Fri Jun 20 21:33:29 2008 -0400
1.3 @@ -35,89 +35,8 @@
1.4
1.5 #include "razor.h"
1.6 #include "razor-internal.h"
1.7 -#include "types.h"
1.8
1.9 -struct razor_set_section {
1.10 - uint32_t type;
1.11 - uint32_t offset;
1.12 - uint32_t size;
1.13 -};
1.14 -
1.15 -struct razor_set_header {
1.16 - uint32_t magic;
1.17 - uint32_t version;
1.18 - struct razor_set_section sections[0];
1.19 -};
1.20 -
1.21 -#define RAZOR_MAGIC 0x7a7a7a7a
1.22 -#define RAZOR_VERSION 1
1.23 -
1.24 -#define RAZOR_STRING_POOL 0
1.25 -#define RAZOR_PACKAGES 1
1.26 -#define RAZOR_PROPERTIES 2
1.27 -#define RAZOR_FILES 3
1.28 -#define RAZOR_PACKAGE_POOL 4
1.29 -#define RAZOR_PROPERTY_POOL 5
1.30 -#define RAZOR_FILE_POOL 6
1.31 -
1.32 -struct razor_package {
1.33 - uint name : 24;
1.34 - uint flags : 8;
1.35 - uint32_t version;
1.36 - uint32_t arch;
1.37 - struct list_head properties;
1.38 - struct list_head files;
1.39 -};
1.40 -
1.41 -struct razor_property {
1.42 - uint32_t name;
1.43 - uint32_t flags;
1.44 - uint32_t version;
1.45 - struct list_head packages;
1.46 -};
1.47 -
1.48 -struct razor_entry {
1.49 - uint name : 24;
1.50 - uint flags : 8;
1.51 - uint32_t start;
1.52 - struct list_head packages;
1.53 -};
1.54 -
1.55 -#define RAZOR_ENTRY_LAST 0x80
1.56 -
1.57 -struct razor_set {
1.58 - struct array string_pool;
1.59 - struct array packages;
1.60 - struct array properties;
1.61 - struct array files;
1.62 - struct array package_pool;
1.63 - struct array property_pool;
1.64 - struct array file_pool;
1.65 - struct razor_set_header *header;
1.66 -};
1.67 -
1.68 -struct import_entry {
1.69 - uint32_t package;
1.70 - char *name;
1.71 -};
1.72 -
1.73 -struct import_directory {
1.74 - uint32_t name, count;
1.75 - struct array files;
1.76 - struct array packages;
1.77 - struct import_directory *last;
1.78 -};
1.79 -
1.80 -struct razor_importer {
1.81 - struct razor_set *set;
1.82 - struct hashtable table;
1.83 - struct razor_package *package;
1.84 - struct array properties;
1.85 - struct array files;
1.86 - struct array file_requires;
1.87 -};
1.88 -
1.89 -static void *
1.90 +void *
1.91 zalloc(size_t size)
1.92 {
1.93 void *p;
1.94 @@ -296,95 +215,8 @@
1.95 snprintf(evr_buf, size, "-%s", release);
1.96 }
1.97
1.98 -void
1.99 -razor_importer_begin_package(struct razor_importer *importer,
1.100 - const char *name,
1.101 - const char *version,
1.102 - const char *arch)
1.103 -{
1.104 - struct razor_package *p;
1.105 -
1.106 - p = array_add(&importer->set->packages, sizeof *p);
1.107 - p->name = hashtable_tokenize(&importer->table, name);
1.108 - p->flags = 0;
1.109 - p->version = hashtable_tokenize(&importer->table, version);
1.110 - p->arch = hashtable_tokenize(&importer->table, arch);
1.111 -
1.112 - importer->package = p;
1.113 - array_init(&importer->properties);
1.114 -}
1.115 -
1.116 -
1.117 -void
1.118 -razor_importer_finish_package(struct razor_importer *importer)
1.119 -{
1.120 - list_set_array(&importer->package->properties,
1.121 - &importer->set->property_pool,
1.122 - &importer->properties,
1.123 - 1);
1.124 -
1.125 - array_release(&importer->properties);
1.126 -}
1.127 -
1.128 -void
1.129 -razor_importer_add_property(struct razor_importer *importer,
1.130 - const char *name,
1.131 - uint32_t flags,
1.132 - const char *version)
1.133 -{
1.134 - struct razor_property *p;
1.135 - uint32_t *r;
1.136 -
1.137 - p = array_add(&importer->set->properties, sizeof *p);
1.138 - p->name = hashtable_tokenize(&importer->table, name);
1.139 - p->flags = flags;
1.140 - p->version = hashtable_tokenize(&importer->table, version);
1.141 - list_set_ptr(&p->packages, importer->package -
1.142 - (struct razor_package *) importer->set->packages.data);
1.143 -
1.144 - r = array_add(&importer->properties, sizeof *r);
1.145 - *r = p - (struct razor_property *) importer->set->properties.data;
1.146 -
1.147 - if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
1.148 - *name == '/') {
1.149 - r = array_add(&importer->file_requires, sizeof *r);
1.150 - *r = p->name;
1.151 - }
1.152 -}
1.153 -
1.154 -void
1.155 -razor_importer_add_file(struct razor_importer *importer, const char *name)
1.156 -{
1.157 - struct import_entry *e;
1.158 -
1.159 - e = array_add(&importer->files, sizeof *e);
1.160 -
1.161 - e->package = importer->package -
1.162 - (struct razor_package *) importer->set->packages.data;
1.163 - e->name = strdup(name);
1.164 -}
1.165 -
1.166 -struct razor_importer *
1.167 -razor_importer_new(void)
1.168 -{
1.169 - struct razor_importer *importer;
1.170 -
1.171 - importer = zalloc(sizeof *importer);
1.172 - importer->set = razor_set_create();
1.173 - hashtable_init(&importer->table, &importer->set->string_pool);
1.174 -
1.175 - return importer;
1.176 -}
1.177 -
1.178 -/* Destroy an importer without creating the set. */
1.179 -void
1.180 -razor_importer_destroy(struct razor_importer *importer)
1.181 -{
1.182 - /* FIXME: write this */
1.183 -}
1.184 -
1.185 -static int
1.186 -versioncmp(const char *s1, const char *s2)
1.187 +int
1.188 +razor_versioncmp(const char *s1, const char *s2)
1.189 {
1.190 const char *p1, *p2;
1.191 long n1, n2;
1.192 @@ -414,489 +246,12 @@
1.193 p1++;
1.194 p2++;
1.195 if (isdigit(*p1) && isdigit(*p2))
1.196 - return versioncmp(p1, p2);
1.197 + return razor_versioncmp(p1, p2);
1.198 }
1.199
1.200 return *p1 - *p2;
1.201 }
1.202
1.203 -static int
1.204 -compare_packages(const void *p1, const void *p2, void *data)
1.205 -{
1.206 - const struct razor_package *pkg1 = p1, *pkg2 = p2;
1.207 - struct razor_set *set = data;
1.208 - char *pool = set->string_pool.data;
1.209 -
1.210 - /* FIXME: what if the flags are different? */
1.211 - if (pkg1->name == pkg2->name)
1.212 - return versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
1.213 - else
1.214 - return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
1.215 -}
1.216 -
1.217 -static int
1.218 -compare_properties(const void *p1, const void *p2, void *data)
1.219 -{
1.220 - const struct razor_property *prop1 = p1, *prop2 = p2;
1.221 - struct razor_set *set = data;
1.222 - char *pool = set->string_pool.data;
1.223 -
1.224 - if (prop1->name != prop2->name)
1.225 - return strcmp(&pool[prop1->name], &pool[prop2->name]);
1.226 - else if (prop1->flags != prop2->flags)
1.227 - return prop1->flags - prop2->flags;
1.228 - else
1.229 - return versioncmp(&pool[prop1->version], &pool[prop2->version]);
1.230 -}
1.231 -
1.232 -static uint32_t *
1.233 -uniqueify_properties(struct razor_set *set)
1.234 -{
1.235 - struct razor_property *rp, *up, *rp_end;
1.236 - struct array *pkgs, *p;
1.237 - struct list_head *r;
1.238 - uint32_t *map, *rmap;
1.239 - int i, count, unique;
1.240 -
1.241 - count = set->properties.size / sizeof(struct razor_property);
1.242 - map = razor_qsort_with_data(set->properties.data,
1.243 - count,
1.244 - sizeof(struct razor_property),
1.245 - compare_properties,
1.246 - set);
1.247 -
1.248 - rp_end = set->properties.data + set->properties.size;
1.249 - rmap = malloc(count * sizeof *map);
1.250 - pkgs = zalloc(count * sizeof *pkgs);
1.251 - for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
1.252 - if (rp->name != up->name ||
1.253 - rp->flags != up->flags ||
1.254 - rp->version != up->version) {
1.255 - up++;
1.256 - up->name = rp->name;
1.257 - up->flags = rp->flags;
1.258 - up->version = rp->version;
1.259 - }
1.260 -
1.261 - unique = up - (struct razor_property *) set->properties.data;
1.262 - rmap[map[i]] = unique;
1.263 - r = array_add(&pkgs[unique], sizeof *r);
1.264 - *r = rp->packages;
1.265 - }
1.266 - free(map);
1.267 -
1.268 - if (up != rp)
1.269 - up++;
1.270 - set->properties.size = (void *) up - set->properties.data;
1.271 - rp_end = up;
1.272 - for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
1.273 - list_set_array(&rp->packages, &set->package_pool, p, 0);
1.274 - array_release(p);
1.275 - }
1.276 -
1.277 - free(pkgs);
1.278 -
1.279 - return rmap;
1.280 -}
1.281 -
1.282 -static int
1.283 -compare_filenames(const void *p1, const void *p2, void *data)
1.284 -{
1.285 - const struct import_entry *e1 = p1;
1.286 - const struct import_entry *e2 = p2;
1.287 - const char *n1 = e1->name;
1.288 - const char *n2 = e2->name;
1.289 -
1.290 - /* Need to make sure that the contents of a directory
1.291 - * are sorted immediately after it. So "foo/bar" has to
1.292 - * sort before "foo.conf"
1.293 - *
1.294 - * FIXME: this is about 60% slower than strcmp
1.295 - */
1.296 - while (*n1 && *n2) {
1.297 - if (*n1 < *n2)
1.298 - return *n2 == '/' ? 1 : -1;
1.299 - else if (*n1 > *n2)
1.300 - return *n1 == '/' ? -1 : 1;
1.301 - n1++;
1.302 - n2++;
1.303 - }
1.304 - if (*n1)
1.305 - return 1;
1.306 - else if (*n2)
1.307 - return -1;
1.308 - else
1.309 - return 0;
1.310 -}
1.311 -
1.312 -static void
1.313 -count_entries(struct import_directory *d)
1.314 -{
1.315 - struct import_directory *p, *end;
1.316 -
1.317 - p = d->files.data;
1.318 - end = d->files.data + d->files.size;
1.319 - d->count = 0;
1.320 - while (p < end) {
1.321 - count_entries(p);
1.322 - d->count += p->count + 1;
1.323 - p++;
1.324 - }
1.325 -}
1.326 -
1.327 -static void
1.328 -serialize_files(struct razor_set *set,
1.329 - struct import_directory *d, struct array *array)
1.330 -{
1.331 - struct import_directory *p, *end;
1.332 - struct razor_entry *e = NULL;
1.333 - uint32_t s;
1.334 -
1.335 - p = d->files.data;
1.336 - end = d->files.data + d->files.size;
1.337 - s = array->size / sizeof *e + d->files.size / sizeof *p;
1.338 - while (p < end) {
1.339 - e = array_add(array, sizeof *e);
1.340 - e->name = p->name;
1.341 - e->flags = 0;
1.342 - e->start = p->count > 0 ? s : 0;
1.343 - s += p->count;
1.344 -
1.345 - list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
1.346 - array_release(&p->packages);
1.347 - p++;
1.348 - }
1.349 - if (e != NULL)
1.350 - e->flags |= RAZOR_ENTRY_LAST;
1.351 -
1.352 - p = d->files.data;
1.353 - end = d->files.data + d->files.size;
1.354 - while (p < end) {
1.355 - serialize_files(set, p, array);
1.356 - p++;
1.357 - }
1.358 -}
1.359 -
1.360 -static void
1.361 -remap_property_package_links(struct array *properties, uint32_t *rmap)
1.362 -{
1.363 - struct razor_property *p, *end;
1.364 -
1.365 - end = properties->data + properties->size;
1.366 - for (p = properties->data; p < end; p++)
1.367 - list_remap_head(&p->packages, rmap);
1.368 -}
1.369 -
1.370 -static void
1.371 -build_file_tree(struct razor_importer *importer)
1.372 -{
1.373 - int count, i, length;
1.374 - struct import_entry *filenames;
1.375 - char *f, *end;
1.376 - uint32_t name, *r;
1.377 - char dirname[256];
1.378 - struct import_directory *d, root;
1.379 - struct razor_entry *e;
1.380 -
1.381 - count = importer->files.size / sizeof (struct import_entry);
1.382 - razor_qsort_with_data(importer->files.data,
1.383 - count,
1.384 - sizeof (struct import_entry),
1.385 - compare_filenames,
1.386 - NULL);
1.387 -
1.388 - root.name = hashtable_tokenize(&importer->table, "");
1.389 - array_init(&root.files);
1.390 - array_init(&root.packages);
1.391 - root.last = NULL;
1.392 -
1.393 - filenames = importer->files.data;
1.394 - for (i = 0; i < count; i++) {
1.395 - f = filenames[i].name;
1.396 - if (*f != '/')
1.397 - continue;
1.398 - f++;
1.399 -
1.400 - d = &root;
1.401 - while (*f) {
1.402 - end = strchr(f, '/');
1.403 - if (end == NULL)
1.404 - end = f + strlen(f);
1.405 - length = end - f;
1.406 - memcpy(dirname, f, length);
1.407 - dirname[length] ='\0';
1.408 - name = hashtable_tokenize(&importer->table, dirname);
1.409 - if (d->last == NULL || d->last->name != name) {
1.410 - d->last = array_add(&d->files, sizeof *d);
1.411 - d->last->name = name;
1.412 - d->last->last = NULL;
1.413 - array_init(&d->last->files);
1.414 - array_init(&d->last->packages);
1.415 - }
1.416 - d = d->last;
1.417 - f = end + 1;
1.418 - if (*end == '\0')
1.419 - break;
1.420 - }
1.421 -
1.422 - r = array_add(&d->packages, sizeof *r);
1.423 - *r = filenames[i].package;
1.424 - free(filenames[i].name);
1.425 - }
1.426 -
1.427 - count_entries(&root);
1.428 - e = importer->set->files.data;
1.429 - e->name = root.name;
1.430 - e->flags = RAZOR_ENTRY_LAST;
1.431 - e->start = importer->files.size ? 1 : 0;
1.432 - list_set_empty(&e->packages);
1.433 -
1.434 - serialize_files(importer->set, &root, &importer->set->files);
1.435 -
1.436 - array_release(&importer->files);
1.437 -}
1.438 -
1.439 -static struct razor_entry *
1.440 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern);
1.441 -
1.442 -static void
1.443 -list_to_array(struct list *list, struct array *array)
1.444 -{
1.445 - uint32_t *item;
1.446 -
1.447 - while (list) {
1.448 - item = array_add(array, sizeof *item);
1.449 - *item = list->data;
1.450 - list = list_next(list);
1.451 - }
1.452 -}
1.453 -
1.454 -static int
1.455 -compare_file_requires(const void *p1, const void *p2, void *data)
1.456 -{
1.457 - uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
1.458 - const char *pool = data;
1.459 -
1.460 - return strcmp(&pool[*f1], &pool[*f2]);
1.461 -}
1.462 -
1.463 -static void
1.464 -find_file_provides(struct razor_importer *importer)
1.465 -{
1.466 - struct razor_property *prop;
1.467 - struct razor_entry *top, *entry;
1.468 - struct razor_package *packages;
1.469 - struct array pkgprops;
1.470 - struct list *pkg;
1.471 - uint32_t *req, *req_start, *req_end;
1.472 - uint32_t *map, *newprop;
1.473 - char *pool;
1.474 -
1.475 - pool = importer->set->string_pool.data;
1.476 - packages = importer->set->packages.data;
1.477 - top = importer->set->files.data;
1.478 -
1.479 - req = req_start = importer->file_requires.data;
1.480 - req_end = importer->file_requires.data + importer->file_requires.size;
1.481 - map = razor_qsort_with_data(req, req_end - req, sizeof *req,
1.482 - compare_file_requires, pool);
1.483 - free(map);
1.484 -
1.485 - for (req = req_start; req < req_end; req++) {
1.486 - if (req > req_start && req[0] == req[-1])
1.487 - continue;
1.488 - entry = find_entry(importer->set, top, &pool[*req]);
1.489 - if (!entry)
1.490 - continue;
1.491 -
1.492 - for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
1.493 - prop = array_add(&importer->set->properties, sizeof *prop);
1.494 - prop->name = *req;
1.495 - prop->flags =
1.496 - RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
1.497 - prop->version = hashtable_tokenize(&importer->table, "");
1.498 - list_set_ptr(&prop->packages, pkg->data);
1.499 -
1.500 - /* Update property list of pkg */
1.501 - array_init(&pkgprops);
1.502 - list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
1.503 - newprop = array_add(&pkgprops, sizeof *newprop);
1.504 - *newprop = prop - (struct razor_property *)importer->set->properties.data;
1.505 - list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
1.506 - array_release(&pkgprops);
1.507 - }
1.508 - }
1.509 -
1.510 - array_release(&importer->file_requires);
1.511 -}
1.512 -
1.513 -static void
1.514 -build_package_file_lists(struct razor_set *set, uint32_t *rmap)
1.515 -{
1.516 - struct razor_package *p, *packages;
1.517 - struct array *pkgs;
1.518 - struct razor_entry *e, *end;
1.519 - struct list *r;
1.520 - uint32_t *q;
1.521 - int i, count;
1.522 -
1.523 - count = set->packages.size / sizeof *p;
1.524 - pkgs = zalloc(count * sizeof *pkgs);
1.525 -
1.526 - end = set->files.data + set->files.size;
1.527 - for (e = set->files.data; e < end; e++) {
1.528 - list_remap_head(&e->packages, rmap);
1.529 - r = list_first(&e->packages, &set->package_pool);
1.530 - while (r) {
1.531 - q = array_add(&pkgs[r->data], sizeof *q);
1.532 - *q = e - (struct razor_entry *) set->files.data;
1.533 - r = list_next(r);
1.534 - }
1.535 - }
1.536 -
1.537 - packages = set->packages.data;
1.538 - for (i = 0; i < count; i++) {
1.539 - list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
1.540 - array_release(&pkgs[i]);
1.541 - }
1.542 - free(pkgs);
1.543 -}
1.544 -
1.545 -struct razor_set *
1.546 -razor_importer_finish(struct razor_importer *importer)
1.547 -{
1.548 - struct razor_set *set;
1.549 - uint32_t *map, *rmap;
1.550 - int i, count;
1.551 -
1.552 - build_file_tree(importer);
1.553 - find_file_provides(importer);
1.554 -
1.555 - map = uniqueify_properties(importer->set);
1.556 - list_remap_pool(&importer->set->property_pool, map);
1.557 - free(map);
1.558 -
1.559 - count = importer->set->packages.size / sizeof(struct razor_package);
1.560 - map = razor_qsort_with_data(importer->set->packages.data,
1.561 - count,
1.562 - sizeof(struct razor_package),
1.563 - compare_packages,
1.564 - importer->set);
1.565 -
1.566 - rmap = malloc(count * sizeof *rmap);
1.567 - for (i = 0; i < count; i++)
1.568 - rmap[map[i]] = i;
1.569 - free(map);
1.570 -
1.571 - list_remap_pool(&importer->set->package_pool, rmap);
1.572 - build_package_file_lists(importer->set, rmap);
1.573 - remap_property_package_links(&importer->set->properties, rmap);
1.574 - free(rmap);
1.575 -
1.576 - set = importer->set;
1.577 - hashtable_release(&importer->table);
1.578 - free(importer);
1.579 -
1.580 - return set;
1.581 -}
1.582 -
1.583 -struct razor_package_iterator {
1.584 - struct razor_set *set;
1.585 - struct razor_package *package, *end;
1.586 - struct list *index;
1.587 - int free_index;
1.588 -};
1.589 -
1.590 -static struct razor_package_iterator *
1.591 -razor_package_iterator_create_with_index(struct razor_set *set,
1.592 - struct list *index)
1.593 -{
1.594 - struct razor_package_iterator *pi;
1.595 -
1.596 - pi = zalloc(sizeof *pi);
1.597 - pi->set = set;
1.598 - pi->index = index;
1.599 -
1.600 - return pi;
1.601 -}
1.602 -
1.603 -struct razor_package_iterator *
1.604 -razor_package_iterator_create(struct razor_set *set)
1.605 -{
1.606 - struct razor_package_iterator *pi;
1.607 -
1.608 - pi = zalloc(sizeof *pi);
1.609 - pi->set = set;
1.610 - pi->end = set->packages.data + set->packages.size;
1.611 - pi->package = set->packages.data;
1.612 -
1.613 - return pi;
1.614 -}
1.615 -
1.616 -static void
1.617 -razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
1.618 - struct razor_set *set,
1.619 - struct razor_property *property)
1.620 -{
1.621 - memset(pi, 0, sizeof *pi);
1.622 - pi->set = set;
1.623 - pi->index = list_first(&property->packages, &set->package_pool);
1.624 -}
1.625 -
1.626 -struct razor_package_iterator *
1.627 -razor_package_iterator_create_for_property(struct razor_set *set,
1.628 - struct razor_property *property)
1.629 -{
1.630 - struct list *index;
1.631 -
1.632 - index = list_first(&property->packages, &set->package_pool);
1.633 - return razor_package_iterator_create_with_index(set, index);
1.634 -}
1.635 -
1.636 -int
1.637 -razor_package_iterator_next(struct razor_package_iterator *pi,
1.638 - struct razor_package **package,
1.639 - const char **name,
1.640 - const char **version,
1.641 - const char **arch)
1.642 -{
1.643 - char *pool;
1.644 - int valid;
1.645 - struct razor_package *p, *packages;
1.646 -
1.647 - if (pi->package) {
1.648 - p = pi->package++;
1.649 - valid = p < pi->end;
1.650 - } else if (pi->index) {
1.651 - packages = pi->set->packages.data;
1.652 - p = &packages[pi->index->data];
1.653 - pi->index = list_next(pi->index);
1.654 - valid = 1;
1.655 - } else
1.656 - valid = 0;
1.657 -
1.658 - if (valid) {
1.659 - pool = pi->set->string_pool.data;
1.660 - *package = p;
1.661 - *name = &pool[p->name];
1.662 - *version = &pool[p->version];
1.663 - *arch = &pool[p->arch];
1.664 - } else {
1.665 - *package = NULL;
1.666 - }
1.667 -
1.668 - return valid;
1.669 -}
1.670 -
1.671 -void
1.672 -razor_package_iterator_destroy(struct razor_package_iterator *pi)
1.673 -{
1.674 - if (pi->free_index)
1.675 - free(pi->index);
1.676 -
1.677 - free(pi);
1.678 -}
1.679 -
1.680 struct razor_package *
1.681 razor_set_get_package(struct razor_set *set, const char *package)
1.682 {
1.683 @@ -914,75 +269,9 @@
1.684 return p;
1.685 }
1.686
1.687 -struct razor_property_iterator {
1.688 - struct razor_set *set;
1.689 - struct razor_property *property, *end;
1.690 - struct list *index;
1.691 -};
1.692 -
1.693 -struct razor_property_iterator *
1.694 -razor_property_iterator_create(struct razor_set *set,
1.695 - struct razor_package *package)
1.696 -{
1.697 - struct razor_property_iterator *pi;
1.698 -
1.699 - pi = zalloc(sizeof *pi);
1.700 - pi->set = set;
1.701 -
1.702 - if (package) {
1.703 - pi->index = list_first(&package->properties,
1.704 - &set->property_pool);
1.705 - } else {
1.706 - pi->property = set->properties.data;
1.707 - pi->end = set->properties.data + set->properties.size;
1.708 - }
1.709 -
1.710 - return pi;
1.711 -}
1.712 -
1.713 -int
1.714 -razor_property_iterator_next(struct razor_property_iterator *pi,
1.715 - struct razor_property **property,
1.716 - const char **name,
1.717 - uint32_t *flags,
1.718 - const char **version)
1.719 -{
1.720 - char *pool;
1.721 - int valid;
1.722 - struct razor_property *p, *properties;
1.723 -
1.724 - if (pi->property) {
1.725 - p = pi->property++;
1.726 - valid = p < pi->end;
1.727 - } else if (pi->index) {
1.728 - properties = pi->set->properties.data;
1.729 - p = &properties[pi->index->data];
1.730 - pi->index = list_next(pi->index);
1.731 - valid = 1;
1.732 - } else
1.733 - valid = 0;
1.734 -
1.735 - if (valid) {
1.736 - pool = pi->set->string_pool.data;
1.737 - *property = p;
1.738 - *name = &pool[p->name];
1.739 - *flags = p->flags;
1.740 - *version = &pool[p->version];
1.741 - } else {
1.742 - *property = NULL;
1.743 - }
1.744 -
1.745 - return valid;
1.746 -}
1.747 -
1.748 -void
1.749 -razor_property_iterator_destroy(struct razor_property_iterator *pi)
1.750 -{
1.751 - free(pi);
1.752 -}
1.753 -
1.754 -static struct razor_entry *
1.755 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
1.756 +struct razor_entry *
1.757 +razor_set_find_entry(struct razor_set *set,
1.758 + struct razor_entry *dir, const char *pattern)
1.759 {
1.760 struct razor_entry *e;
1.761 const char *n, *pool = set->string_pool.data;
1.762 @@ -996,7 +285,7 @@
1.763 len = strlen(n);
1.764 if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
1.765 pattern[len + 1] == '/') {
1.766 - return find_entry(set, e, pattern + len + 1);
1.767 + return razor_set_find_entry(set, e, pattern + len + 1);
1.768 }
1.769 } while (!((e++)->flags & RAZOR_ENTRY_LAST));
1.770
1.771 @@ -1039,7 +328,7 @@
1.772 }
1.773
1.774 strcpy(buffer, pattern);
1.775 - e = find_entry(set, set->files.data, buffer);
1.776 + e = razor_set_find_entry(set, set->files.data, buffer);
1.777 if (e && e->start > 0) {
1.778 base = NULL;
1.779 } else {
1.780 @@ -1051,26 +340,11 @@
1.781 base = NULL;
1.782 }
1.783 }
1.784 - e = find_entry(set, set->files.data, buffer);
1.785 + e = razor_set_find_entry(set, set->files.data, buffer);
1.786 if (e->start != 0)
1.787 list_dir(set, e, buffer, base);
1.788 }
1.789
1.790 -struct razor_package_iterator *
1.791 -razor_package_iterator_create_for_file(struct razor_set *set,
1.792 - const char *filename)
1.793 -{
1.794 - struct razor_entry *entry;
1.795 - struct list *index;
1.796 -
1.797 - entry = find_entry(set, set->files.data, filename);
1.798 - if (entry == NULL)
1.799 - return NULL;
1.800 -
1.801 - index = list_first(&entry->packages, &set->package_pool);
1.802 - return razor_package_iterator_create_with_index(set, index);
1.803 -}
1.804 -
1.805 static struct list *
1.806 list_package_files(struct razor_set *set, struct list *r,
1.807 struct razor_entry *dir, uint32_t end,
1.808 @@ -1142,509 +416,6 @@
1.809 list_package_files(set, r, set->files.data, end, buffer);
1.810 }
1.811
1.812 -#define UPSTREAM_SOURCE 0x80
1.813 -
1.814 -struct source {
1.815 - struct razor_set *set;
1.816 - uint32_t *property_map;
1.817 - uint32_t *file_map;
1.818 -};
1.819 -
1.820 -struct razor_merger {
1.821 - struct razor_set *set;
1.822 - struct hashtable table;
1.823 - struct source source1;
1.824 - struct source source2;
1.825 -};
1.826 -
1.827 -static struct razor_merger *
1.828 -razor_merger_create(struct razor_set *set1, struct razor_set *set2)
1.829 -{
1.830 - struct razor_merger *merger;
1.831 - int count;
1.832 - size_t size;
1.833 -
1.834 - merger = zalloc(sizeof *merger);
1.835 - merger->set = razor_set_create();
1.836 - hashtable_init(&merger->table, &merger->set->string_pool);
1.837 -
1.838 - merger->source1.set = set1;
1.839 - count = set1->properties.size / sizeof (struct razor_property);
1.840 - size = count * sizeof merger->source1.property_map[0];
1.841 - merger->source1.property_map = zalloc(size);
1.842 - count = set1->files.size / sizeof (struct razor_entry);
1.843 - size = count * sizeof merger->source1.file_map[0];
1.844 - merger->source1.file_map = zalloc(size);
1.845 -
1.846 - merger->source2.set = set2;
1.847 - count = set2->properties.size / sizeof (struct razor_property);
1.848 - size = count * sizeof merger->source2.property_map[0];
1.849 - merger->source2.property_map = zalloc(size);
1.850 - count = set2->files.size / sizeof (struct razor_entry);
1.851 - size = count * sizeof merger->source2.file_map[0];
1.852 - merger->source2.file_map = zalloc(size);
1.853 -
1.854 - return merger;
1.855 -}
1.856 -
1.857 -static void
1.858 -razor_merger_add_package(struct razor_merger *merger,
1.859 - struct razor_package *package)
1.860 -{
1.861 - char *pool;
1.862 - struct list *r;
1.863 - struct razor_package *p;
1.864 - struct razor_set *set1;
1.865 - struct source *source;
1.866 - uint32_t flags;
1.867 -
1.868 - set1 = merger->source1.set;
1.869 - if (set1->packages.data <= (void *) package &&
1.870 - (void *) package < set1->packages.data + set1->packages.size) {
1.871 - source = &merger->source1;
1.872 - flags = 0;
1.873 - } else {
1.874 - source = &merger->source2;
1.875 - flags = UPSTREAM_SOURCE;
1.876 - }
1.877 -
1.878 - pool = source->set->string_pool.data;
1.879 - p = array_add(&merger->set->packages, sizeof *p);
1.880 - p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
1.881 - p->flags = flags;
1.882 - p->version = hashtable_tokenize(&merger->table,
1.883 - &pool[package->version]);
1.884 - p->arch = hashtable_tokenize(&merger->table,
1.885 - &pool[package->arch]);
1.886 -
1.887 - p->properties = package->properties;
1.888 - r = list_first(&package->properties, &source->set->property_pool);
1.889 - while (r) {
1.890 - source->property_map[r->data] = 1;
1.891 - r = list_next(r);
1.892 - }
1.893 -
1.894 - p->files = package->files;
1.895 - r = list_first(&package->files, &source->set->file_pool);
1.896 - while (r) {
1.897 - source->file_map[r->data] = 1;
1.898 - r = list_next(r);
1.899 - }
1.900 -}
1.901 -
1.902 -static uint32_t
1.903 -add_property(struct razor_merger *merger,
1.904 - const char *name, uint32_t flags, const char *version)
1.905 -{
1.906 - struct razor_property *p;
1.907 -
1.908 - p = array_add(&merger->set->properties, sizeof *p);
1.909 - p->name = hashtable_tokenize(&merger->table, name);
1.910 - p->flags = flags;
1.911 - p->version = hashtable_tokenize(&merger->table, version);
1.912 -
1.913 - return p - (struct razor_property *) merger->set->properties.data;
1.914 -}
1.915 -
1.916 -static void
1.917 -merge_properties(struct razor_merger *merger)
1.918 -{
1.919 - struct razor_property *p1, *p2;
1.920 - struct razor_set *set1, *set2;
1.921 - uint32_t *map1, *map2;
1.922 - int i, j, cmp, count1, count2;
1.923 - char *pool1, *pool2;
1.924 -
1.925 - set1 = merger->source1.set;
1.926 - set2 = merger->source2.set;
1.927 - map1 = merger->source1.property_map;
1.928 - map2 = merger->source2.property_map;
1.929 -
1.930 - i = 0;
1.931 - j = 0;
1.932 - pool1 = set1->string_pool.data;
1.933 - pool2 = set2->string_pool.data;
1.934 -
1.935 - count1 = set1->properties.size / sizeof *p1;
1.936 - count2 = set2->properties.size / sizeof *p2;
1.937 - while (i < count1 || j < count2) {
1.938 - if (i < count1 && map1[i] == 0) {
1.939 - i++;
1.940 - continue;
1.941 - }
1.942 - if (j < count2 && map2[j] == 0) {
1.943 - j++;
1.944 - continue;
1.945 - }
1.946 - p1 = (struct razor_property *) set1->properties.data + i;
1.947 - p2 = (struct razor_property *) set2->properties.data + j;
1.948 - if (i < count1 && j < count2)
1.949 - cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
1.950 - else if (i < count1)
1.951 - cmp = -1;
1.952 - else
1.953 - cmp = 1;
1.954 - if (cmp == 0)
1.955 - cmp = p1->flags - p2->flags;
1.956 - if (cmp == 0)
1.957 - cmp = versioncmp(&pool1[p1->version],
1.958 - &pool2[p2->version]);
1.959 - if (cmp < 0) {
1.960 - map1[i++] = add_property(merger,
1.961 - &pool1[p1->name],
1.962 - p1->flags,
1.963 - &pool1[p1->version]);
1.964 - } else if (cmp > 0) {
1.965 - map2[j++] = add_property(merger,
1.966 - &pool2[p2->name],
1.967 - p2->flags,
1.968 - &pool2[p2->version]);
1.969 - } else {
1.970 - map1[i++] = map2[j++] =
1.971 - add_property(merger,
1.972 - &pool1[p1->name],
1.973 - p1->flags,
1.974 - &pool1[p1->version]);
1.975 - }
1.976 - }
1.977 -}
1.978 -
1.979 -static void
1.980 -emit_properties(struct list_head *properties, struct array *source_pool,
1.981 - uint32_t *map, struct array *pool)
1.982 -{
1.983 - uint32_t r;
1.984 - struct list *p, *q;
1.985 -
1.986 - r = pool->size / sizeof *q;
1.987 - p = list_first(properties, source_pool);
1.988 - while (p) {
1.989 - q = array_add(pool, sizeof *q);
1.990 - q->data = map[p->data];
1.991 - q->flags = p->flags;
1.992 - p = list_next(p);
1.993 - }
1.994 -
1.995 - list_set_ptr(properties, r);
1.996 -}
1.997 -
1.998 -static uint32_t
1.999 -add_file(struct razor_merger *merger, const char *name)
1.1000 -{
1.1001 - struct razor_entry *e;
1.1002 -
1.1003 - e = array_add(&merger->set->files, sizeof *e);
1.1004 - e->name = hashtable_tokenize(&merger->table, name);
1.1005 - e->flags = 0;
1.1006 - e->start = 0;
1.1007 -
1.1008 - return e - (struct razor_entry *)merger->set->files.data;
1.1009 -}
1.1010 -
1.1011 -/* FIXME. Blah */
1.1012 -static int
1.1013 -fix_file_map(uint32_t *map,
1.1014 - struct razor_entry *files,
1.1015 - struct razor_entry *top)
1.1016 -{
1.1017 - uint32_t e;
1.1018 - int found_file = 0;
1.1019 -
1.1020 - e = top->start;
1.1021 - do {
1.1022 - if (files[e].start)
1.1023 - fix_file_map(map, files, &files[e]);
1.1024 - if (map[e])
1.1025 - found_file = 1;
1.1026 - } while (!(files[e++].flags & RAZOR_ENTRY_LAST));
1.1027 -
1.1028 - if (found_file)
1.1029 - map[top - files] = 1;
1.1030 - return found_file;
1.1031 -}
1.1032 -
1.1033 -struct merge_directory {
1.1034 - uint32_t merged, dir1, dir2;
1.1035 -};
1.1036 -
1.1037 -static void
1.1038 -merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
1.1039 -{
1.1040 - struct razor_entry *root1, *root2, *mroot, *e1, *e2;
1.1041 - struct razor_set *set1, *set2;
1.1042 - struct array merge_stack;
1.1043 - struct merge_directory *child_md, *end_md;
1.1044 - uint32_t *map1, *map2, start, last;
1.1045 - int cmp;
1.1046 - char *pool1, *pool2;
1.1047 -
1.1048 - set1 = merger->source1.set;
1.1049 - set2 = merger->source2.set;
1.1050 - map1 = merger->source1.file_map;
1.1051 - map2 = merger->source2.file_map;
1.1052 - pool1 = set1->string_pool.data;
1.1053 - pool2 = set2->string_pool.data;
1.1054 - root1 = (struct razor_entry *) set1->files.data;
1.1055 - root2 = (struct razor_entry *) set2->files.data;
1.1056 -
1.1057 - array_init(&merge_stack);
1.1058 -
1.1059 - start = merger->set->files.size / sizeof (struct razor_entry);
1.1060 - last = 0;
1.1061 - e1 = md->dir1 ? root1 + md->dir1 : NULL;
1.1062 - e2 = md->dir2 ? root2 + md->dir2 : NULL;
1.1063 - while (e1 || e2) {
1.1064 - if (!e2 && !map1[e1 - root1]) {
1.1065 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
1.1066 - e1 = NULL;
1.1067 - continue;
1.1068 - }
1.1069 - if (!e1 && !map2[e2 - root2]) {
1.1070 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
1.1071 - e2 = NULL;
1.1072 - continue;
1.1073 - }
1.1074 - if (e1 && !map1[e1 - root1] &&
1.1075 - e2 && !map1[e2 - root2]) {
1.1076 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
1.1077 - e1 = NULL;
1.1078 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
1.1079 - e2 = NULL;
1.1080 - continue;
1.1081 - }
1.1082 -
1.1083 - if (!e1)
1.1084 - cmp = 1;
1.1085 - else if (!e2)
1.1086 - cmp = -1;
1.1087 - else {
1.1088 - cmp = strcmp (&pool1[e1->name],
1.1089 - &pool2[e2->name]);
1.1090 - }
1.1091 -
1.1092 - if (cmp < 0) {
1.1093 - if (map1[e1 - root1]) {
1.1094 - map1[e1 - root1] = last =
1.1095 - add_file(merger, &pool1[e1->name]);
1.1096 - if (e1->start) {
1.1097 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
1.1098 - child_md->merged = last;
1.1099 - child_md->dir1 = e1->start;
1.1100 - child_md->dir2 = 0;
1.1101 - }
1.1102 - }
1.1103 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
1.1104 - e1 = NULL;
1.1105 - } else if (cmp > 0) {
1.1106 - if (map2[e2 - root2]) {
1.1107 - map2[e2 - root2] = last =
1.1108 - add_file(merger, &pool2[e2->name]);
1.1109 - if (e2->start) {
1.1110 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
1.1111 - child_md->merged = last;
1.1112 - child_md->dir1 = 0;
1.1113 - child_md->dir2 = e2->start;
1.1114 - }
1.1115 - }
1.1116 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
1.1117 - e2 = NULL;
1.1118 - } else {
1.1119 - map1[e1 - root1] = map2[e2- root2] = last =
1.1120 - add_file(merger, &pool1[e1->name]);
1.1121 - if (e1->start || e2->start) {
1.1122 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
1.1123 - child_md->merged = last;
1.1124 - child_md->dir1 = e1->start;
1.1125 - child_md->dir2 = e2->start;
1.1126 - }
1.1127 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
1.1128 - e1 = NULL;
1.1129 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
1.1130 - e2 = NULL;
1.1131 - }
1.1132 - }
1.1133 -
1.1134 - mroot = (struct razor_entry *)merger->set->files.data;
1.1135 - if (last) {
1.1136 - mroot[last].flags = RAZOR_ENTRY_LAST;
1.1137 - mroot[md->merged].start = start;
1.1138 - } else
1.1139 - mroot[md->merged].start = 0;
1.1140 -
1.1141 - end_md = merge_stack.data + merge_stack.size;
1.1142 - for (child_md = merge_stack.data; child_md < end_md; child_md++)
1.1143 - merge_one_directory(merger, child_md);
1.1144 - array_release(&merge_stack);
1.1145 -}
1.1146 -
1.1147 -static void
1.1148 -merge_files(struct razor_merger *merger)
1.1149 -{
1.1150 - struct razor_entry *root;
1.1151 - struct merge_directory md;
1.1152 - uint32_t *map1, *map2;
1.1153 -
1.1154 - map1 = merger->source1.file_map;
1.1155 - map2 = merger->source2.file_map;
1.1156 -
1.1157 - md.merged = 0;
1.1158 -
1.1159 - if (merger->source1.set->files.size) {
1.1160 - root = (struct razor_entry *) merger->source1.set->files.data;
1.1161 - if (root->start)
1.1162 - fix_file_map(map1, root, root);
1.1163 - md.dir1 = root->start;
1.1164 - } else
1.1165 - md.dir1 = 0;
1.1166 -
1.1167 - if (merger->source2.set->files.size) {
1.1168 - root = (struct razor_entry *) merger->source2.set->files.data;
1.1169 - if (root->start)
1.1170 - fix_file_map(map2, root, root);
1.1171 - md.dir2 = root->start;
1.1172 - } else
1.1173 - md.dir2 = 0;
1.1174 -
1.1175 - merge_one_directory(merger, &md);
1.1176 -}
1.1177 -
1.1178 -static void
1.1179 -emit_files(struct list_head *files, struct array *source_pool,
1.1180 - uint32_t *map, struct array *pool)
1.1181 -{
1.1182 - uint32_t r;
1.1183 - struct list *p, *q;
1.1184 -
1.1185 - r = pool->size / sizeof *q;
1.1186 - p = list_first(files, source_pool);
1.1187 - while (p) {
1.1188 - q = array_add(pool, sizeof *q);
1.1189 - q->data = map[p->data];
1.1190 - q->flags = p->flags;
1.1191 - p = list_next(p);
1.1192 - }
1.1193 -
1.1194 - list_set_ptr(files, r);
1.1195 -}
1.1196 -
1.1197 -/* Rebuild property->packages maps. We can't just remap these, as a
1.1198 - * property may have lost or gained a number of packages. Allocate an
1.1199 - * array per property and loop through the packages and add them to
1.1200 - * the arrays for their properties. */
1.1201 -static void
1.1202 -rebuild_property_package_lists(struct razor_set *set)
1.1203 -{
1.1204 - struct array *pkgs, *a;
1.1205 - struct razor_package *pkg, *pkg_end;
1.1206 - struct razor_property *prop, *prop_end;
1.1207 - struct list *r;
1.1208 - uint32_t *q;
1.1209 - int count;
1.1210 -
1.1211 - count = set->properties.size / sizeof (struct razor_property);
1.1212 - pkgs = zalloc(count * sizeof *pkgs);
1.1213 - pkg_end = set->packages.data + set->packages.size;
1.1214 -
1.1215 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
1.1216 - r = list_first(&pkg->properties, &set->property_pool);
1.1217 - while (r) {
1.1218 - q = array_add(&pkgs[r->data], sizeof *q);
1.1219 - *q = pkg - (struct razor_package *) set->packages.data;
1.1220 - r = list_next(r);
1.1221 - }
1.1222 - }
1.1223 -
1.1224 - prop_end = set->properties.data + set->properties.size;
1.1225 - a = pkgs;
1.1226 - for (prop = set->properties.data; prop < prop_end; prop++, a++) {
1.1227 - list_set_array(&prop->packages, &set->package_pool, a, 0);
1.1228 - array_release(a);
1.1229 - }
1.1230 - free(pkgs);
1.1231 -}
1.1232 -
1.1233 -static void
1.1234 -rebuild_file_package_lists(struct razor_set *set)
1.1235 -{
1.1236 - struct array *pkgs, *a;
1.1237 - struct razor_package *pkg, *pkg_end;
1.1238 - struct razor_entry *entry, *entry_end;
1.1239 - struct list *r;
1.1240 - uint32_t *q;
1.1241 - int count;
1.1242 -
1.1243 - count = set->files.size / sizeof (struct razor_entry);
1.1244 - pkgs = zalloc(count * sizeof *pkgs);
1.1245 - pkg_end = set->packages.data + set->packages.size;
1.1246 -
1.1247 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
1.1248 - r = list_first(&pkg->files, &set->file_pool);
1.1249 - while (r) {
1.1250 - q = array_add(&pkgs[r->data], sizeof *q);
1.1251 - *q = pkg - (struct razor_package *) set->packages.data;
1.1252 - r = list_next(r);
1.1253 - }
1.1254 - }
1.1255 -
1.1256 - entry_end = set->files.data + set->files.size;
1.1257 - a = pkgs;
1.1258 - for (entry = set->files.data; entry < entry_end; entry++, a++) {
1.1259 - list_set_array(&entry->packages, &set->package_pool, a, 0);
1.1260 - array_release(a);
1.1261 - }
1.1262 - free(pkgs);
1.1263 -}
1.1264 -
1.1265 -static struct razor_set *
1.1266 -razor_merger_finish(struct razor_merger *merger)
1.1267 -{
1.1268 - struct razor_set *result;
1.1269 - struct razor_package *p, *pend;
1.1270 -
1.1271 - /* As we built the package list, we filled out a bitvector of
1.1272 - * the properties that are referenced by the packages in the
1.1273 - * new set. Now we do a parallel loop through the properties
1.1274 - * and emit those marked in the bit vector to the new set. In
1.1275 - * the process, we update the bit vector to actually map from
1.1276 - * indices in the old property list to indices in the new
1.1277 - * property list for both sets. */
1.1278 -
1.1279 - merge_properties(merger);
1.1280 - merge_files(merger);
1.1281 -
1.1282 - /* Now we loop through the packages again and emit the
1.1283 - * property lists, remapped to point to the new properties. */
1.1284 -
1.1285 - pend = merger->set->packages.data + merger->set->packages.size;
1.1286 - for (p = merger->set->packages.data; p < pend; p++) {
1.1287 - struct source *src;
1.1288 -
1.1289 - if (p->flags & UPSTREAM_SOURCE)
1.1290 - src = &merger->source2;
1.1291 - else
1.1292 - src = &merger->source1;
1.1293 -
1.1294 - emit_properties(&p->properties,
1.1295 - &src->set->property_pool,
1.1296 - src->property_map,
1.1297 - &merger->set->property_pool);
1.1298 - emit_files(&p->files,
1.1299 - &src->set->file_pool,
1.1300 - src->file_map,
1.1301 - &merger->set->file_pool);
1.1302 - p->flags &= ~UPSTREAM_SOURCE;
1.1303 - }
1.1304 -
1.1305 - rebuild_property_package_lists(merger->set);
1.1306 - rebuild_file_package_lists(merger->set);
1.1307 -
1.1308 - result = merger->set;
1.1309 - hashtable_release(&merger->table);
1.1310 - free(merger);
1.1311 -
1.1312 - return result;
1.1313 -}
1.1314 -
1.1315 /* The diff order matters. We should sort the packages so that a
1.1316 * REMOVE of a package comes before the INSTALL, and so that all
1.1317 * requires for a package have been installed before the package.
1.1318 @@ -1669,7 +440,7 @@
1.1319 if (p1 && p2) {
1.1320 res = strcmp(name1, name2);
1.1321 if (res == 0)
1.1322 - res = versioncmp(version1, version2);
1.1323 + res = razor_versioncmp(version1, version2);
1.1324 } else {
1.1325 res = 0;
1.1326 }
1.1327 @@ -1690,953 +461,3 @@
1.1328 razor_package_iterator_destroy(pi1);
1.1329 razor_package_iterator_destroy(pi2);
1.1330 }
1.1331 -
1.1332 -static int
1.1333 -provider_satisfies_requirement(struct razor_property *provider,
1.1334 - const char *provider_strings,
1.1335 - uint32_t flags,
1.1336 - const char *required)
1.1337 -{
1.1338 - int cmp, len;
1.1339 - const char *provided = &provider_strings[provider->version];
1.1340 -
1.1341 - if (!*required)
1.1342 - return 1;
1.1343 - if (!*provided) {
1.1344 - if (flags & RAZOR_PROPERTY_LESS)
1.1345 - return 0;
1.1346 - else
1.1347 - return 1;
1.1348 - }
1.1349 -
1.1350 - cmp = versioncmp(provided, required);
1.1351 -
1.1352 - switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
1.1353 - case RAZOR_PROPERTY_LESS:
1.1354 - return cmp < 0;
1.1355 -
1.1356 - case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
1.1357 - if (cmp <= 0)
1.1358 - return 1;
1.1359 - /* fall through: FIXME, make sure this is correct */
1.1360 -
1.1361 - case RAZOR_PROPERTY_EQUAL:
1.1362 - if (cmp == 0)
1.1363 - return 1;
1.1364 -
1.1365 - /* "foo == 1.1" is satisfied by "foo 1.1-2" */
1.1366 - len = strlen(required);
1.1367 - if (!strncmp(required, provided, len) && provided[len] == '-')
1.1368 - return 1;
1.1369 - return 0;
1.1370 -
1.1371 - case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
1.1372 - return cmp >= 0;
1.1373 -
1.1374 - case RAZOR_PROPERTY_GREATER:
1.1375 - return cmp > 0;
1.1376 - }
1.1377 -
1.1378 - /* shouldn't happen */
1.1379 - return 0;
1.1380 -}
1.1381 -
1.1382 -#define TRANS_PACKAGE_PRESENT 1
1.1383 -#define TRANS_PACKAGE_UPDATE 2
1.1384 -#define TRANS_PROPERTY_SATISFIED 0x80000000
1.1385 -
1.1386 -struct transaction_set {
1.1387 - struct razor_set *set;
1.1388 - uint32_t *packages;
1.1389 - uint32_t *properties;
1.1390 -};
1.1391 -
1.1392 -struct razor_transaction {
1.1393 - int package_count, errors;
1.1394 - struct transaction_set system, upstream;
1.1395 - int changes;
1.1396 -};
1.1397 -
1.1398 -static void
1.1399 -transaction_set_init(struct transaction_set *ts, struct razor_set *set)
1.1400 -{
1.1401 - int count;
1.1402 -
1.1403 - ts->set = set;
1.1404 - count = set->packages.size / sizeof (struct razor_package);
1.1405 - ts->packages = zalloc(count * sizeof *ts->packages);
1.1406 - count = set->properties.size / sizeof (struct razor_property);
1.1407 - ts->properties = zalloc(count * sizeof *ts->properties);
1.1408 -}
1.1409 -
1.1410 -static void
1.1411 -transaction_set_release(struct transaction_set *ts)
1.1412 -{
1.1413 - free(ts->packages);
1.1414 - free(ts->properties);
1.1415 -}
1.1416 -
1.1417 -static void
1.1418 -transaction_set_install_package(struct transaction_set *ts,
1.1419 - struct razor_package *package)
1.1420 -{
1.1421 - struct razor_package *pkgs;
1.1422 - struct list *prop;
1.1423 - int i;
1.1424 -
1.1425 - pkgs = ts->set->packages.data;
1.1426 - i = package - pkgs;
1.1427 - if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
1.1428 - return;
1.1429 -
1.1430 - ts->packages[i] = TRANS_PACKAGE_PRESENT;
1.1431 -
1.1432 - prop = list_first(&package->properties, &ts->set->property_pool);
1.1433 - while (prop) {
1.1434 - ts->properties[prop->data]++;
1.1435 - prop = list_next(prop);
1.1436 - }
1.1437 -}
1.1438 -
1.1439 -static void
1.1440 -transaction_set_remove_package(struct transaction_set *ts,
1.1441 - struct razor_package *package)
1.1442 -{
1.1443 - struct razor_package *pkgs;
1.1444 - struct list *prop;
1.1445 - int i;
1.1446 -
1.1447 - pkgs = ts->set->packages.data;
1.1448 - i = package - pkgs;
1.1449 - if (ts->packages[i] == 0)
1.1450 - return;
1.1451 -
1.1452 - ts->packages[i] = 0;
1.1453 -
1.1454 - prop = list_first(&package->properties, &ts->set->property_pool);
1.1455 - while (prop) {
1.1456 - ts->properties[prop->data]--;
1.1457 - prop = list_next(prop);
1.1458 - }
1.1459 -}
1.1460 -
1.1461 -struct razor_transaction *
1.1462 -razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
1.1463 -{
1.1464 - struct razor_transaction *trans;
1.1465 - struct razor_package *p, *spkgs, *pend;
1.1466 -
1.1467 - trans = zalloc(sizeof *trans);
1.1468 - transaction_set_init(&trans->system, system);
1.1469 - transaction_set_init(&trans->upstream, upstream);
1.1470 -
1.1471 - spkgs = trans->system.set->packages.data;
1.1472 - pend = trans->system.set->packages.data +
1.1473 - trans->system.set->packages.size;
1.1474 - for (p = spkgs; p < pend; p++)
1.1475 - transaction_set_install_package(&trans->system, p);
1.1476 -
1.1477 - return trans;
1.1478 -}
1.1479 -
1.1480 -void
1.1481 -razor_transaction_install_package(struct razor_transaction *trans,
1.1482 - struct razor_package *package)
1.1483 -{
1.1484 - transaction_set_install_package(&trans->upstream, package);
1.1485 - trans->changes++;
1.1486 -}
1.1487 -
1.1488 -void
1.1489 -razor_transaction_remove_package(struct razor_transaction *trans,
1.1490 - struct razor_package *package)
1.1491 -{
1.1492 - transaction_set_remove_package(&trans->system, package);
1.1493 - trans->changes++;
1.1494 -}
1.1495 -
1.1496 -void
1.1497 -razor_transaction_update_package(struct razor_transaction *trans,
1.1498 - struct razor_package *package)
1.1499 -{
1.1500 - struct razor_package *spkgs, *upkgs, *end;
1.1501 -
1.1502 - spkgs = trans->system.set->packages.data;
1.1503 - upkgs = trans->upstream.set->packages.data;
1.1504 - end = trans->system.set->packages.data +
1.1505 - trans->system.set->packages.size;
1.1506 - if (spkgs <= package && package < end)
1.1507 - trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
1.1508 - else
1.1509 - trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
1.1510 -}
1.1511 -
1.1512 -struct prop_iter {
1.1513 - struct razor_property *p, *start, *end;
1.1514 - const char *pool;
1.1515 - uint32_t *present;
1.1516 -};
1.1517 -
1.1518 -static void
1.1519 -prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
1.1520 -{
1.1521 - pi->p = ts->set->properties.data;
1.1522 - pi->start = ts->set->properties.data;
1.1523 - pi->end = ts->set->properties.data + ts->set->properties.size;
1.1524 - pi->pool = ts->set->string_pool.data;
1.1525 - pi->present = ts->properties;
1.1526 -}
1.1527 -
1.1528 -static int
1.1529 -prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
1.1530 -{
1.1531 - while (pi->p < pi->end) {
1.1532 - if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
1.1533 - (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
1.1534 - *p = pi->p++;
1.1535 - return 1;
1.1536 - }
1.1537 - pi->p++;
1.1538 - }
1.1539 -
1.1540 - return 0;
1.1541 -}
1.1542 -
1.1543 -static struct razor_property *
1.1544 -prop_iter_seek_to(struct prop_iter *pi,
1.1545 - uint32_t flags, const char *match)
1.1546 -{
1.1547 - uint32_t name;
1.1548 -
1.1549 - while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
1.1550 - pi->p++;
1.1551 -
1.1552 - if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
1.1553 - return NULL;
1.1554 -
1.1555 - name = pi->p->name;
1.1556 - while (pi->p < pi->end &&
1.1557 - pi->p->name == name &&
1.1558 - (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
1.1559 - pi->p++;
1.1560 -
1.1561 - if (pi->p == pi->end || pi->p->name != name)
1.1562 - return NULL;
1.1563 -
1.1564 - return pi->p;
1.1565 -}
1.1566 -
1.1567 -/* Remove packages from set that provide any of the matching (same
1.1568 - * name and type) providers from ppi onwards that match the
1.1569 - * requirement that rpi points to. */
1.1570 -static void
1.1571 -remove_matching_providers(struct razor_transaction *trans,
1.1572 - struct prop_iter *ppi,
1.1573 - uint32_t flags,
1.1574 - const char *version)
1.1575 -{
1.1576 - struct razor_property *p;
1.1577 - struct razor_package *pkg, *pkgs;
1.1578 - struct razor_package_iterator pkg_iter;
1.1579 - struct razor_set *set;
1.1580 - const char *n, *v, *a;
1.1581 - uint32_t type;
1.1582 -
1.1583 - if (ppi->present == trans->system.properties)
1.1584 - set = trans->system.set;
1.1585 - else
1.1586 - set = trans->upstream.set;
1.1587 -
1.1588 - pkgs = (struct razor_package *) set->packages.data;
1.1589 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.1590 - for (p = ppi->p;
1.1591 - p < ppi->end &&
1.1592 - p->name == ppi->p->name &&
1.1593 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.1594 - p++) {
1.1595 - if (!ppi->present[p - ppi->start])
1.1596 - continue;
1.1597 - if (!provider_satisfies_requirement(p, ppi->pool,
1.1598 - flags, version))
1.1599 - continue;
1.1600 -
1.1601 - razor_package_iterator_init_for_property(&pkg_iter, set, p);
1.1602 - while (razor_package_iterator_next(&pkg_iter,
1.1603 - &pkg, &n, &v, &a)) {
1.1604 - fprintf(stderr, "removing %s-%s\n", n, v);
1.1605 - razor_transaction_remove_package(trans, pkg);
1.1606 - }
1.1607 - }
1.1608 -}
1.1609 -
1.1610 -static void
1.1611 -flag_matching_providers(struct razor_transaction *trans,
1.1612 - struct prop_iter *ppi,
1.1613 - struct razor_property *r,
1.1614 - struct prop_iter *rpi,
1.1615 - unsigned int flag)
1.1616 -{
1.1617 - struct razor_property *p;
1.1618 - struct razor_package *pkg, *pkgs;
1.1619 - struct razor_package_iterator pkg_iter;
1.1620 - struct razor_set *set;
1.1621 - const char *name, *version, *arch;
1.1622 - uint32_t *flags, type;
1.1623 -
1.1624 - if (ppi->present == trans->system.properties) {
1.1625 - set = trans->system.set;
1.1626 - flags = trans->system.packages;
1.1627 - } else {
1.1628 - set = trans->upstream.set;
1.1629 - flags = trans->upstream.packages;
1.1630 - }
1.1631 -
1.1632 - pkgs = (struct razor_package *) set->packages.data;
1.1633 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.1634 - for (p = ppi->p;
1.1635 - p < ppi->end &&
1.1636 - p->name == ppi->p->name &&
1.1637 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.1638 - p++) {
1.1639 - if (!ppi->present[p - ppi->start])
1.1640 - continue;
1.1641 - if (!provider_satisfies_requirement(p, ppi->pool,
1.1642 - r->flags,
1.1643 - &rpi->pool[r->version]))
1.1644 - continue;
1.1645 -
1.1646 - razor_package_iterator_init_for_property(&pkg_iter, set, p);
1.1647 - while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1648 - &name, &version, &arch)) {
1.1649 -
1.1650 - fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
1.1651 - name, version,
1.1652 - ppi->pool + p->name,
1.1653 - rpi->pool + r->name,
1.1654 - rpi->pool + r->version);
1.1655 - flags[pkg - pkgs] |= flag;
1.1656 - }
1.1657 - }
1.1658 -}
1.1659 -
1.1660 -static struct razor_package *
1.1661 -pick_matching_provider(struct razor_set *set,
1.1662 - struct prop_iter *ppi,
1.1663 - uint32_t flags,
1.1664 - const char *version)
1.1665 -{
1.1666 - struct razor_property *p;
1.1667 - struct razor_package *pkgs;
1.1668 - struct list *i;
1.1669 - uint32_t type;
1.1670 -
1.1671 - /* This is where we decide which pkgs to pull in to satisfy a
1.1672 - * requirement. There may be several different providers
1.1673 - * (different versions) and each version of a provider may
1.1674 - * come from a number of packages. We pick the first package
1.1675 - * from the first provider that matches. */
1.1676 -
1.1677 - pkgs = set->packages.data;
1.1678 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.1679 - for (p = ppi->p;
1.1680 - p < ppi->end &&
1.1681 - p->name == ppi->p->name &&
1.1682 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
1.1683 - ppi->present[p - ppi->start] == 0;
1.1684 - p++) {
1.1685 - if (!provider_satisfies_requirement(p, ppi->pool,
1.1686 - flags, version))
1.1687 - continue;
1.1688 -
1.1689 - i = list_first(&p->packages, &set->package_pool);
1.1690 -
1.1691 - return &pkgs[i->data];
1.1692 - }
1.1693 -
1.1694 - return NULL;
1.1695 -}
1.1696 -
1.1697 -static void
1.1698 -remove_obsoleted_packages(struct razor_transaction *trans)
1.1699 -{
1.1700 - struct razor_property *up;
1.1701 - struct razor_package *spkgs;
1.1702 - struct prop_iter spi, upi;
1.1703 -
1.1704 - spkgs = trans->system.set->packages.data;
1.1705 - prop_iter_init(&spi, &trans->system);
1.1706 - prop_iter_init(&upi, &trans->upstream);
1.1707 -
1.1708 - while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
1.1709 - if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
1.1710 - &upi.pool[up->name]))
1.1711 - continue;
1.1712 - remove_matching_providers(trans, &spi, up->flags,
1.1713 - &upi.pool[up->version]);
1.1714 - }
1.1715 -}
1.1716 -
1.1717 -static int
1.1718 -any_provider_satisfies_requirement(struct prop_iter *ppi,
1.1719 - uint32_t flags,
1.1720 - const char *version)
1.1721 -{
1.1722 - struct razor_property *p;
1.1723 - uint32_t type;
1.1724 -
1.1725 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
1.1726 - for (p = ppi->p;
1.1727 - p < ppi->end &&
1.1728 - p->name == ppi->p->name &&
1.1729 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
1.1730 - p++) {
1.1731 - if (ppi->present[p - ppi->start] > 0 &&
1.1732 - provider_satisfies_requirement(p, ppi->pool,
1.1733 - flags, version))
1.1734 - return 1;
1.1735 - }
1.1736 -
1.1737 - return 0;
1.1738 -}
1.1739 -
1.1740 -static void
1.1741 -clear_requires_flags(struct transaction_set *ts)
1.1742 -{
1.1743 - struct razor_property *p;
1.1744 - const char *pool;
1.1745 - int i, count;
1.1746 -
1.1747 - count = ts->set->properties.size / sizeof *p;
1.1748 - p = ts->set->properties.data;
1.1749 - pool = ts->set->string_pool.data;
1.1750 - for (i = 0; i < count; i++) {
1.1751 - ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
1.1752 - if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
1.1753 - ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
1.1754 - }
1.1755 -}
1.1756 -
1.1757 -const char *
1.1758 -razor_property_relation_to_string(struct razor_property *p)
1.1759 -{
1.1760 - switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
1.1761 - case RAZOR_PROPERTY_LESS:
1.1762 - return "<";
1.1763 -
1.1764 - case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
1.1765 - return "<=";
1.1766 -
1.1767 - case RAZOR_PROPERTY_EQUAL:
1.1768 - return "=";
1.1769 -
1.1770 - case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
1.1771 - return ">=";
1.1772 -
1.1773 - case RAZOR_PROPERTY_GREATER:
1.1774 - return ">";
1.1775 -
1.1776 - default:
1.1777 - return "?";
1.1778 - }
1.1779 -}
1.1780 -
1.1781 -const char *
1.1782 -razor_property_type_to_string(struct razor_property *p)
1.1783 -{
1.1784 - switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
1.1785 - case RAZOR_PROPERTY_REQUIRES:
1.1786 - return "requires";
1.1787 - case RAZOR_PROPERTY_PROVIDES:
1.1788 - return "provides";
1.1789 - case RAZOR_PROPERTY_CONFLICTS:
1.1790 - return "conflicts";
1.1791 - case RAZOR_PROPERTY_OBSOLETES:
1.1792 - return "obsoletes";
1.1793 - default:
1.1794 - return NULL;
1.1795 - }
1.1796 -}
1.1797 -
1.1798 -static void
1.1799 -mark_satisfied_requires(struct razor_transaction *trans,
1.1800 - struct transaction_set *rts,
1.1801 - struct transaction_set *pts)
1.1802 -{
1.1803 - struct prop_iter rpi, ppi;
1.1804 - struct razor_property *rp;
1.1805 -
1.1806 - prop_iter_init(&rpi, rts);
1.1807 - prop_iter_init(&ppi, pts);
1.1808 -
1.1809 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1810 - if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
1.1811 - &rpi.pool[rp->name]))
1.1812 - continue;
1.1813 -
1.1814 - if (any_provider_satisfies_requirement(&ppi, rp->flags,
1.1815 - &rpi.pool[rp->version]))
1.1816 - rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
1.1817 - }
1.1818 -}
1.1819 -
1.1820 -static void
1.1821 -mark_all_satisfied_requires(struct razor_transaction *trans)
1.1822 -{
1.1823 - clear_requires_flags(&trans->system);
1.1824 - clear_requires_flags(&trans->upstream);
1.1825 - mark_satisfied_requires(trans, &trans->system, &trans->system);
1.1826 - mark_satisfied_requires(trans, &trans->system, &trans->upstream);
1.1827 - mark_satisfied_requires(trans, &trans->upstream, &trans->system);
1.1828 - mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
1.1829 -}
1.1830 -
1.1831 -static void
1.1832 -update_unsatisfied_packages(struct razor_transaction *trans)
1.1833 -{
1.1834 - struct razor_package *spkgs, *pkg;
1.1835 - struct razor_property *sp;
1.1836 - struct prop_iter spi;
1.1837 - struct razor_package_iterator pkg_iter;
1.1838 - const char *name, *version, *arch;
1.1839 -
1.1840 - spkgs = trans->system.set->packages.data;
1.1841 - prop_iter_init(&spi, &trans->system);
1.1842 -
1.1843 - while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
1.1844 - if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
1.1845 - continue;
1.1846 -
1.1847 - razor_package_iterator_init_for_property(&pkg_iter,
1.1848 - trans->system.set,
1.1849 - sp);
1.1850 - while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1851 - &name, &version, &arch)) {
1.1852 - fprintf(stderr, "updating %s because %s %s %s "
1.1853 - "isn't satisfied\n",
1.1854 - name, spi.pool + sp->name,
1.1855 - razor_property_relation_to_string(sp),
1.1856 - spi.pool + sp->version);
1.1857 - trans->system.packages[pkg - spkgs] |=
1.1858 - TRANS_PACKAGE_UPDATE;
1.1859 - }
1.1860 - }
1.1861 -}
1.1862 -
1.1863 -void
1.1864 -razor_transaction_update_all(struct razor_transaction *trans)
1.1865 -{
1.1866 - struct razor_package *p;
1.1867 - int i, count;
1.1868 -
1.1869 - count = trans->system.set->packages.size / sizeof *p;
1.1870 - for (i = 0; i < count; i++)
1.1871 - trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
1.1872 -}
1.1873 -
1.1874 -static void
1.1875 -update_conflicted_packages(struct razor_transaction *trans)
1.1876 -{
1.1877 - struct razor_package *pkg, *spkgs;
1.1878 - struct razor_property *up, *sp;
1.1879 - struct prop_iter spi, upi;
1.1880 - struct razor_package_iterator pkg_iter;
1.1881 - const char *name, *version, *arch;
1.1882 -
1.1883 - spkgs = trans->system.set->packages.data;
1.1884 - prop_iter_init(&spi, &trans->system);
1.1885 - prop_iter_init(&upi, &trans->upstream);
1.1886 -
1.1887 - while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
1.1888 - if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
1.1889 - &spi.pool[sp->name]))
1.1890 - continue;
1.1891 -
1.1892 - if (!any_provider_satisfies_requirement(&upi, sp->flags,
1.1893 - &spi.pool[sp->version]))
1.1894 - continue;
1.1895 -
1.1896 - razor_package_iterator_init_for_property(&pkg_iter,
1.1897 - trans->system.set,
1.1898 - sp);
1.1899 - while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1900 - &name, &version, &arch)) {
1.1901 - fprintf(stderr, "updating %s %s because it conflicts with %s",
1.1902 - name, version, spi.pool + sp->name);
1.1903 - trans->system.packages[pkg - spkgs] |=
1.1904 - TRANS_PACKAGE_UPDATE;
1.1905 - }
1.1906 - }
1.1907 -
1.1908 - prop_iter_init(&spi, &trans->system);
1.1909 - prop_iter_init(&upi, &trans->upstream);
1.1910 -
1.1911 - while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
1.1912 - sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
1.1913 - &upi.pool[upi.p->name]);
1.1914 -
1.1915 - if (sp)
1.1916 - flag_matching_providers(trans, &spi, up, &upi,
1.1917 - TRANS_PACKAGE_UPDATE);
1.1918 - }
1.1919 -}
1.1920 -
1.1921 -static void
1.1922 -pull_in_requirements(struct razor_transaction *trans,
1.1923 - struct prop_iter *rpi, struct prop_iter *ppi)
1.1924 -{
1.1925 - struct razor_property *rp, *pp;
1.1926 - struct razor_package *pkg, *upkgs;
1.1927 -
1.1928 - upkgs = trans->upstream.set->packages.data;
1.1929 - while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1930 - if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
1.1931 - continue;
1.1932 -
1.1933 - pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
1.1934 - &rpi->pool[rp->name]);
1.1935 - if (pp == NULL)
1.1936 - continue;
1.1937 - pkg = pick_matching_provider(trans->upstream.set,
1.1938 - ppi, rp->flags,
1.1939 - &rpi->pool[rp->version]);
1.1940 - if (pkg == NULL)
1.1941 - continue;
1.1942 -
1.1943 - rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
1.1944 -
1.1945 - fprintf(stderr, "pulling in %s which provides %s %s %s "
1.1946 - "to satisfy %s %s %s\n",
1.1947 - ppi->pool + pkg->name,
1.1948 - ppi->pool + pp->name,
1.1949 - razor_property_relation_to_string(pp),
1.1950 - ppi->pool + pp->version,
1.1951 - &rpi->pool[rp->name],
1.1952 - razor_property_relation_to_string(rp),
1.1953 - &rpi->pool[rp->version]);
1.1954 -
1.1955 - trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
1.1956 - }
1.1957 -}
1.1958 -
1.1959 -static void
1.1960 -pull_in_all_requirements(struct razor_transaction *trans)
1.1961 -{
1.1962 - struct prop_iter rpi, ppi;
1.1963 -
1.1964 - prop_iter_init(&rpi, &trans->system);
1.1965 - prop_iter_init(&ppi, &trans->upstream);
1.1966 - pull_in_requirements(trans, &rpi, &ppi);
1.1967 -
1.1968 - prop_iter_init(&rpi, &trans->upstream);
1.1969 - prop_iter_init(&ppi, &trans->upstream);
1.1970 - pull_in_requirements(trans, &rpi, &ppi);
1.1971 -}
1.1972 -
1.1973 -static void
1.1974 -flush_scheduled_system_updates(struct razor_transaction *trans)
1.1975 -{
1.1976 - struct razor_package_iterator *pi;
1.1977 - struct razor_package *p, *pkg, *spkgs;
1.1978 - struct prop_iter ppi;
1.1979 - const char *name, *version, *arch;
1.1980 -
1.1981 - spkgs = trans->system.set->packages.data;
1.1982 - pi = razor_package_iterator_create(trans->system.set);
1.1983 - prop_iter_init(&ppi, &trans->upstream);
1.1984 -
1.1985 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
1.1986 - if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
1.1987 - continue;
1.1988 -
1.1989 - if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
1.1990 - continue;
1.1991 -
1.1992 - pkg = pick_matching_provider(trans->upstream.set, &ppi,
1.1993 - RAZOR_PROPERTY_GREATER, version);
1.1994 - if (pkg == NULL)
1.1995 - continue;
1.1996 -
1.1997 - fprintf(stderr, "updating %s-%s to %s-%s\n",
1.1998 - name, version,
1.1999 - &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
1.2000 -
1.2001 - razor_transaction_remove_package(trans, p);
1.2002 - razor_transaction_install_package(trans, pkg);
1.2003 - }
1.2004 -
1.2005 - razor_package_iterator_destroy(pi);
1.2006 -}
1.2007 -
1.2008 -static void
1.2009 -flush_scheduled_upstream_updates(struct razor_transaction *trans)
1.2010 -{
1.2011 - struct razor_package_iterator *pi;
1.2012 - struct razor_package *p, *upkgs;
1.2013 - struct prop_iter spi;
1.2014 - const char *name, *version, *arch;
1.2015 -
1.2016 - upkgs = trans->upstream.set->packages.data;
1.2017 - pi = razor_package_iterator_create(trans->upstream.set);
1.2018 - prop_iter_init(&spi, &trans->system);
1.2019 -
1.2020 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
1.2021 - if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
1.2022 - continue;
1.2023 -
1.2024 - if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
1.2025 - remove_matching_providers(trans,
1.2026 - &spi,
1.2027 - RAZOR_PROPERTY_LESS,
1.2028 - version);
1.2029 - razor_transaction_install_package(trans, p);
1.2030 - fprintf(stderr, "installing %s-%s\n", name, version);
1.2031 - }
1.2032 -}
1.2033 -
1.2034 -int
1.2035 -razor_transaction_resolve(struct razor_transaction *trans)
1.2036 -{
1.2037 - int last = 0;
1.2038 -
1.2039 - flush_scheduled_system_updates(trans);
1.2040 - flush_scheduled_upstream_updates(trans);
1.2041 -
1.2042 - while (last < trans->changes) {
1.2043 - last = trans->changes;
1.2044 - remove_obsoleted_packages(trans);
1.2045 - mark_all_satisfied_requires(trans);
1.2046 - update_unsatisfied_packages(trans);
1.2047 - update_conflicted_packages(trans);
1.2048 - pull_in_all_requirements(trans);
1.2049 - flush_scheduled_system_updates(trans);
1.2050 - flush_scheduled_upstream_updates(trans);
1.2051 - }
1.2052 -
1.2053 - return trans->changes;
1.2054 -}
1.2055 -
1.2056 -static void
1.2057 -describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
1.2058 -{
1.2059 - struct razor_package_iterator pi;
1.2060 - struct razor_package *pkg;
1.2061 - const char *name, *version, *arch, *pool;
1.2062 -
1.2063 - pool = set->string_pool.data;
1.2064 - if (pool[rp->version] == '\0') {
1.2065 - razor_package_iterator_init_for_property(&pi, set, rp);
1.2066 - while (razor_package_iterator_next(&pi, &pkg,
1.2067 - &name, &version, &arch))
1.2068 - fprintf(stderr, "%s is needed by %s-%s.%s\n",
1.2069 - &pool[rp->name],
1.2070 - name, version, arch);
1.2071 - } else {
1.2072 - razor_package_iterator_init_for_property(&pi, set, rp);
1.2073 - while (razor_package_iterator_next(&pi, &pkg,
1.2074 - &name, &version, &arch))
1.2075 - fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
1.2076 - &pool[rp->name],
1.2077 - razor_property_relation_to_string(rp),
1.2078 - &pool[rp->version],
1.2079 - name, version, arch);
1.2080 - }
1.2081 -}
1.2082 -
1.2083 -int
1.2084 -razor_transaction_describe(struct razor_transaction *trans)
1.2085 -{
1.2086 - struct prop_iter rpi;
1.2087 - struct razor_property *rp;
1.2088 - int unsatisfied;
1.2089 -
1.2090 - flush_scheduled_system_updates(trans);
1.2091 - flush_scheduled_upstream_updates(trans);
1.2092 - mark_all_satisfied_requires(trans);
1.2093 -
1.2094 - unsatisfied = 0;
1.2095 - prop_iter_init(&rpi, &trans->system);
1.2096 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.2097 - if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
1.2098 - describe_unsatisfied(trans->system.set, rp);
1.2099 - unsatisfied++;
1.2100 - }
1.2101 - }
1.2102 -
1.2103 - prop_iter_init(&rpi, &trans->upstream);
1.2104 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.2105 - if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
1.2106 - describe_unsatisfied(trans->upstream.set, rp);
1.2107 - unsatisfied++;
1.2108 - }
1.2109 - }
1.2110 -
1.2111 - return unsatisfied;
1.2112 -}
1.2113 -
1.2114 -int
1.2115 -razor_transaction_unsatisfied_property(struct razor_transaction *trans,
1.2116 - const char *name,
1.2117 - uint32_t flags,
1.2118 - const char *version)
1.2119 -{
1.2120 - struct prop_iter pi;
1.2121 - struct razor_property *p;
1.2122 -
1.2123 - prop_iter_init(&pi, &trans->system);
1.2124 - while (prop_iter_next(&pi, flags, &p)) {
1.2125 - if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.2126 - p->flags == flags &&
1.2127 - strcmp(&pi.pool[p->name], name) == 0 &&
1.2128 - strcmp(&pi.pool[p->version], version) == 0)
1.2129 -
1.2130 - return 1;
1.2131 - }
1.2132 -
1.2133 - prop_iter_init(&pi, &trans->upstream);
1.2134 - while (prop_iter_next(&pi, flags, &p)) {
1.2135 - if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.2136 - p->flags == flags &&
1.2137 - strcmp(&pi.pool[p->name], name) == 0 &&
1.2138 - strcmp(&pi.pool[p->version], version) == 0)
1.2139 -
1.2140 - return 1;
1.2141 - }
1.2142 -
1.2143 - return 0;
1.2144 -}
1.2145 -
1.2146 -struct razor_set *
1.2147 -razor_transaction_finish(struct razor_transaction *trans)
1.2148 -{
1.2149 - struct razor_merger *merger;
1.2150 - struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
1.2151 - char *upool, *spool;
1.2152 - int cmp;
1.2153 -
1.2154 - s = trans->system.set->packages.data;
1.2155 - spkgs = trans->system.set->packages.data;
1.2156 - send = trans->system.set->packages.data +
1.2157 - trans->system.set->packages.size;
1.2158 - spool = trans->system.set->string_pool.data;
1.2159 -
1.2160 - u = trans->upstream.set->packages.data;
1.2161 - upkgs = trans->upstream.set->packages.data;
1.2162 - uend = trans->upstream.set->packages.data +
1.2163 - trans->upstream.set->packages.size;
1.2164 - upool = trans->upstream.set->string_pool.data;
1.2165 -
1.2166 - merger = razor_merger_create(trans->system.set, trans->upstream.set);
1.2167 - while (s < send || u < uend) {
1.2168 - if (s < send && u < uend)
1.2169 - cmp = strcmp(&spool[s->name], &upool[u->name]);
1.2170 - else if (s < send)
1.2171 - cmp = -1;
1.2172 - else
1.2173 - cmp = 1;
1.2174 -
1.2175 - if (cmp < 0) {
1.2176 - if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
1.2177 - razor_merger_add_package(merger, s);
1.2178 - s++;
1.2179 - } else if (cmp == 0) {
1.2180 - if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
1.2181 - razor_merger_add_package(merger, s);
1.2182 - if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
1.2183 - razor_merger_add_package(merger, u);
1.2184 -
1.2185 - s++;
1.2186 - u++;
1.2187 - } else {
1.2188 - if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
1.2189 - razor_merger_add_package(merger, u);
1.2190 - u++;
1.2191 - }
1.2192 - }
1.2193 -
1.2194 - razor_transaction_destroy(trans);
1.2195 -
1.2196 - return razor_merger_finish(merger);
1.2197 -}
1.2198 -
1.2199 -void
1.2200 -razor_transaction_destroy(struct razor_transaction *trans)
1.2201 -{
1.2202 - transaction_set_release(&trans->system);
1.2203 - transaction_set_release(&trans->upstream);
1.2204 - free(trans);
1.2205 -}
1.2206 -
1.2207 -struct razor_package_query {
1.2208 - struct razor_set *set;
1.2209 - char *vector;
1.2210 - int count;
1.2211 -};
1.2212 -
1.2213 -struct razor_package_query *
1.2214 -razor_package_query_create(struct razor_set *set)
1.2215 -{
1.2216 - struct razor_package_query *pq;
1.2217 - int count;
1.2218 -
1.2219 - pq = zalloc(sizeof *pq);
1.2220 - pq->set = set;
1.2221 - count = set->packages.size / sizeof(struct razor_package);
1.2222 - pq->vector = zalloc(count * sizeof(char));
1.2223 -
1.2224 - return pq;
1.2225 -}
1.2226 -
1.2227 -void
1.2228 -razor_package_query_add_package(struct razor_package_query *pq,
1.2229 - struct razor_package *p)
1.2230 -{
1.2231 - struct razor_package *packages;
1.2232 -
1.2233 - packages = pq->set->packages.data;
1.2234 - pq->count += pq->vector[p - packages] ^ 1;
1.2235 - pq->vector[p - packages] = 1;
1.2236 -}
1.2237 -
1.2238 -void
1.2239 -razor_package_query_add_iterator(struct razor_package_query *pq,
1.2240 - struct razor_package_iterator *pi)
1.2241 -{
1.2242 - struct razor_package *packages, *p;
1.2243 - const char *name, *version, *arch;
1.2244 -
1.2245 - packages = pq->set->packages.data;
1.2246 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
1.2247 - pq->count += pq->vector[p - packages] ^ 1;
1.2248 - pq->vector[p - packages] = 1;
1.2249 - }
1.2250 -}
1.2251 -
1.2252 -struct razor_package_iterator *
1.2253 -razor_package_query_finish(struct razor_package_query *pq)
1.2254 -{
1.2255 - struct razor_package_iterator *pi;
1.2256 - struct razor_set *set;
1.2257 - struct list *index;
1.2258 - int i, j, count;
1.2259 -
1.2260 - set = pq->set;
1.2261 - count = set->packages.size / sizeof(struct razor_package);
1.2262 - index = zalloc(pq->count * sizeof *index);
1.2263 -
1.2264 - for (i = 0, j = 0; i < count; i++) {
1.2265 - if (!pq->vector[i])
1.2266 - continue;
1.2267 -
1.2268 - index[j].data = i;
1.2269 - if (j == pq->count - 1)
1.2270 - index[j].flags = 0x80;
1.2271 - j++;
1.2272 - }
1.2273 -
1.2274 - free(pq);
1.2275 -
1.2276 - pi = razor_package_iterator_create_with_index(set, index);
1.2277 - pi->free_index = 1;
1.2278 -
1.2279 - return pi;
1.2280 -}