1.1 --- a/razor.c Fri Feb 29 12:45:08 2008 -0500
1.2 +++ b/razor.c Fri Feb 29 15:09:44 2008 -0500
1.3 @@ -1978,19 +1978,70 @@
1.4 }
1.5
1.6 static void
1.7 -lose_requirement(struct razor_transaction *trans, struct array *package_array,
1.8 - const char *req_package, struct razor_property *req,
1.9 - struct razor_property *lost_provider,
1.10 - struct razor_property *first_provider)
1.11 +gather_lost_files(struct razor_set *set, struct razor_package *pkg,
1.12 + struct array *lost_files)
1.13 {
1.14 - struct razor_property *provider, *prop_end;
1.15 - struct razor_package *pkgs;
1.16 + struct razor_entry *entries = set->files.data, *entry, **lost;
1.17 + struct list *e, *providers;
1.18 +
1.19 + for (e = list_first(&pkg->files, &set->file_pool); e; e = list_next(e)) {
1.20 + entry = &entries[e->data];
1.21 + providers = list_first(&entry->packages, &set->package_pool);
1.22 + if (providers && !list_next(providers)) {
1.23 + lost = array_add(lost_files, sizeof *lost);
1.24 + *lost = entry;
1.25 + }
1.26 + }
1.27 +}
1.28 +
1.29 +static void
1.30 +lose_required_package(struct razor_transaction *trans,
1.31 + struct array *package_array,
1.32 + struct razor_property *req,
1.33 + struct list_head *lost_package_list)
1.34 +{
1.35 + struct razor_package *pkgs, *lost_package;
1.36 char *pool = trans->system->string_pool.data;
1.37 struct list *p;
1.38 struct razor_transaction_package *tp, *packages;;
1.39 int already;
1.40
1.41 pkgs = trans->system->packages.data;
1.42 + lost_package = &pkgs[list_first(lost_package_list, &trans->system->package_pool)->data];
1.43 +
1.44 + for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
1.45 + packages = package_array->data;
1.46 + already = find_transaction_package(package_array, &pkgs[p->data]);
1.47 + if (already != -1 &&
1.48 + (packages[already].state & RAZOR_PACKAGE_REMOVE))
1.49 + continue;
1.50 +
1.51 + tp = array_add(package_array, sizeof *tp);
1.52 + memset(tp, 0, sizeof *tp);
1.53 + tp->package = &pkgs[p->data];
1.54 + tp->name = &pool[tp->package->name];
1.55 + tp->version = &pool[tp->package->version];
1.56 + tp->req_package = &pool[lost_package->name];
1.57 + tp->req_property = &pool[req->name];
1.58 + tp->req_relation = req->relation;
1.59 + tp->req_version = &pool[req->version];
1.60 + if (already != -1) {
1.61 + tp->state = RAZOR_PACKAGE_REMOVE_BLOCKED;
1.62 + trans->errors++;
1.63 + } else
1.64 + tp->state = RAZOR_PACKAGE_REMOVE;
1.65 + }
1.66 +}
1.67 +
1.68 +static void
1.69 +lose_requirement(struct razor_transaction *trans, struct array *package_array,
1.70 + struct razor_property *req,
1.71 + struct razor_property *lost_provider,
1.72 + struct razor_property *first_provider)
1.73 +{
1.74 + struct razor_property *provider, *prop_end;
1.75 + char *pool = trans->system->string_pool.data;
1.76 +
1.77 prop_end = trans->system->properties.data + trans->system->properties.size;
1.78
1.79 /* See if any other provider satisfies req */
1.80 @@ -2004,29 +2055,8 @@
1.81 return;
1.82 }
1.83
1.84 - /* Remove each of the packages requiring req */
1.85 - for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
1.86 - packages = package_array->data;
1.87 - already = find_transaction_package(package_array, &pkgs[p->data]);
1.88 - if (already != -1 &&
1.89 - (packages[already].state & RAZOR_PACKAGE_REMOVE))
1.90 - continue;
1.91 -
1.92 - tp = array_add(package_array, sizeof *tp);
1.93 - memset(tp, 0, sizeof *tp);
1.94 - tp->package = &pkgs[p->data];
1.95 - tp->name = &pool[tp->package->name];
1.96 - tp->version = &pool[tp->package->version];
1.97 - tp->req_package = req_package;
1.98 - tp->req_property = &pool[req->name];
1.99 - tp->req_relation = req->relation;
1.100 - tp->req_version = &pool[req->version];
1.101 - if (already != -1) {
1.102 - tp->state = RAZOR_PACKAGE_REMOVE_BLOCKED;
1.103 - trans->errors++;
1.104 - } else
1.105 - tp->state = RAZOR_PACKAGE_REMOVE;
1.106 - }
1.107 + lose_required_package(trans, package_array, req,
1.108 + &lost_provider->packages);
1.109 }
1.110
1.111 static void
1.112 @@ -2038,41 +2068,74 @@
1.113 struct razor_package *pkgs;
1.114 int pkg_count, r;
1.115 uint32_t *lost, *lost_end;
1.116 + struct razor_entry *entry, **lostf, **lostf_end;
1.117 struct razor_property *props, *prop_end, *req, *first_provider;
1.118 - struct array lost_provides;
1.119 - const char *req_package;
1.120 + struct array lost_provides, lost_files;
1.121 + char *pool;
1.122
1.123 pkgs = trans->system->packages.data;
1.124 pkg_count = trans->system->packages.size / sizeof (struct razor_package);
1.125 props = trans->system->properties.data;
1.126 prop_end = trans->system->properties.data + trans->system->properties.size;
1.127 + pool = trans->system->string_pool.data;
1.128
1.129 + array_init(&lost_files);
1.130 + array_init(&lost_provides);
1.131 for (r = start; r < end; r++) {
1.132 packages = package_array->data;
1.133 if (packages[r].state != RAZOR_PACKAGE_REMOVE)
1.134 continue;
1.135
1.136 - array_init(&lost_provides);
1.137 - req_package = packages[r].name;
1.138 gather_lost_provides(trans->system, packages[r].package,
1.139 &lost_provides);
1.140 + gather_lost_files(trans->system, packages[r].package,
1.141 + &lost_files);
1.142 + }
1.143
1.144 - lost_end = lost_provides.data + lost_provides.size;
1.145 - for (lost = lost_provides.data; lost < lost_end; lost++) {
1.146 - /* Requires FOO will appear before Provides FOO */
1.147 - for (req = &props[*lost]; req > props && req->name == props[*lost].name && req->type != RAZOR_PROPERTY_REQUIRES; req--)
1.148 - ;
1.149 - first_provider = req + 1;
1.150 + /* Handle lost_provides */
1.151 + lost_end = lost_provides.data + lost_provides.size;
1.152 + for (lost = lost_provides.data; lost < lost_end; lost++) {
1.153 + /* Requires FOO will appear before Provides FOO */
1.154 + for (req = &props[*lost]; req > props && req->name == props[*lost].name && req->type != RAZOR_PROPERTY_REQUIRES; req--)
1.155 + ;
1.156 + first_provider = req + 1;
1.157
1.158 - while (req > props && req->name == props[*lost].name) {
1.159 - lose_requirement(trans, package_array,
1.160 - req_package, req,
1.161 - &props[*lost], first_provider);
1.162 - req--;
1.163 - }
1.164 + while (req > props && req->name == props[*lost].name) {
1.165 + lose_requirement(trans, package_array, req,
1.166 + &props[*lost], first_provider);
1.167 + req--;
1.168 }
1.169 - array_release(&lost_provides);
1.170 }
1.171 + array_release(&lost_provides);
1.172 +
1.173 + /* And now lost_files. FIXME, inefficient */
1.174 + lostf_end = lost_files.data + lost_files.size;
1.175 +
1.176 + req = props;
1.177 + /* Due to the sorting of props, this loop is likely a no-op */
1.178 + while (pool[req->name] != '/')
1.179 + req++;
1.180 +
1.181 + for (; req < prop_end && pool[req->name] == '/'; req++) {
1.182 + if (req->type != RAZOR_PROPERTY_REQUIRES)
1.183 + continue;
1.184 +
1.185 + entry = find_entry(trans->system, trans->system->files.data,
1.186 + &pool[req->name]);
1.187 + if (!entry)
1.188 + continue;
1.189 +
1.190 + for (lostf = lost_files.data; lostf < lostf_end; lostf++) {
1.191 + if (*lostf == entry)
1.192 + break;
1.193 + }
1.194 + if (lostf == lostf_end)
1.195 + continue;
1.196 +
1.197 + lose_required_package(trans, package_array, req,
1.198 + &(entry)->packages);
1.199 + }
1.200 + array_release(&lost_files);
1.201 }
1.202
1.203 /* The diff order matters. We should sort the packages so that a