1.1 --- a/razor.c Wed Jun 04 20:53:17 2008 -0400
1.2 +++ b/razor.c Mon Jun 09 16:14:05 2008 -0400
1.3 @@ -839,6 +839,16 @@
1.4 return pi;
1.5 }
1.6
1.7 +static void
1.8 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
1.9 + struct razor_set *set,
1.10 + struct razor_property *property)
1.11 +{
1.12 + memset(pi, 0, sizeof *pi);
1.13 + pi->set = set;
1.14 + pi->index = list_first(&property->packages, &set->package_pool);
1.15 +}
1.16 +
1.17 struct razor_package_iterator *
1.18 razor_package_iterator_create_for_property(struct razor_set *set,
1.19 struct razor_property *property)
1.20 @@ -1140,82 +1150,6 @@
1.21 list_package_files(set, r, set->files.data, end, buffer);
1.22 }
1.23
1.24 -static void
1.25 -razor_set_validate(struct razor_set *set, struct array *unsatisfied)
1.26 -{
1.27 - struct razor_property *r, *p, *end;
1.28 - uint32_t *u;
1.29 - char *pool;
1.30 -
1.31 - end = set->properties.data + set->properties.size;
1.32 - pool = set->string_pool.data;
1.33 -
1.34 - for (r = set->properties.data, p = r; r < end; r++) {
1.35 - if (r->type != RAZOR_PROPERTY_REQUIRES)
1.36 - continue;
1.37 -
1.38 - p = r;
1.39 - while (p < end && p->name == r->name &&
1.40 - p->type == r->type)
1.41 - p++;
1.42 -
1.43 - /* If there is more than one version of a provides,
1.44 - * seek to the end for the highest version. */
1.45 - /* FIXME: This doesn't work if we have a series of
1.46 - * requires a = 1, provides a = 1, requires a = 2,
1.47 - * provides a = 2, as the kernel and kernel-devel
1.48 - * does.*/
1.49 - while (p + 1 < end && p->name == (p + 1)->name &&
1.50 - p->type == (p + 1)->type)
1.51 - p++;
1.52 -
1.53 - /* FIXME: We need to track property flags (<, <=, =
1.54 - * etc) to properly determine if a requires is
1.55 - * satisfied. The current code doesn't track that the
1.56 - * requires a = 1 isn't satisfied by a = 2 provides. */
1.57 -
1.58 - if (p == end ||
1.59 - p->type != RAZOR_PROPERTY_PROVIDES ||
1.60 - r->name != p->name ||
1.61 - versioncmp(&pool[r->version], &pool[p->version]) > 0) {
1.62 - /* FIXME: We ignore file requires for now. */
1.63 - if (pool[r->name] == '/')
1.64 - continue;
1.65 - u = array_add(unsatisfied, sizeof *u);
1.66 - *u = r - (struct razor_property *) set->properties.data;
1.67 - }
1.68 - }
1.69 -}
1.70 -
1.71 -void
1.72 -razor_set_list_unsatisfied(struct razor_set *set)
1.73 -{
1.74 - struct array unsatisfied;
1.75 - struct razor_property *properties, *r;
1.76 - uint32_t *u, *end;
1.77 - char *pool;
1.78 -
1.79 - array_init(&unsatisfied);
1.80 - razor_set_validate(set, &unsatisfied);
1.81 -
1.82 - end = unsatisfied.data + unsatisfied.size;
1.83 - properties = set->properties.data;
1.84 - pool = set->string_pool.data;
1.85 -
1.86 - for (u = unsatisfied.data; u < end; u++) {
1.87 - r = properties + *u;
1.88 - if (pool[r->version] == '\0')
1.89 - printf("%s not satisfied\n",
1.90 - &pool[r->name]);
1.91 - else
1.92 - printf("%s-%s not satisfied\n",
1.93 - &pool[r->name],
1.94 - &pool[r->version]);
1.95 - }
1.96 -
1.97 - array_release(&unsatisfied);
1.98 -}
1.99 -
1.100 #define UPSTREAM_SOURCE 0x80
1.101
1.102 struct source {
1.103 @@ -1262,13 +1196,25 @@
1.104 }
1.105
1.106 static void
1.107 -add_package(struct razor_merger *merger,
1.108 - struct razor_package *package, struct source *source,
1.109 - uint32_t flags)
1.110 +razor_merger_add_package(struct razor_merger *merger,
1.111 + struct razor_package *package)
1.112 {
1.113 char *pool;
1.114 struct list *r;
1.115 struct razor_package *p;
1.116 + struct razor_set *set1;
1.117 + struct source *source;
1.118 + uint32_t flags;
1.119 +
1.120 + set1 = merger->source1.set;
1.121 + if (set1->packages.data <= (void *) package &&
1.122 + (void *) package < set1->packages.data + set1->packages.size) {
1.123 + source = &merger->source1;
1.124 + flags = 0;
1.125 + } else {
1.126 + source = &merger->source2;
1.127 + flags = UPSTREAM_SOURCE;
1.128 + }
1.129
1.130 pool = source->set->string_pool.data;
1.131 p = array_add(&merger->set->packages, sizeof *p);
1.132 @@ -1723,8 +1669,8 @@
1.133 razor_set_diff(struct razor_set *set, struct razor_set *upstream,
1.134 razor_package_callback_t callback, void *data)
1.135 {
1.136 - struct razor_package_iterator *pi1, *pi2;
1.137 - struct razor_package *p1, *p2;
1.138 + struct razor_package_iterator *pi1, *pi2;
1.139 + struct razor_package *p1, *p2;
1.140 const char *name1, *name2, *version1, *version2, *arch1, *arch2;
1.141 int res;
1.142
1.143 @@ -1760,232 +1706,19 @@
1.144 razor_package_iterator_destroy(pi2);
1.145 }
1.146
1.147 -struct razor_transaction;
1.148 -struct razor_transaction_package;
1.149 -struct razor_transaction_resolver;
1.150 -
1.151 -struct razor_transaction {
1.152 - int package_count, errors;
1.153 - struct razor_set *system, *upstream;
1.154 -
1.155 - struct bitarray syspkgs, uppkgs;
1.156 - struct array packages;
1.157 -};
1.158 -
1.159 -struct razor_transaction_package {
1.160 - const char *name, *old_version, *new_version;
1.161 - struct razor_package *old_package, *new_package;
1.162 - enum razor_transaction_package_state state;
1.163 -
1.164 - /* dep_package is the name of the package that resulted in
1.165 - * this entry being created (or NULL if the user requested the
1.166 - * install/remove), with the other dep_ fields providing
1.167 - * additional information.
1.168 - *
1.169 - * For INSTALL, if dep_type is REQUIRES, then dep_package
1.170 - * required something that this package provides. If dep_type
1.171 - * is CONFLICTS, then dep_package is a package that conflicted
1.172 - * with an older version of this package, forcing an upgrade.
1.173 - *
1.174 - * For REMOVE, if dep_type is REQUIRES, then dep_package is a
1.175 - * package that is being removed. If dep_type is OBSOLETES,
1.176 - * then dep_package is a package that obsoletes this one.
1.177 - *
1.178 - * For OLD_CONFLICT or NEW_CONFLICT, dep_package is an
1.179 - * existing package that conflicts with this one. The
1.180 - * conflicting property comes from the already-installed
1.181 - * package for OLD_CONFLICT, or the to-be-installed package
1.182 - * for NEW_CONFLICT.
1.183 - *
1.184 - * For UNSATISFIABLE, the dep_ fields are as for an INSTALL,
1.185 - * but the name field will be NULL.
1.186 - */
1.187 - const char *dep_package;
1.188 - enum razor_property_type dep_type;
1.189 - const char *dep_property;
1.190 - enum razor_version_relation dep_relation;
1.191 - const char *dep_version;
1.192 -};
1.193 -
1.194 -static int
1.195 -package_in_set(void *package, struct razor_set *set)
1.196 -{
1.197 - return package >= set->packages.data &&
1.198 - package < set->packages.data + set->packages.size;
1.199 -}
1.200 -
1.201 -static int
1.202 -property_in_set(void *property, struct razor_set *set)
1.203 -{
1.204 - return property >= set->properties.data &&
1.205 - property < set->properties.data + set->properties.size;
1.206 -}
1.207 -
1.208 -static struct razor_package *
1.209 -property_provider_package(struct razor_transaction *trans,
1.210 - struct razor_property *prop,
1.211 - int installed)
1.212 -{
1.213 - struct razor_set *set;
1.214 - struct bitarray *pkgbits;
1.215 - struct razor_package *pkgs;
1.216 - struct list *p;
1.217 -
1.218 - if (installed && prop->type != RAZOR_PROPERTY_PROVIDES)
1.219 - return NULL;
1.220 - else if (!installed &&
1.221 - prop->type != RAZOR_PROPERTY_PROVIDES &&
1.222 - prop->type != RAZOR_PROPERTY_OBSOLETES)
1.223 - return NULL;
1.224 -
1.225 - if (property_in_set(prop, trans->system)) {
1.226 - set = trans->system;
1.227 - pkgbits = &trans->syspkgs;
1.228 - } else {
1.229 - set = trans->upstream;
1.230 - pkgbits = &trans->uppkgs;
1.231 - }
1.232 - pkgs = set->packages.data;
1.233 -
1.234 - for (p = list_first(&prop->packages, &set->package_pool); p; p = list_next(p)) {
1.235 - if (bitarray_get(pkgbits, p->data) != installed)
1.236 - continue;
1.237 - if (prop->type == RAZOR_PROPERTY_OBSOLETES ||
1.238 - pkgs[p->data].name == prop->name)
1.239 - return &pkgs[p->data];
1.240 - }
1.241 - return NULL;
1.242 -}
1.243 -
1.244 -static int
1.245 -compare_transaction_packages(const void *one, const void *two)
1.246 -{
1.247 - struct razor_transaction_package **tp1 = (void *)one;
1.248 - struct razor_transaction_package **tp2 = (void *)two;
1.249 -
1.250 - if (!(*tp1)->name)
1.251 - return 1;
1.252 - else if (!(*tp2)->name)
1.253 - return -1;
1.254 - else
1.255 - return strcmp((*tp1)->name, (*tp2)->name);
1.256 -}
1.257 -
1.258 -/* FIXME: merge this into the other property loop in razor_transaction_satisfy */
1.259 -static void
1.260 -resolve_new_packages(struct razor_transaction *trans,
1.261 - int start, int end)
1.262 -{
1.263 - struct razor_property *sp, *up, *sp_end, *up_end;
1.264 - struct razor_package *spkg, *spkgs, *upkg, *upkgs;
1.265 - struct razor_transaction_package **packages;
1.266 - const char *spool, *upool;
1.267 - int i;
1.268 -
1.269 - sp_end = trans->system->properties.data + trans->system->properties.size;
1.270 - spool = trans->system->string_pool.data;
1.271 - spkgs = trans->system->packages.data;
1.272 - up_end = trans->upstream->properties.data + trans->upstream->properties.size;
1.273 - upool = trans->upstream->string_pool.data;
1.274 - upkgs = trans->upstream->packages.data;
1.275 -
1.276 - /* FIXME, check if sorting the packages directly (rather than
1.277 - * sorting pointers-to-packages) still results in confusing
1.278 - * descriptions.
1.279 - */
1.280 - packages = calloc(end - start, sizeof *packages);
1.281 - for (i = start; i < end; i++)
1.282 - packages[i - start] = ((struct razor_transaction_package *)trans->packages.data) + i;
1.283 - qsort(packages, end - start, sizeof *packages,
1.284 - compare_transaction_packages);
1.285 -
1.286 - sp = trans->system->properties.data;
1.287 - up = trans->upstream->properties.data;
1.288 - for (i = 0; i < end - start; i++) {
1.289 - if (!packages[i]->name ||
1.290 - packages[i]->state >= RAZOR_PACKAGE_FIRST_ERROR_STATE)
1.291 - continue;
1.292 -
1.293 - spkg = NULL;
1.294 - while (sp < sp_end &&
1.295 - strcmp(&spool[sp->name], packages[i]->name) < 0)
1.296 - sp++;
1.297 - while (sp < sp_end &&
1.298 - strcmp(&spool[sp->name], packages[i]->name) == 0 &&
1.299 - !(spkg = property_provider_package(trans, sp, 1)))
1.300 - sp++;
1.301 -
1.302 - upkg = NULL;
1.303 - while (up < up_end &&
1.304 - strcmp(&upool[up->name], packages[i]->name) < 0)
1.305 - up++;
1.306 - while (up < up_end &&
1.307 - strcmp(&upool[up->name], packages[i]->name) == 0 &&
1.308 - !(upkg = property_provider_package(trans, up, 0)))
1.309 - up++;
1.310 -
1.311 - if (packages[i]->state == RAZOR_PACKAGE_REMOVE ||
1.312 - packages[i]->state == RAZOR_PACKAGE_OBSOLETED) {
1.313 - if (spkg) {
1.314 - packages[i]->old_package = spkg;
1.315 - packages[i]->name = &spool[spkg->name];
1.316 - packages[i]->old_version = &spool[spkg->version];
1.317 - bitarray_set(&trans->syspkgs, spkg - spkgs, 0);
1.318 - }
1.319 - if (!packages[i]->old_package) {
1.320 - packages[i]->name = strdup(packages[i]->name);
1.321 - packages[i]->state |= RAZOR_PACKAGE_UNAVAILABLE_FLAG;
1.322 - trans->errors++;
1.323 - }
1.324 - } else {
1.325 - if (upkg) {
1.326 - packages[i]->new_package = upkg;
1.327 - packages[i]->name = &upool[upkg->name];
1.328 - packages[i]->new_version = &upool[upkg->version];
1.329 -
1.330 - if (up->name != upkg->name) {
1.331 - packages[i]->dep_package = &upool[upkg->name];
1.332 - packages[i]->dep_type = up->type;
1.333 - packages[i]->dep_property = &upool[up->name];
1.334 - packages[i]->dep_relation = up->relation;
1.335 - packages[i]->dep_version = &upool[up->version];
1.336 - }
1.337 -
1.338 - if (spkg) {
1.339 - packages[i]->old_package = spkg;
1.340 - packages[i]->old_version = &spool[spkg->version];
1.341 - if (versioncmp(&spool[spkg->version], &upool[up->version]) >= 0) {
1.342 - packages[i]->state = RAZOR_PACKAGE_UP_TO_DATE;
1.343 - trans->errors++;
1.344 - continue;
1.345 - }
1.346 - bitarray_set(&trans->syspkgs, spkg - spkgs, 0);
1.347 - }
1.348 - bitarray_set(&trans->uppkgs, upkg - upkgs, 1);
1.349 - }
1.350 - if (!packages[i]->new_package) {
1.351 - packages[i]->name = strdup(packages[i]->name);
1.352 - packages[i]->state |= RAZOR_PACKAGE_UNAVAILABLE_FLAG;
1.353 - trans->errors++;
1.354 - }
1.355 - }
1.356 - }
1.357 -}
1.358 -
1.359 static int
1.360 provider_satisfies_requirement(struct razor_property *provider,
1.361 const char *provider_strings,
1.362 - struct razor_property *requirement,
1.363 - const char *requirement_strings)
1.364 + enum razor_version_relation relation,
1.365 + const char *required)
1.366 {
1.367 int cmp, len;
1.368 const char *provided = &provider_strings[provider->version];
1.369 - const char *required = &requirement_strings[requirement->version];
1.370
1.371 if (!*required)
1.372 return 1;
1.373 if (!*provided) {
1.374 - if (requirement->relation >= RAZOR_VERSION_EQUAL)
1.375 + if (relation >= RAZOR_VERSION_EQUAL)
1.376 return 1;
1.377 else
1.378 return 0;
1.379 @@ -1993,7 +1726,7 @@
1.380
1.381 cmp = versioncmp(provided, required);
1.382
1.383 - switch (requirement->relation) {
1.384 + switch (relation) {
1.385 case RAZOR_VERSION_LESS:
1.386 return cmp < 0;
1.387
1.388 @@ -2023,614 +1756,82 @@
1.389 return 0;
1.390 }
1.391
1.392 -static struct razor_package *
1.393 -find_package_for_file(struct razor_set *set, struct bitarray *pkgbits,
1.394 - const char *filename, int installed)
1.395 +#define TRANS_PACKAGE_PRESENT 1
1.396 +#define TRANS_PACKAGE_UPDATE 2
1.397 +#define TRANS_PROPERTY_SATISFIED 0x80000000
1.398 +
1.399 +struct transaction_set {
1.400 + struct razor_set *set;
1.401 + uint32_t *packages;
1.402 + uint32_t *properties;
1.403 +};
1.404 +
1.405 +struct razor_transaction {
1.406 + int package_count, errors;
1.407 + struct transaction_set system, upstream;
1.408 + int changes;
1.409 +};
1.410 +
1.411 +static void
1.412 +transaction_set_init(struct transaction_set *ts, struct razor_set *set)
1.413 {
1.414 - struct razor_package *pkgs = set->packages.data;
1.415 - struct razor_entry *entry;
1.416 - struct list *p;
1.417 + int count;
1.418
1.419 - if (filename[0] != '/')
1.420 - return 0;
1.421 -
1.422 - entry = find_entry(set, set->files.data, filename);
1.423 - if (!entry)
1.424 - return 0;
1.425 -
1.426 - for (p = list_first(&entry->packages, &set->package_pool); p; p = list_next(p)) {
1.427 - if (bitarray_get(pkgbits, p->data) == installed)
1.428 - return &pkgs[p->data];
1.429 - }
1.430 - return NULL;
1.431 -}
1.432 -
1.433 -static struct razor_package *
1.434 -find_installed_package_for_file(struct razor_transaction *trans,
1.435 - const char *filename)
1.436 -{
1.437 - struct razor_package *pkg;
1.438 -
1.439 - pkg = find_package_for_file(trans->system, &trans->syspkgs,
1.440 - filename, 1);
1.441 - if (!pkg)
1.442 - pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
1.443 - filename, 1);
1.444 - return pkg;
1.445 -}
1.446 -
1.447 -static struct razor_package *
1.448 -find_uninstalled_package_for_file(struct razor_transaction *trans,
1.449 - const char *filename)
1.450 -{
1.451 - struct razor_package *pkg;
1.452 -
1.453 - pkg = find_package_for_file(trans->upstream, &trans->uppkgs,
1.454 - filename, 0);
1.455 - if (!pkg)
1.456 - pkg = find_package_for_file(trans->system, &trans->syspkgs,
1.457 - filename, 0);
1.458 - return pkg;
1.459 -}
1.460 -
1.461 -static struct razor_property *
1.462 -skip_to_matching_property(struct razor_transaction *trans,
1.463 - struct razor_property *match,
1.464 - struct razor_property *prop)
1.465 -{
1.466 - struct razor_set *mset, *pset;
1.467 - const char *ppool, *mpool;
1.468 - struct razor_property *prop_end;
1.469 -
1.470 - if (property_in_set(match, trans->system))
1.471 - mset = trans->system;
1.472 - else
1.473 - mset = trans->upstream;
1.474 -
1.475 - if (property_in_set(prop, trans->system))
1.476 - pset = trans->system;
1.477 - else if (property_in_set(prop, trans->upstream))
1.478 - pset = trans->upstream;
1.479 - else
1.480 - return prop;
1.481 -
1.482 - prop_end = pset->properties.data + pset->properties.size;
1.483 - ppool = pset->string_pool.data;
1.484 - mpool = mset->string_pool.data;
1.485 -
1.486 - while (prop < prop_end &&
1.487 - strcmp(&ppool[prop->name], &mpool[match->name]) < 0)
1.488 - prop++;
1.489 - return prop;
1.490 -}
1.491 -
1.492 -static struct razor_package *
1.493 -find_package_matching(struct razor_transaction *trans, int installed,
1.494 - struct razor_property *prop,
1.495 - struct razor_property *req,
1.496 - struct razor_set *req_set)
1.497 -{
1.498 - struct razor_set *set;
1.499 - struct bitarray *pkgbits;
1.500 - struct razor_package *pkgs;
1.501 - struct razor_property *props, *prop_end;
1.502 - enum razor_property_type match_type;
1.503 - const char *pool;
1.504 - const char *rpool;
1.505 - int match_name = (req->type == RAZOR_PROPERTY_OBSOLETES);
1.506 - int match;
1.507 -
1.508 - if (property_in_set(prop, trans->system)) {
1.509 - set = trans->system;
1.510 - pkgbits = &trans->syspkgs;
1.511 - } else if (property_in_set(prop, trans->upstream)) {
1.512 - set = trans->upstream;
1.513 - pkgbits = &trans->uppkgs;
1.514 - } else
1.515 - return NULL;
1.516 -
1.517 - if (!req_set) {
1.518 - if (property_in_set(req, trans->system))
1.519 - req_set = trans->system;
1.520 - else
1.521 - req_set = trans->upstream;
1.522 - }
1.523 - rpool = req_set->string_pool.data;
1.524 -
1.525 - if (req->type == RAZOR_PROPERTY_PROVIDES)
1.526 - match_type = RAZOR_PROPERTY_CONFLICTS;
1.527 - else
1.528 - match_type = RAZOR_PROPERTY_PROVIDES;
1.529 -
1.530 - pkgs = set->packages.data;
1.531 - props = set->properties.data;
1.532 - prop_end = set->properties.data + set->properties.size;
1.533 - pool = set->string_pool.data;
1.534 -
1.535 - /* Find first matching property */
1.536 - while (prop < prop_end &&
1.537 - strcmp(&pool[prop->name], &rpool[req->name]) < 0)
1.538 - prop++;
1.539 - if (prop == prop_end ||
1.540 - strcmp(&pool[prop->name], &rpool[req->name]) > 0)
1.541 - return NULL;
1.542 -
1.543 - if (prop->type < match_type) {
1.544 - while (prop < prop_end && prop->type != match_type)
1.545 - prop++;
1.546 - } else {
1.547 - while (prop >= props && prop->type != match_type)
1.548 - prop--;
1.549 - while (prop > props + 1 && (prop - 1)->name == prop->name &&
1.550 - (prop - 1)->type == match_type)
1.551 - prop--;
1.552 - }
1.553 -
1.554 - /* Scan matching properties */
1.555 - while (prop < prop_end && prop->type == match_type &&
1.556 - strcmp(&pool[prop->name], &rpool[req->name]) == 0) {
1.557 - if (match_type == RAZOR_PROPERTY_PROVIDES)
1.558 - match = provider_satisfies_requirement(prop, pool, req, rpool);
1.559 - else
1.560 - match = provider_satisfies_requirement(req, rpool, prop, pool);
1.561 - if (match) {
1.562 - struct list *pkg;
1.563 -
1.564 - for (pkg = list_first(&prop->packages, &set->package_pool); pkg; pkg = list_next(pkg)) {
1.565 - if (bitarray_get(pkgbits, pkg->data) != installed)
1.566 - continue;
1.567 - if (!match_name ||
1.568 - strcmp(&pool[pkgs[pkg->data].name],
1.569 - &rpool[req->name]) == 0)
1.570 - return &pkgs[pkg->data];
1.571 - }
1.572 - }
1.573 - prop++;
1.574 - }
1.575 -
1.576 - return NULL;
1.577 -}
1.578 -
1.579 -static struct razor_package *
1.580 -find_installed_package_for_property(struct razor_transaction *trans,
1.581 - struct razor_property *sys_start,
1.582 - struct razor_property *up_start,
1.583 - struct razor_property *req)
1.584 -{
1.585 - struct razor_package *pkg;
1.586 -
1.587 - pkg = find_package_matching(trans, 1, sys_start, req, NULL);
1.588 - if (!pkg)
1.589 - pkg = find_package_matching(trans, 1, up_start, req, NULL);
1.590 - return pkg;
1.591 -}
1.592 -
1.593 -static struct razor_package *
1.594 -find_uninstalled_package_for_property(struct razor_transaction *trans,
1.595 - struct razor_property *sys_start,
1.596 - struct razor_property *up_start,
1.597 - struct razor_property *req)
1.598 -{
1.599 - struct razor_package *pkg;
1.600 -
1.601 - pkg = find_package_matching(trans, 0, up_start, req, NULL);
1.602 - if (!pkg)
1.603 - pkg = find_package_matching(trans, 0, sys_start, req, NULL);
1.604 - return pkg;
1.605 -}
1.606 -
1.607 -static struct razor_transaction_package *
1.608 -find_transaction_package(struct razor_transaction *trans, const char *name)
1.609 -{
1.610 - struct razor_transaction_package *packages;
1.611 - int count, i;
1.612 -
1.613 - packages = trans->packages.data;
1.614 - count = trans->packages.size / sizeof *packages;
1.615 - for (i = 0; i < count; i++) {
1.616 - if (packages[i].name && !strcmp(packages[i].name, name))
1.617 - return &packages[i];
1.618 - }
1.619 - return NULL;
1.620 -}
1.621 -
1.622 -/* FIXME? */
1.623 -static int
1.624 -prop_is_being_installed(struct razor_transaction *trans,
1.625 - struct razor_property *prop)
1.626 -{
1.627 - struct list *pkg;
1.628 -
1.629 - for (pkg = list_first(&prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
1.630 - if (bitarray_get(&trans->uppkgs, pkg->data))
1.631 - return 1;
1.632 - }
1.633 - return 0;
1.634 -}
1.635 -
1.636 -static int
1.637 -prop_is_being_removed(struct razor_transaction *trans,
1.638 - struct razor_property *prop)
1.639 -{
1.640 - struct list *pkg;
1.641 -
1.642 - for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
1.643 - if (bitarray_get(&trans->syspkgs, pkg->data))
1.644 - return 0;
1.645 - }
1.646 - return 1;
1.647 -}
1.648 -
1.649 -static int
1.650 -prop_is_being_updated(struct razor_transaction *trans,
1.651 - struct razor_property *prop)
1.652 -{
1.653 - struct razor_package *packages = trans->system->packages.data;
1.654 - const char *pool = trans->system->string_pool.data;
1.655 - struct razor_transaction_package *tp;
1.656 - struct list *pkg;
1.657 -
1.658 - /* Assumes prop_is_being_removed returns true */
1.659 -
1.660 - for (pkg = list_first(&prop->packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
1.661 - tp = find_transaction_package(trans, &pool[packages[pkg->data].name]);
1.662 - if (tp && tp->state == RAZOR_PACKAGE_REMOVE)
1.663 - return 0;
1.664 - }
1.665 - return 1;
1.666 + ts->set = set;
1.667 + count = set->packages.size / sizeof (struct razor_package);
1.668 + ts->packages = zalloc(count * sizeof *ts->packages);
1.669 + count = set->properties.size / sizeof (struct razor_property);
1.670 + ts->properties = zalloc(count * sizeof *ts->properties);
1.671 }
1.672
1.673 static void
1.674 -add_transaction_package(struct razor_transaction *trans,
1.675 - struct razor_package *new_package,
1.676 - struct razor_package *old_package,
1.677 - enum razor_transaction_package_state state,
1.678 - const char *req_package,
1.679 - struct razor_property *req_prop)
1.680 +transaction_set_release(struct transaction_set *ts)
1.681 {
1.682 - struct razor_set *new_package_set, *old_package_set, *req_set;
1.683 - struct bitarray *reqpkgbits;
1.684 - struct razor_transaction_package *tp, *already;
1.685 - const char *pool;
1.686 - struct razor_package *pkgs;
1.687 - struct list *pkg;
1.688 - int contradiction = 0;
1.689 -
1.690 - if (package_in_set(new_package, trans->system))
1.691 - new_package_set = trans->system;
1.692 - else
1.693 - new_package_set = trans->upstream;
1.694 - if (package_in_set(old_package, trans->system))
1.695 - old_package_set = trans->system;
1.696 - else
1.697 - old_package_set = trans->upstream;
1.698 - if (property_in_set(req_prop, trans->system)) {
1.699 - req_set = trans->system;
1.700 - reqpkgbits = &trans->syspkgs;
1.701 - } else {
1.702 - req_set = trans->upstream;
1.703 - reqpkgbits = &trans->uppkgs;
1.704 - }
1.705 -
1.706 - if (new_package) {
1.707 - pool = new_package_set->string_pool.data;
1.708 - already = find_transaction_package(trans, &pool[new_package->name]);
1.709 - if (already) {
1.710 - if (already->new_package == new_package) {
1.711 - /* Already taken care of */
1.712 - return;
1.713 - } else if (new_package_set == trans->upstream &&
1.714 - already->state == RAZOR_PACKAGE_FORCED_UPDATE) {
1.715 - already->new_package = new_package;
1.716 - return;
1.717 - } else if (new_package_set == trans->upstream) {
1.718 - return;
1.719 - }
1.720 -
1.721 - /* Oops. We lose */
1.722 - if (state != RAZOR_PACKAGE_CONTRADICTION)
1.723 - contradiction = 1;
1.724 - }
1.725 - } else if (old_package) {
1.726 - pool = old_package_set->string_pool.data;
1.727 - already = find_transaction_package(trans, &pool[old_package->name]);
1.728 - if (already) {
1.729 - if (already->old_package == old_package) {
1.730 - /* Already taken care of */
1.731 - return;
1.732 - } else if (old_package_set == trans->system) {
1.733 - already->old_package = old_package;
1.734 - return;
1.735 - }
1.736 -
1.737 - /* Oops. We lose */
1.738 - if (state != RAZOR_PACKAGE_CONTRADICTION)
1.739 - contradiction = 1;
1.740 - }
1.741 - } else
1.742 - state = RAZOR_PACKAGE_UNSATISFIABLE;
1.743 -
1.744 - tp = array_add(&trans->packages, sizeof *tp);
1.745 - memset(tp, 0, sizeof *tp);
1.746 -
1.747 - if (new_package) {
1.748 - pool = new_package_set->string_pool.data;
1.749 - tp->new_package = new_package;
1.750 - tp->name = &pool[new_package->name];
1.751 - tp->new_version = &pool[new_package->version];
1.752 -
1.753 - pkgs = new_package_set->packages.data;
1.754 - }
1.755 - if (old_package) {
1.756 - pool = old_package_set->string_pool.data;
1.757 - tp->old_package = old_package;
1.758 - tp->name = &pool[old_package->name];
1.759 - tp->old_version = &pool[old_package->version];
1.760 -
1.761 - pkgs = old_package_set->packages.data;
1.762 - }
1.763 -
1.764 - tp->state = state;
1.765 - if (state != RAZOR_PACKAGE_INSTALL &&
1.766 - state != RAZOR_PACKAGE_FORCED_UPDATE &&
1.767 - state != RAZOR_PACKAGE_REMOVE &&
1.768 - state != RAZOR_PACKAGE_OBSOLETED)
1.769 - trans->errors++;
1.770 -
1.771 - if (contradiction) {
1.772 - /* Do this now, after adding tp, so that it ends up
1.773 - * after both the INSTALL and the REMOVE in the array.
1.774 - */
1.775 - add_transaction_package(trans, new_package, old_package,
1.776 - RAZOR_PACKAGE_CONTRADICTION,
1.777 - NULL, NULL);
1.778 - }
1.779 -
1.780 - if (req_package)
1.781 - tp->dep_package = req_package;
1.782 - if (!req_prop)
1.783 - return;
1.784 -
1.785 - pool = req_set->string_pool.data;
1.786 - pkgs = req_set->packages.data;
1.787 - if (!req_package) {
1.788 - for (pkg = list_first(&req_prop->packages, &req_set->package_pool); pkg; pkg = list_next(pkg)) {
1.789 - if (bitarray_get(reqpkgbits, pkg->data))
1.790 - break;
1.791 - }
1.792 - if (pkg)
1.793 - tp->dep_package = &pool[pkgs[pkg->data].name];
1.794 - }
1.795 -
1.796 - tp->dep_type = req_prop->type;
1.797 - tp->dep_property = &pool[req_prop->name];
1.798 - tp->dep_relation = req_prop->relation;
1.799 - tp->dep_version = &pool[req_prop->version];
1.800 + free(ts->packages);
1.801 + free(ts->properties);
1.802 }
1.803
1.804 static void
1.805 -razor_transaction_satisfy(struct razor_transaction *trans)
1.806 +transaction_set_install_package(struct transaction_set *ts,
1.807 + struct razor_package *package)
1.808 {
1.809 - struct razor_package *spkgs, *upkgs, *pkg;
1.810 - struct razor_property *sp, *sprops, *sprop_end;
1.811 - struct razor_property *up, *uprops, *uprop_end;
1.812 - struct razor_property *sr, *ur, *first_up;
1.813 - const char *spool, *upool, *removed_package;
1.814 - struct list *reqpkg;
1.815 + struct razor_package *pkgs;
1.816 + struct list *prop;
1.817 + int i;
1.818
1.819 - spkgs = trans->system->packages.data;
1.820 - sprops = trans->system->properties.data;
1.821 - sprop_end = trans->system->properties.data + trans->system->properties.size;
1.822 - spool = trans->system->string_pool.data;
1.823 - upkgs = trans->upstream->packages.data;
1.824 - uprops = trans->upstream->properties.data;
1.825 - uprop_end = trans->upstream->properties.data + trans->upstream->properties.size;
1.826 - upool = trans->upstream->string_pool.data;
1.827 + pkgs = ts->set->packages.data;
1.828 + i = package - pkgs;
1.829 + if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
1.830 + return;
1.831
1.832 - sp = sprops;
1.833 - for (up = uprops; up < uprop_end; up++) {
1.834 - /* Skip 'up' ahead to a property of a package which is
1.835 - * to-be-installed.
1.836 - */
1.837 - while (up < uprop_end &&
1.838 - !prop_is_being_installed(trans, up))
1.839 - up++;
1.840 - if (up == uprop_end)
1.841 - break;
1.842 - sp = skip_to_matching_property(trans, up, sp);
1.843 + ts->packages[i] = TRANS_PACKAGE_PRESENT;
1.844
1.845 - switch (up->type) {
1.846 - case RAZOR_PROPERTY_REQUIRES:
1.847 - if (!strncmp(&upool[up->name], "rpmlib(", 7))
1.848 - break;
1.849 -
1.850 - if (find_installed_package_for_property(trans, sp, up, up) ||
1.851 - find_installed_package_for_file(trans, &upool[up->name])) {
1.852 - /* Requires something that is either installed
1.853 - * or to-be-installed.
1.854 - */
1.855 - break;
1.856 - }
1.857 -
1.858 - /* See if we can install a new upstream provider */
1.859 - pkg = find_uninstalled_package_for_property(trans, sp, up, up);
1.860 - if (!pkg)
1.861 - pkg = find_uninstalled_package_for_file(trans, &upool[up->name]);
1.862 - add_transaction_package(trans, pkg, NULL,
1.863 - RAZOR_PACKAGE_INSTALL,
1.864 - NULL, up);
1.865 - break;
1.866 -
1.867 - case RAZOR_PROPERTY_PROVIDES:
1.868 - /* find_installed_package_for_property works backwards
1.869 - * here, finding a *conflicting* installed package.
1.870 - */
1.871 - pkg = find_installed_package_for_property(trans, sp, up, up);
1.872 - if (!pkg)
1.873 - break;
1.874 -
1.875 - if (package_in_set(pkg, trans->system)) {
1.876 - /* pkg CONFLICTS with what 'up' PROVIDES. Try
1.877 - * finding an upgrade
1.878 - */
1.879 - add_transaction_package(trans, NULL, pkg,
1.880 - RAZOR_PACKAGE_FORCED_UPDATE,
1.881 - &upool[up->name], sp);
1.882 - } else {
1.883 - add_transaction_package(trans, NULL, pkg,
1.884 - RAZOR_PACKAGE_CONTRADICTION,
1.885 - NULL, up);
1.886 - }
1.887 - break;
1.888 -
1.889 - case RAZOR_PROPERTY_CONFLICTS:
1.890 - pkg = find_installed_package_for_property(trans, sp, up, up);
1.891 - if (!pkg)
1.892 - break;
1.893 -
1.894 - if (package_in_set(pkg, trans->system)) {
1.895 - /* Conflicts with something already installed.
1.896 - * Try to upgrade out.
1.897 - */
1.898 - add_transaction_package(trans, NULL, pkg,
1.899 - RAZOR_PACKAGE_FORCED_UPDATE,
1.900 - NULL, up);
1.901 - } else {
1.902 - add_transaction_package(trans, pkg, NULL,
1.903 - RAZOR_PACKAGE_CONTRADICTION,
1.904 - NULL, up);
1.905 - }
1.906 - break;
1.907 -
1.908 - case RAZOR_PROPERTY_OBSOLETES:
1.909 - pkg = find_installed_package_for_property(trans, sp, up, up);
1.910 - if (pkg) {
1.911 - /* If pkg is to-be-installed, this
1.912 - * will add a CONTRADICTION error as well.
1.913 - */
1.914 - add_transaction_package(trans, NULL, pkg,
1.915 - RAZOR_PACKAGE_OBSOLETED,
1.916 - NULL, up);
1.917 - }
1.918 - break;
1.919 -
1.920 - default:
1.921 - /* can't happen */
1.922 - break;
1.923 - }
1.924 - }
1.925 -
1.926 - up = uprops;
1.927 - for (sp = sprops; sp < sprop_end; sp++) {
1.928 - /* Skip 'sp' ahead to a PROVIDES of a package which is
1.929 - * to-be-removed.
1.930 - */
1.931 - while (sp < sprop_end &&
1.932 - (sp->type != RAZOR_PROPERTY_PROVIDES ||
1.933 - !prop_is_being_removed(trans, sp)))
1.934 - sp++;
1.935 - if (sp == sprop_end)
1.936 - break;
1.937 -
1.938 - removed_package = &spool[spkgs[list_first(&sp->packages, &trans->system->package_pool)->data].name];
1.939 -
1.940 - /* Skip 'up' to match */
1.941 - up = skip_to_matching_property(trans, sp, up);
1.942 - ur = first_up = up;
1.943 -
1.944 - /* If the package is just being upgraded, we may
1.945 - * already be installing an identical PROVIDES, so
1.946 - * check for that.
1.947 - */
1.948 - while (up < uprop_end &&
1.949 - strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
1.950 - (up->type != RAZOR_PROPERTY_PROVIDES ||
1.951 - sp->relation != up->relation ||
1.952 - strcmp(&spool[sp->name], &upool[up->name]) != 0))
1.953 - up++;
1.954 - if (up < uprop_end &&
1.955 - up->type == RAZOR_PROPERTY_PROVIDES &&
1.956 - strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
1.957 - sp->relation == up->relation &&
1.958 - strcmp(&spool[sp->version], &upool[up->version]) == 0 &&
1.959 - prop_is_being_installed(trans, up)) {
1.960 - up = first_up;
1.961 - continue;
1.962 - }
1.963 - up = first_up;
1.964 -
1.965 - /* For all still-installed packages that require
1.966 - * sp->name, see if they are satisfied by any other
1.967 - * still-installed or to-be-installed property. If
1.968 - * not, either remove or attempt to update the
1.969 - * package, depending on why the required property has
1.970 - * disappeared
1.971 - */
1.972 - sr = sp;
1.973 - while (sr > sprops + 1 && (sr - 1)->name == sr->name)
1.974 - sr--;
1.975 - for (; sr->type == RAZOR_PROPERTY_REQUIRES; sr++) {
1.976 - if (prop_is_being_removed(trans, sr))
1.977 - continue;
1.978 - if (find_installed_package_for_property(trans, sp, up, sr))
1.979 - continue;
1.980 -
1.981 - for (reqpkg = list_first(&sr->packages, &trans->system->package_pool); reqpkg; reqpkg = list_next(reqpkg)) {
1.982 - if (!bitarray_get(&trans->syspkgs, reqpkg->data))
1.983 - continue;
1.984 - pkg = &spkgs[reqpkg->data];
1.985 - if (prop_is_being_updated(trans, sp)) {
1.986 - add_transaction_package(trans, NULL, pkg,
1.987 - RAZOR_PACKAGE_FORCED_UPDATE,
1.988 - removed_package, NULL);
1.989 - } else {
1.990 - add_transaction_package(trans, NULL, pkg,
1.991 - RAZOR_PACKAGE_REMOVE,
1.992 - removed_package, sr);
1.993 - }
1.994 - }
1.995 - }
1.996 + prop = list_first(&package->properties, &ts->set->property_pool);
1.997 + while (prop) {
1.998 + ts->properties[prop->data]++;
1.999 + prop = list_next(prop);
1.1000 }
1.1001 }
1.1002
1.1003 -void
1.1004 -razor_transaction_install_package(struct razor_transaction *transaction,
1.1005 - struct razor_package *package)
1.1006 +static void
1.1007 +transaction_set_remove_package(struct transaction_set *ts,
1.1008 + struct razor_package *package)
1.1009 {
1.1010 - add_transaction_package(transaction, package, NULL,
1.1011 - RAZOR_PACKAGE_INSTALL, NULL, NULL);
1.1012 -}
1.1013 + struct razor_package *pkgs;
1.1014 + struct list *prop;
1.1015 + int i;
1.1016
1.1017 -void
1.1018 -razor_transaction_remove_package(struct razor_transaction *transaction,
1.1019 - struct razor_package *package)
1.1020 -{
1.1021 - add_transaction_package(transaction, NULL, package,
1.1022 - RAZOR_PACKAGE_REMOVE, NULL, NULL);
1.1023 -}
1.1024 + pkgs = ts->set->packages.data;
1.1025 + i = package - pkgs;
1.1026 + if (ts->packages[i] == 0)
1.1027 + return;
1.1028
1.1029 -void
1.1030 -razor_transaction_update_all(struct razor_transaction *trans)
1.1031 -{
1.1032 - struct razor_package *sp, *spkgs, *send, *up, *upkgs, *uend;
1.1033 - const char *spool, *upool;
1.1034 + ts->packages[i] = 0;
1.1035
1.1036 - spkgs = trans->system->packages.data;
1.1037 - send = trans->system->packages.data + trans->system->packages.size;
1.1038 - spool = trans->system->string_pool.data;
1.1039 - up = upkgs = trans->upstream->packages.data;
1.1040 - uend = trans->upstream->packages.data + trans->upstream->packages.size;
1.1041 - upool = trans->upstream->string_pool.data;
1.1042 -
1.1043 - for (sp = spkgs; sp < send; sp++) {
1.1044 - while (up < uend && strcmp(&spool[sp->name], &upool[up->name]) > 0)
1.1045 - up++;
1.1046 - if (strcmp(&spool[sp->name], &upool[up->name]) == 0 &&
1.1047 - versioncmp(&spool[sp->version], &upool[up->version]) < 0) {
1.1048 - add_transaction_package(trans, up, sp,
1.1049 - RAZOR_PACKAGE_INSTALL,
1.1050 - NULL, NULL);
1.1051 - }
1.1052 + prop = list_first(&package->properties, &ts->set->property_pool);
1.1053 + while (prop) {
1.1054 + ts->properties[prop->data]--;
1.1055 + prop = list_next(prop);
1.1056 }
1.1057 }
1.1058
1.1059 @@ -2638,242 +1839,618 @@
1.1060 razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
1.1061 {
1.1062 struct razor_transaction *trans;
1.1063 - int count;
1.1064 + struct razor_package *p, *spkgs, *pend;
1.1065
1.1066 trans = zalloc(sizeof *trans);
1.1067 + transaction_set_init(&trans->system, system);
1.1068 + transaction_set_init(&trans->upstream, upstream);
1.1069
1.1070 - trans->system = system;
1.1071 - trans->upstream = upstream ? upstream : razor_set_create();
1.1072 - array_init(&trans->packages);
1.1073 - count = trans->system->packages.size / sizeof (struct razor_package);
1.1074 - bitarray_init(&trans->syspkgs, count, 1);
1.1075 - count = trans->upstream->packages.size / sizeof (struct razor_package);
1.1076 - bitarray_init(&trans->uppkgs, count, 0);
1.1077 + spkgs = trans->system.set->packages.data;
1.1078 + pend = trans->system.set->packages.data +
1.1079 + trans->system.set->packages.size;
1.1080 + for (p = spkgs; p < pend; p++)
1.1081 + transaction_set_install_package(&trans->system, p);
1.1082
1.1083 return trans;
1.1084 }
1.1085
1.1086 -static void
1.1087 -resolve_transaction(struct razor_transaction *trans)
1.1088 +void
1.1089 +razor_transaction_install_package(struct razor_transaction *trans,
1.1090 + struct razor_package *package)
1.1091 {
1.1092 - int start, end;
1.1093 -
1.1094 - if (trans->package_count > 0)
1.1095 - /* Already did this, return. */
1.1096 - return;
1.1097 -
1.1098 - start = 0;
1.1099 - end = trans->packages.size / sizeof (struct razor_transaction_package);
1.1100 -
1.1101 - while (start != end) {
1.1102 - resolve_new_packages(trans, start, end);
1.1103 - if (trans->errors)
1.1104 - break;
1.1105 -
1.1106 - razor_transaction_satisfy(trans);
1.1107 -
1.1108 - start = end;
1.1109 - end = trans->packages.size / sizeof (struct razor_transaction_package);
1.1110 - }
1.1111 -
1.1112 - trans->package_count = end;
1.1113 + transaction_set_install_package(&trans->upstream, package);
1.1114 + trans->changes++;
1.1115 }
1.1116
1.1117 -const char * const razor_version_relations[] = {
1.1118 - /* same order as enum razor_version_relation */
1.1119 - "<", "<=", "=", ">=", ">"
1.1120 -};
1.1121 +void
1.1122 +razor_transaction_remove_package(struct razor_transaction *trans,
1.1123 + struct razor_package *package)
1.1124 +{
1.1125 + transaction_set_remove_package(&trans->system, package);
1.1126 + trans->changes++;
1.1127 +}
1.1128
1.1129 -const char * const razor_property_types[] = {
1.1130 - /* same order as enum razor_property_type */
1.1131 - "requires", "provides", "conflicts with", "obsoletes"
1.1132 +void
1.1133 +razor_transaction_update_package(struct razor_transaction *trans,
1.1134 + struct razor_package *package)
1.1135 +{
1.1136 + struct razor_package *spkgs;
1.1137 +
1.1138 + spkgs = trans->system.set->packages.data;
1.1139 + trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
1.1140 +}
1.1141 +
1.1142 +struct prop_iter {
1.1143 + struct razor_property *p, *start, *end;
1.1144 + const char *pool;
1.1145 + uint32_t *present;
1.1146 };
1.1147
1.1148 static void
1.1149 -print_requirement(struct razor_transaction_package *p)
1.1150 +prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
1.1151 {
1.1152 - if (p->dep_type == RAZOR_PROPERTY_CONFLICTS &&
1.1153 - !strcmp(p->dep_package, p->name)) {
1.1154 - printf(" because %s %s conflicts with %s",
1.1155 - p->name, p->old_version, p->dep_property);
1.1156 - if (*p->dep_version) {
1.1157 - printf(" %s %s",
1.1158 - razor_version_relations[p->dep_relation],
1.1159 - p->dep_version);
1.1160 + pi->p = ts->set->properties.data;
1.1161 + pi->start = ts->set->properties.data;
1.1162 + pi->end = ts->set->properties.data + ts->set->properties.size;
1.1163 + pi->pool = ts->set->string_pool.data;
1.1164 + pi->present = ts->properties;
1.1165 +}
1.1166 +
1.1167 +static int
1.1168 +prop_iter_next(struct prop_iter *pi,
1.1169 + enum razor_property_type type, struct razor_property **p)
1.1170 +{
1.1171 + while (pi->p < pi->end) {
1.1172 + if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
1.1173 + pi->p->type == type) {
1.1174 + *p = pi->p++;
1.1175 + return 1;
1.1176 }
1.1177 + pi->p++;
1.1178 + }
1.1179 +
1.1180 + return 0;
1.1181 +}
1.1182 +
1.1183 +static struct razor_property *
1.1184 +prop_iter_seek_to(struct prop_iter *pi,
1.1185 + enum razor_property_type type, const char *match)
1.1186 +{
1.1187 + uint32_t name;
1.1188 +
1.1189 + while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
1.1190 + pi->p++;
1.1191 +
1.1192 + if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
1.1193 + return NULL;
1.1194 +
1.1195 + name = pi->p->name;
1.1196 + while (pi->p < pi->end &&
1.1197 + pi->p->name == name &&
1.1198 + pi->p->type != type)
1.1199 + pi->p++;
1.1200 +
1.1201 + if (pi->p == pi->end || pi->p->name != name)
1.1202 + return NULL;
1.1203 +
1.1204 + return pi->p;
1.1205 +}
1.1206 +
1.1207 +/* Remove packages from set that provide any of the matching (same
1.1208 + * name and type) providers from ppi onwards that match the
1.1209 + * requirement that rpi points to. */
1.1210 +static void
1.1211 +remove_matching_providers(struct razor_transaction *trans,
1.1212 + struct prop_iter *ppi,
1.1213 + enum razor_version_relation relation,
1.1214 + const char *version)
1.1215 +{
1.1216 + struct razor_property *p;
1.1217 + struct razor_package *pkg, *pkgs;
1.1218 + struct razor_package_iterator pkg_iter;
1.1219 + struct razor_set *set;
1.1220 + const char *n, *v, *a;
1.1221 +
1.1222 + if (ppi->present == trans->system.properties)
1.1223 + set = trans->system.set;
1.1224 + else
1.1225 + set = trans->upstream.set;
1.1226 +
1.1227 + pkgs = (struct razor_package *) set->packages.data;
1.1228 + for (p = ppi->p;
1.1229 + p < ppi->end &&
1.1230 + p->name == ppi->p->name &&
1.1231 + p->type == ppi->p->type;
1.1232 + p++) {
1.1233 + if (!ppi->present[p - ppi->start])
1.1234 + continue;
1.1235 + if (!provider_satisfies_requirement(p, ppi->pool,
1.1236 + relation, version))
1.1237 + continue;
1.1238 +
1.1239 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
1.1240 + while (razor_package_iterator_next(&pkg_iter,
1.1241 + &pkg, &n, &v, &a)) {
1.1242 + fprintf(stderr, "removing %s-%s\n", n, v);
1.1243 + razor_transaction_remove_package(trans, pkg);
1.1244 + }
1.1245 + }
1.1246 +}
1.1247 +
1.1248 +static void
1.1249 +flag_matching_providers(struct razor_transaction *trans,
1.1250 + struct prop_iter *ppi,
1.1251 + struct razor_property *r,
1.1252 + struct prop_iter *rpi,
1.1253 + unsigned int flag)
1.1254 +{
1.1255 + struct razor_property *p;
1.1256 + struct razor_package *pkg, *pkgs;
1.1257 + struct razor_package_iterator pkg_iter;
1.1258 + struct razor_set *set;
1.1259 + const char *name, *version, *arch;
1.1260 + uint32_t *flags;
1.1261 +
1.1262 + if (ppi->present == trans->system.properties) {
1.1263 + set = trans->system.set;
1.1264 + flags = trans->system.packages;
1.1265 } else {
1.1266 - if (strcmp(p->name, p->dep_package) != 0)
1.1267 - printf(" for %s", p->dep_package);
1.1268 - if (*p->dep_version) {
1.1269 - printf(", which %s %s %s %s",
1.1270 - razor_property_types[p->dep_type],
1.1271 - p->dep_property,
1.1272 - razor_version_relations[p->dep_relation],
1.1273 - p->dep_version);
1.1274 - } else if (strcmp(p->dep_property, p->name) != 0) {
1.1275 - printf(", which %s %s",
1.1276 - razor_property_types[p->dep_type],
1.1277 - p->dep_property);
1.1278 + set = trans->upstream.set;
1.1279 + flags = trans->upstream.packages;
1.1280 + }
1.1281 +
1.1282 + pkgs = (struct razor_package *) set->packages.data;
1.1283 + for (p = ppi->p;
1.1284 + p < ppi->end &&
1.1285 + p->name == ppi->p->name &&
1.1286 + p->type == ppi->p->type;
1.1287 + p++) {
1.1288 + if (!ppi->present[p - ppi->start])
1.1289 + continue;
1.1290 + if (!provider_satisfies_requirement(p, ppi->pool,
1.1291 + r->relation,
1.1292 + &rpi->pool[r->version]))
1.1293 + continue;
1.1294 +
1.1295 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
1.1296 + while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1297 + &name, &version, &arch)) {
1.1298 +
1.1299 + fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
1.1300 + name, version,
1.1301 + ppi->pool + p->name,
1.1302 + rpi->pool + r->name,
1.1303 + rpi->pool + r->version);
1.1304 + flags[pkg - pkgs] |= flag;
1.1305 }
1.1306 }
1.1307 }
1.1308
1.1309 +static struct razor_package *
1.1310 +pick_matching_provider(struct razor_set *set,
1.1311 + struct prop_iter *ppi,
1.1312 + enum razor_version_relation relation,
1.1313 + const char *version)
1.1314 +{
1.1315 + struct razor_property *p;
1.1316 + struct razor_package *pkgs;
1.1317 + struct list *i;
1.1318 +
1.1319 + /* This is where we decide which pkgs to pull in to satisfy a
1.1320 + * requirement. There may be several different providers
1.1321 + * (different versions) and each version of a provider may
1.1322 + * come from a number of packages. We pick the first package
1.1323 + * from the first provider that matches. */
1.1324 +
1.1325 + pkgs = set->packages.data;
1.1326 + for (p = ppi->p;
1.1327 + p < ppi->end &&
1.1328 + p->name == ppi->p->name &&
1.1329 + p->type == ppi->p->type &&
1.1330 + ppi->present[p - ppi->start] == 0;
1.1331 + p++) {
1.1332 + if (!provider_satisfies_requirement(p, ppi->pool,
1.1333 + relation, version))
1.1334 + continue;
1.1335 +
1.1336 + i = list_first(&p->packages, &set->package_pool);
1.1337 +
1.1338 + return &pkgs[i->data];
1.1339 + }
1.1340 +
1.1341 + return NULL;
1.1342 +}
1.1343 +
1.1344 +static void
1.1345 +remove_obsoleted_packages(struct razor_transaction *trans)
1.1346 +{
1.1347 + struct razor_property *up;
1.1348 + struct razor_package *spkgs;
1.1349 + struct prop_iter spi, upi;
1.1350 +
1.1351 + spkgs = trans->system.set->packages.data;
1.1352 + prop_iter_init(&spi, &trans->system);
1.1353 + prop_iter_init(&upi, &trans->upstream);
1.1354 +
1.1355 + while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
1.1356 + if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
1.1357 + &upi.pool[up->name]))
1.1358 + continue;
1.1359 + remove_matching_providers(trans, &spi, up->relation,
1.1360 + &upi.pool[up->version]);
1.1361 + }
1.1362 +}
1.1363 +
1.1364 +static int
1.1365 +any_provider_satisfies_requirement(struct prop_iter *ppi,
1.1366 + enum razor_version_relation relation,
1.1367 + const char *version)
1.1368 +{
1.1369 + struct razor_property *p;
1.1370 +
1.1371 + for (p = ppi->p;
1.1372 + p < ppi->end &&
1.1373 + p->name == ppi->p->name &&
1.1374 + p->type == ppi->p->type;
1.1375 + p++) {
1.1376 + if (ppi->present[p - ppi->start] > 0 &&
1.1377 + provider_satisfies_requirement(p, ppi->pool,
1.1378 + relation, version))
1.1379 + return 1;
1.1380 + }
1.1381 +
1.1382 + return 0;
1.1383 +}
1.1384 +
1.1385 +static void
1.1386 +clear_requires_flags(struct transaction_set *ts)
1.1387 +{
1.1388 + struct razor_property *p;
1.1389 + const char *pool;
1.1390 + int i, count;
1.1391 +
1.1392 + count = ts->set->properties.size / sizeof *p;
1.1393 + p = ts->set->properties.data;
1.1394 + pool = ts->set->string_pool.data;
1.1395 + for (i = 0; i < count; i++) {
1.1396 + ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
1.1397 + if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
1.1398 + ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
1.1399 + }
1.1400 +}
1.1401 +
1.1402 +static void
1.1403 +mark_satisfied_requires(struct razor_transaction *trans,
1.1404 + struct transaction_set *rts,
1.1405 + struct transaction_set *pts)
1.1406 +{
1.1407 + struct prop_iter rpi, ppi;
1.1408 + struct razor_property *rp;
1.1409 +
1.1410 + prop_iter_init(&rpi, rts);
1.1411 + prop_iter_init(&ppi, pts);
1.1412 +
1.1413 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1414 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
1.1415 + &rpi.pool[rp->name]))
1.1416 + continue;
1.1417 +
1.1418 + if (any_provider_satisfies_requirement(&ppi, rp->relation,
1.1419 + &rpi.pool[rp->version]))
1.1420 + rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
1.1421 + }
1.1422 +}
1.1423 +
1.1424 +static const char *relation_string[] = { "<", "<=", "=", ">=", ">" };
1.1425 +
1.1426 +static void
1.1427 +mark_all_satisfied_requires(struct razor_transaction *trans)
1.1428 +{
1.1429 + struct razor_property *sp;
1.1430 + struct prop_iter spi;
1.1431 +
1.1432 + clear_requires_flags(&trans->system);
1.1433 + clear_requires_flags(&trans->upstream);
1.1434 + mark_satisfied_requires(trans, &trans->system, &trans->system);
1.1435 + mark_satisfied_requires(trans, &trans->system, &trans->upstream);
1.1436 + mark_satisfied_requires(trans, &trans->upstream, &trans->system);
1.1437 + mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
1.1438 +
1.1439 + prop_iter_init(&spi, &trans->system);
1.1440 + while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
1.1441 + if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
1.1442 + continue;
1.1443 + fprintf(stderr, "unsatisfied system requires: %s %s %s\n",
1.1444 + spi.pool + sp->name,
1.1445 + relation_string[sp->relation],
1.1446 + spi.pool + sp->version);
1.1447 + }
1.1448 +
1.1449 + prop_iter_init(&spi, &trans->upstream);
1.1450 + while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
1.1451 + if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
1.1452 + continue;
1.1453 + fprintf(stderr, "unsatisfied upstream requires: %s %s %s\n",
1.1454 + spi.pool + sp->name,
1.1455 + relation_string[sp->relation],
1.1456 + spi.pool + sp->version);
1.1457 + }
1.1458 +}
1.1459 +
1.1460 +static void
1.1461 +update_unsatisfied_packages(struct razor_transaction *trans)
1.1462 +{
1.1463 + struct razor_package *spkgs, *pkg;
1.1464 + struct razor_property *sp;
1.1465 + struct prop_iter spi;
1.1466 + struct razor_package_iterator pkg_iter;
1.1467 + const char *name, *version, *arch;
1.1468 +
1.1469 + spkgs = trans->system.set->packages.data;
1.1470 + prop_iter_init(&spi, &trans->system);
1.1471 +
1.1472 + while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
1.1473 + if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
1.1474 + continue;
1.1475 +
1.1476 + razor_package_iterator_init_for_property(&pkg_iter,
1.1477 + trans->system.set,
1.1478 + sp);
1.1479 + while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1480 + &name, &version, &arch)) {
1.1481 + fprintf(stderr, "updating %s because %s %s %s "
1.1482 + "isn't satisfied\n",
1.1483 + name, spi.pool + sp->name,
1.1484 + relation_string[sp->relation],
1.1485 + spi.pool + sp->version);
1.1486 + trans->system.packages[pkg - spkgs] |=
1.1487 + TRANS_PACKAGE_UPDATE;
1.1488 + }
1.1489 + }
1.1490 +}
1.1491 +
1.1492 +void
1.1493 +razor_transaction_update_all(struct razor_transaction *trans)
1.1494 +{
1.1495 + struct razor_package *p;
1.1496 + int i, count;
1.1497 +
1.1498 + count = trans->system.set->packages.size / sizeof *p;
1.1499 + for (i = 0; i < count; i++)
1.1500 + trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
1.1501 +}
1.1502 +
1.1503 +static void
1.1504 +update_conflicted_packages(struct razor_transaction *trans)
1.1505 +{
1.1506 + struct razor_package *pkg, *spkgs;
1.1507 + struct razor_property *up, *sp;
1.1508 + struct prop_iter spi, upi;
1.1509 + struct razor_package_iterator pkg_iter;
1.1510 + const char *name, *version, *arch;
1.1511 +
1.1512 + spkgs = trans->system.set->packages.data;
1.1513 + prop_iter_init(&spi, &trans->system);
1.1514 + prop_iter_init(&upi, &trans->upstream);
1.1515 +
1.1516 + while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
1.1517 + if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
1.1518 + &spi.pool[sp->name]))
1.1519 + continue;
1.1520 +
1.1521 + if (!any_provider_satisfies_requirement(&upi, sp->relation,
1.1522 + &spi.pool[sp->version]))
1.1523 + continue;
1.1524 +
1.1525 + razor_package_iterator_init_for_property(&pkg_iter,
1.1526 + trans->system.set,
1.1527 + sp);
1.1528 + while (razor_package_iterator_next(&pkg_iter, &pkg,
1.1529 + &name, &version, &arch)) {
1.1530 + fprintf(stderr, "updating %s %s because it conflicts with %s",
1.1531 + name, version, spi.pool + sp->name);
1.1532 + trans->system.packages[pkg - spkgs] |=
1.1533 + TRANS_PACKAGE_UPDATE;
1.1534 + }
1.1535 + }
1.1536 +
1.1537 + prop_iter_init(&spi, &trans->system);
1.1538 + prop_iter_init(&upi, &trans->upstream);
1.1539 +
1.1540 + while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
1.1541 + sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
1.1542 + &upi.pool[upi.p->name]);
1.1543 +
1.1544 + if (sp)
1.1545 + flag_matching_providers(trans, &spi, up, &upi,
1.1546 + TRANS_PACKAGE_UPDATE);
1.1547 + }
1.1548 +}
1.1549 +
1.1550 +static void
1.1551 +pull_in_requirements(struct razor_transaction *trans,
1.1552 + struct prop_iter *rpi, struct prop_iter *ppi)
1.1553 +{
1.1554 + struct razor_property *rp, *pp;
1.1555 + struct razor_package *pkg, *upkgs;
1.1556 +
1.1557 + upkgs = trans->upstream.set->packages.data;
1.1558 + while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1559 + if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
1.1560 + continue;
1.1561 +
1.1562 + pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
1.1563 + &rpi->pool[rp->name]);
1.1564 + if (pp == NULL)
1.1565 + continue;
1.1566 + pkg = pick_matching_provider(trans->upstream.set,
1.1567 + ppi, rp->relation,
1.1568 + &rpi->pool[rp->version]);
1.1569 + if (pkg == NULL)
1.1570 + continue;
1.1571 +
1.1572 + rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
1.1573 +
1.1574 + fprintf(stderr, "pulling in %s which provides %s %s %s "
1.1575 + "to satisfy %s %s %s\n",
1.1576 + ppi->pool + pkg->name,
1.1577 + ppi->pool + pp->name,
1.1578 + relation_string[pp->relation],
1.1579 + ppi->pool + pp->version,
1.1580 + &rpi->pool[rp->name],
1.1581 + relation_string[rp->relation],
1.1582 + &rpi->pool[rp->version]);
1.1583 +
1.1584 + trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
1.1585 + }
1.1586 +}
1.1587 +
1.1588 +static void
1.1589 +pull_in_all_requirements(struct razor_transaction *trans)
1.1590 +{
1.1591 + struct prop_iter rpi, ppi;
1.1592 + struct razor_property *rp;
1.1593 +
1.1594 + prop_iter_init(&rpi, &trans->system);
1.1595 + prop_iter_init(&ppi, &trans->upstream);
1.1596 + pull_in_requirements(trans, &rpi, &ppi);
1.1597 +
1.1598 + prop_iter_init(&rpi, &trans->upstream);
1.1599 + prop_iter_init(&ppi, &trans->upstream);
1.1600 + pull_in_requirements(trans, &rpi, &ppi);
1.1601 +
1.1602 + prop_iter_init(&rpi, &trans->system);
1.1603 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1604 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED))
1.1605 + fprintf(stderr, "could not satisfy req %s %s %s\n",
1.1606 + &rpi.pool[rp->name],
1.1607 + relation_string[rp->relation],
1.1608 + &rpi.pool[rp->version]);
1.1609 + }
1.1610 +
1.1611 + prop_iter_init(&rpi, &trans->upstream);
1.1612 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
1.1613 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED))
1.1614 + fprintf(stderr, "could not satisfy req %s %s %s\n",
1.1615 + &rpi.pool[rp->name],
1.1616 + relation_string[rp->relation],
1.1617 + &rpi.pool[rp->version]);
1.1618 + }
1.1619 +}
1.1620 +
1.1621 +static void
1.1622 +flush_scheduled_system_updates(struct razor_transaction *trans)
1.1623 +{
1.1624 + struct razor_package_iterator *pi;
1.1625 + struct razor_package *p, *pkg, *spkgs;
1.1626 + struct prop_iter ppi;
1.1627 + const char *name, *version, *arch;
1.1628 +
1.1629 + spkgs = trans->system.set->packages.data;
1.1630 + pi = razor_package_iterator_create(trans->system.set);
1.1631 + prop_iter_init(&ppi, &trans->upstream);
1.1632 +
1.1633 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
1.1634 + if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
1.1635 + continue;
1.1636 +
1.1637 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name)) {
1.1638 + fprintf(stderr, "nothing provides %s\n", name);
1.1639 + continue;
1.1640 + }
1.1641 +
1.1642 + pkg = pick_matching_provider(trans->upstream.set, &ppi,
1.1643 + RAZOR_VERSION_GREATER, version);
1.1644 + if (pkg == NULL) {
1.1645 + fprintf(stderr,
1.1646 + "no newer version of %s available\n", name);
1.1647 + continue;
1.1648 + }
1.1649 +
1.1650 + fprintf(stderr, "updating %s from %s to %s\n",
1.1651 + name, version, &ppi.pool[pkg->version]);
1.1652 +
1.1653 + razor_transaction_remove_package(trans, p);
1.1654 + razor_transaction_install_package(trans, pkg);
1.1655 + }
1.1656 +
1.1657 + razor_package_iterator_destroy(pi);
1.1658 +}
1.1659 +
1.1660 +static void
1.1661 +flush_scheduled_upstream_updates(struct razor_transaction *trans)
1.1662 +{
1.1663 + struct razor_package_iterator *pi;
1.1664 + struct razor_package *p, *upkgs;
1.1665 + struct prop_iter spi;
1.1666 + const char *name, *version, *arch;
1.1667 +
1.1668 + upkgs = trans->upstream.set->packages.data;
1.1669 + pi = razor_package_iterator_create(trans->upstream.set);
1.1670 + prop_iter_init(&spi, &trans->system);
1.1671 +
1.1672 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
1.1673 + if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
1.1674 + continue;
1.1675 +
1.1676 + if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
1.1677 + continue;
1.1678 + remove_matching_providers(trans, &spi,
1.1679 + RAZOR_VERSION_LESS, version);
1.1680 + razor_transaction_install_package(trans, p);
1.1681 + fprintf(stderr, "installing %s-%s\n", name, version);
1.1682 + }
1.1683 +}
1.1684 +
1.1685 int
1.1686 razor_transaction_resolve(struct razor_transaction *trans)
1.1687 {
1.1688 - struct razor_transaction_package *p, *pend, *tps;
1.1689 - int errors_only = 0;
1.1690 + int last = 0;
1.1691
1.1692 - resolve_transaction(trans);
1.1693 + flush_scheduled_system_updates(trans);
1.1694
1.1695 - tps = trans->packages.data;
1.1696 - pend = trans->packages.data + trans->packages.size;
1.1697 - for (p = trans->packages.data; p < pend; p++) {
1.1698 - switch (p->state) {
1.1699 - case RAZOR_PACKAGE_INSTALL:
1.1700 - if (errors_only)
1.1701 - break;
1.1702 -
1.1703 - printf("Installing %s %s", p->name, p->new_version);
1.1704 - if (p->dep_package)
1.1705 - print_requirement(p);
1.1706 - printf("\n");
1.1707 - break;
1.1708 -
1.1709 - case RAZOR_PACKAGE_FORCED_UPDATE:
1.1710 - if (errors_only)
1.1711 - break;
1.1712 -
1.1713 - printf("Updating %s to %s due to update of %s\n",
1.1714 - p->name, p->new_version, p->dep_package);
1.1715 - break;
1.1716 -
1.1717 - case RAZOR_PACKAGE_REMOVE:
1.1718 - if (errors_only)
1.1719 - break;
1.1720 - printf("Removing %s %s", p->name, p->old_version);
1.1721 - if (p->dep_package) {
1.1722 - printf(" which required %s",
1.1723 - p->dep_package);
1.1724 - if (strcmp(p->dep_property, p->dep_package) != 0)
1.1725 - printf(" for %s", p->dep_property);
1.1726 - }
1.1727 - printf("\n");
1.1728 - break;
1.1729 -
1.1730 - case RAZOR_PACKAGE_OBSOLETED:
1.1731 - if (errors_only)
1.1732 - break;
1.1733 - printf("Removing %s %s", p->name, p->old_version);
1.1734 - if (p->dep_package) {
1.1735 - printf(" which is obsoleted by %s",
1.1736 - p->dep_package);
1.1737 - }
1.1738 - printf("\n");
1.1739 - break;
1.1740 -
1.1741 - case RAZOR_PACKAGE_INSTALL_UNAVAILABLE:
1.1742 - printf("Error: can't find %s", p->name);
1.1743 - if (p->dep_package) {
1.1744 - printf(" (which is required");
1.1745 - print_requirement(p);
1.1746 - printf(")");
1.1747 - }
1.1748 - printf("\n");
1.1749 - errors_only = 1;
1.1750 - break;
1.1751 -
1.1752 - case RAZOR_PACKAGE_UPDATE_UNAVAILABLE:
1.1753 - printf("Error: can't find an updated version of %s (which must be updated due to update of %s)\n",
1.1754 - p->name, p->dep_package);
1.1755 - errors_only = 1;
1.1756 - break;
1.1757 -
1.1758 - case RAZOR_PACKAGE_REMOVE_NOT_INSTALLED:
1.1759 - printf("Error: can't remove %s: not installed\n", p->name);
1.1760 - errors_only = 1;
1.1761 - break;
1.1762 -
1.1763 - case RAZOR_PACKAGE_UP_TO_DATE:
1.1764 - printf("Error: can't update %s", p->name);
1.1765 - if (p->dep_package)
1.1766 - printf(" (which must be updated due to update of %s)", p->dep_package);
1.1767 - printf(": %s is most recent version\n", p->old_version);
1.1768 - errors_only = 1;
1.1769 - break;
1.1770 -
1.1771 - case RAZOR_PACKAGE_CONTRADICTION:
1.1772 - printf("Error: package %s is marked for both installation and removal\n", p->name);
1.1773 - errors_only = 1;
1.1774 - break;
1.1775 -
1.1776 - case RAZOR_PACKAGE_OLD_CONFLICT:
1.1777 - printf("Error: can't install %s, because installed package %s conflicts with ",
1.1778 - p->name, p->dep_package);
1.1779 - if (*p->dep_version) {
1.1780 - printf("%s %s %s",
1.1781 - p->dep_property,
1.1782 - razor_version_relations[p->dep_relation],
1.1783 - p->dep_version);
1.1784 - } else
1.1785 - printf("it");
1.1786 - printf("\n");
1.1787 -
1.1788 - errors_only = 1;
1.1789 - break;
1.1790 -
1.1791 - case RAZOR_PACKAGE_NEW_CONFLICT:
1.1792 - printf("Error: can't install %s, because it conflicts with %s",
1.1793 - p->name, p->dep_package);
1.1794 - if (*p->dep_version) {
1.1795 - printf(" %s %s",
1.1796 - razor_version_relations[p->dep_relation],
1.1797 - p->dep_version);
1.1798 - }
1.1799 - printf("\n");
1.1800 -
1.1801 - errors_only = 1;
1.1802 - break;
1.1803 -
1.1804 - case RAZOR_PACKAGE_UNSATISFIABLE:
1.1805 - printf("Error: can't find package for %s", p->dep_property);
1.1806 - if (*p->dep_version) {
1.1807 - printf(" %s %s",
1.1808 - razor_version_relations[p->dep_relation],
1.1809 - p->dep_version);
1.1810 - }
1.1811 - printf(" which is required by %s\n",
1.1812 - p->dep_package);
1.1813 - errors_only = 1;
1.1814 - break;
1.1815 -
1.1816 - default:
1.1817 - /* Shouldn't actually happen */
1.1818 - break;
1.1819 - }
1.1820 + while (last < trans->changes) {
1.1821 + last = trans->changes;
1.1822 + remove_obsoleted_packages(trans);
1.1823 + mark_all_satisfied_requires(trans);
1.1824 + update_unsatisfied_packages(trans);
1.1825 + update_conflicted_packages(trans);
1.1826 + pull_in_all_requirements(trans);
1.1827 + flush_scheduled_system_updates(trans);
1.1828 + flush_scheduled_upstream_updates(trans);
1.1829 }
1.1830
1.1831 - return trans->errors;
1.1832 + return trans->changes;
1.1833 }
1.1834
1.1835 int
1.1836 razor_transaction_unsatisfied_property(struct razor_transaction *trans,
1.1837 const char *name,
1.1838 enum razor_version_relation rel,
1.1839 - const char *version)
1.1840 + const char *version,
1.1841 + enum razor_property_type type)
1.1842 {
1.1843 - struct razor_transaction_package *p, *end;
1.1844 + struct prop_iter pi;
1.1845 + struct razor_property *p;
1.1846
1.1847 - end = trans->packages.data + trans->packages.size;
1.1848 - for (p = trans->packages.data; p < end; p++) {
1.1849 - if (p->state != RAZOR_PACKAGE_UNSATISFIABLE)
1.1850 - continue;
1.1851 - if (strcmp(name, p->dep_property) != 0 ||
1.1852 - rel != p->dep_relation ||
1.1853 - strcmp(version, p->dep_version) != 0)
1.1854 - continue;
1.1855 + prop_iter_init(&pi, &trans->system);
1.1856 + while (prop_iter_next(&pi, type, &p)) {
1.1857 + if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.1858 + p->relation == rel &&
1.1859 + strcmp(&pi.pool[p->name], name) == 0 &&
1.1860 + strcmp(&pi.pool[p->version], version) == 0)
1.1861 +
1.1862 + return 1;
1.1863 + }
1.1864
1.1865 - return 1;
1.1866 + prop_iter_init(&pi, &trans->upstream);
1.1867 + while (prop_iter_next(&pi, type, &p)) {
1.1868 + if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
1.1869 + p->relation == rel &&
1.1870 + strcmp(&pi.pool[p->name], name) == 0 &&
1.1871 + strcmp(&pi.pool[p->version], version) == 0)
1.1872 +
1.1873 + return 1;
1.1874 }
1.1875
1.1876 return 0;
1.1877 @@ -2882,117 +2459,61 @@
1.1878 struct razor_set *
1.1879 razor_transaction_finish(struct razor_transaction *trans)
1.1880 {
1.1881 - struct array install_packages, remove_packages;
1.1882 struct razor_merger *merger;
1.1883 - struct razor_package *pkg, *i, *iend, *r, *rend, *s, *send;
1.1884 - struct razor_set *set;
1.1885 - struct source *source1, *source2;
1.1886 - char *spool, *ipool, *rpool;
1.1887 - uint32_t *map;
1.1888 - struct razor_transaction_package *p, *end;
1.1889 + struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
1.1890 + char *upool, *spool;
1.1891 int cmp;
1.1892
1.1893 - /* FIXME */
1.1894 - if (trans->errors)
1.1895 - return NULL;
1.1896 + s = trans->system.set->packages.data;
1.1897 + spkgs = trans->system.set->packages.data;
1.1898 + send = trans->system.set->packages.data +
1.1899 + trans->system.set->packages.size;
1.1900 + spool = trans->system.set->string_pool.data;
1.1901
1.1902 - /* Sort the transaction packages into two arrays */
1.1903 - array_init(&install_packages);
1.1904 - array_init(&remove_packages);
1.1905 + u = trans->upstream.set->packages.data;
1.1906 + upkgs = trans->upstream.set->packages.data;
1.1907 + uend = trans->upstream.set->packages.data +
1.1908 + trans->upstream.set->packages.size;
1.1909 + upool = trans->upstream.set->string_pool.data;
1.1910
1.1911 - end = trans->packages.data + trans->packages.size;
1.1912 - for (p = trans->packages.data; p < end; p++) {
1.1913 - if (p->new_package) {
1.1914 - pkg = array_add(&install_packages, sizeof *pkg);
1.1915 - *pkg = *p->new_package;
1.1916 - } else {
1.1917 - pkg = array_add(&remove_packages, sizeof *pkg);
1.1918 - *pkg = *p->old_package;
1.1919 - }
1.1920 - }
1.1921 - map = razor_qsort_with_data(install_packages.data,
1.1922 - install_packages.size / sizeof *pkg,
1.1923 - sizeof *pkg,
1.1924 - compare_packages,
1.1925 - trans->upstream);
1.1926 - free(map);
1.1927 - map = razor_qsort_with_data(remove_packages.data,
1.1928 - remove_packages.size / sizeof *pkg,
1.1929 - sizeof *pkg,
1.1930 - compare_packages,
1.1931 - trans->system);
1.1932 - free(map);
1.1933 -
1.1934 - merger = razor_merger_create(trans->system, trans->upstream);
1.1935 -
1.1936 - source1 = &merger->source1;
1.1937 - source2 = &merger->source2;
1.1938 -
1.1939 - i = install_packages.data;
1.1940 - iend = install_packages.data + install_packages.size;
1.1941 - ipool = trans->upstream->string_pool.data;
1.1942 -
1.1943 - r = remove_packages.data;
1.1944 - rend = remove_packages.data + remove_packages.size;
1.1945 - rpool = trans->system->string_pool.data;
1.1946 -
1.1947 - s = trans->system->packages.data;
1.1948 - send = trans->system->packages.data + trans->system->packages.size;
1.1949 - spool = trans->system->string_pool.data;
1.1950 -
1.1951 - while (s < send || i < iend) {
1.1952 - /* Check if s is being removed */
1.1953 - if (s < send && r < rend &&
1.1954 - s->name == r->name && s->version && r->version) {
1.1955 - s++;
1.1956 - r++;
1.1957 - continue;
1.1958 - }
1.1959 -
1.1960 - if (s < send && i < iend)
1.1961 - cmp = strcmp(&spool[s->name], &ipool[i->name]);
1.1962 + merger = razor_merger_create(trans->system.set, trans->upstream.set);
1.1963 + while (s < send || u < uend) {
1.1964 + if (s < send && u < uend)
1.1965 + cmp = strcmp(&spool[s->name], &upool[u->name]);
1.1966 else if (s < send)
1.1967 cmp = -1;
1.1968 else
1.1969 cmp = 1;
1.1970 +
1.1971 if (cmp < 0) {
1.1972 - add_package(merger, s, source1, 0);
1.1973 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
1.1974 + razor_merger_add_package(merger, s);
1.1975 s++;
1.1976 } else if (cmp == 0) {
1.1977 - add_package(merger, i, source2, UPSTREAM_SOURCE);
1.1978 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
1.1979 + razor_merger_add_package(merger, s);
1.1980 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
1.1981 + razor_merger_add_package(merger, u);
1.1982 +
1.1983 s++;
1.1984 - i++;
1.1985 + u++;
1.1986 } else {
1.1987 - add_package(merger, i, source2, UPSTREAM_SOURCE);
1.1988 - i++;
1.1989 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
1.1990 + razor_merger_add_package(merger, u);
1.1991 + u++;
1.1992 }
1.1993 }
1.1994
1.1995 - array_release(&install_packages);
1.1996 - array_release(&remove_packages);
1.1997 -
1.1998 - set = razor_merger_finish(merger);
1.1999 razor_transaction_destroy(trans);
1.2000
1.2001 - return set;
1.2002 + return razor_merger_finish(merger);
1.2003 }
1.2004
1.2005 void
1.2006 razor_transaction_destroy(struct razor_transaction *trans)
1.2007 {
1.2008 - struct razor_transaction_package *p, *end;
1.2009 -
1.2010 - end = trans->packages.data + trans->packages.size;
1.2011 - for (p = trans->packages.data; p < end; p++) {
1.2012 - if (!p->dep_package &&
1.2013 - (p->state == RAZOR_PACKAGE_INSTALL_UNAVAILABLE ||
1.2014 - p->state == RAZOR_PACKAGE_REMOVE_NOT_INSTALLED))
1.2015 - free((char *)p->name);
1.2016 - }
1.2017 -
1.2018 - array_release(&trans->packages);
1.2019 - bitarray_release(&trans->syspkgs);
1.2020 - bitarray_release(&trans->uppkgs);
1.2021 + transaction_set_release(&trans->system);
1.2022 + transaction_set_release(&trans->upstream);
1.2023 free(trans);
1.2024
1.2025 /* FIXME: free upstream if it was created as an empty set */