1.1 --- a/razor.c Fri Feb 22 12:53:07 2008 -0500
1.2 +++ b/razor.c Fri Feb 29 11:46:37 2008 -0500
1.3 @@ -1822,50 +1822,130 @@
1.4 }
1.5 }
1.6
1.7 -/* FIXME: this is all wrong anyway; we should recompute the new_unsatisfied
1.8 - * set as we add and remove packages...
1.9 - */
1.10 +static int
1.11 +find_provider(struct razor_set *set, const char *req_name,
1.12 + enum razor_version_relation relation, const char *version)
1.13 +{
1.14 + struct razor_property *props = set->properties.data;
1.15 + int p, hi, lo, cmp, pkg;
1.16 + char *pool = set->string_pool.data;
1.17 +
1.18 + lo = 0;
1.19 + hi = set->properties.size / sizeof *props;
1.20 + while (lo < hi) {
1.21 + p = (lo + hi) / 2;
1.22 + cmp = strcmp(&pool[props[p].name], req_name);
1.23 + if (cmp < 0)
1.24 + lo = p + 1;
1.25 + else if (cmp > 0)
1.26 + hi = p;
1.27 + else
1.28 + break;
1.29 + }
1.30 + if (lo >= hi)
1.31 + return -1;
1.32 +
1.33 + /* Seek to the last (ie, highest version number) PROVIDES
1.34 + * entry for this name.
1.35 + */
1.36 + if (props[p].type < RAZOR_PROPERTY_PROVIDES) {
1.37 + while (p < hi &&
1.38 + props[p].type != RAZOR_PROPERTY_PROVIDES &&
1.39 + props[p + 1].name == props[p].name)
1.40 + p++;
1.41 + } else if (props[p].type > RAZOR_PROPERTY_PROVIDES) {
1.42 + while (p > lo &&
1.43 + props[p].type != RAZOR_PROPERTY_PROVIDES &&
1.44 + props[p - 1].name == props[p].name)
1.45 + p--;
1.46 + }
1.47 + while (p < hi &&
1.48 + props[p + 1].type == RAZOR_PROPERTY_PROVIDES &&
1.49 + props[p + 1].name == props[p].name)
1.50 + p++;
1.51 +
1.52 + if (props[p].type != RAZOR_PROPERTY_PROVIDES)
1.53 + return -1;
1.54 +
1.55 + do {
1.56 + pkg = list_first(&props[p].packages, &set->package_pool)->data;
1.57 + if (!*version)
1.58 + return pkg;
1.59 +
1.60 + cmp = versioncmp(&pool[props[p].version], version);
1.61 +
1.62 + switch (relation) {
1.63 + case RAZOR_VERSION_EQUAL:
1.64 + case RAZOR_VERSION_GREATER_OR_EQUAL:
1.65 + case RAZOR_VERSION_GREATER:
1.66 + if (cmp >= 0)
1.67 + return pkg;
1.68 + else {
1.69 + /* If the highest version doesn't pass,
1.70 + * none of the others will either.
1.71 + */
1.72 + return -1;
1.73 + }
1.74 +
1.75 + case RAZOR_VERSION_LESS_OR_EQUAL:
1.76 + if (cmp <= 0)
1.77 + return pkg;
1.78 + break;
1.79 +
1.80 + case RAZOR_VERSION_LESS:
1.81 + if (cmp < 0)
1.82 + return pkg;
1.83 + break;
1.84 + }
1.85 +
1.86 + p--;
1.87 + } while (p > lo && props[p].name == props[p + 1].name &&
1.88 + props[p].type == RAZOR_PROPERTY_PROVIDES);
1.89 +
1.90 + return -1;
1.91 +}
1.92 +
1.93 static void
1.94 -razor_set_revalidate(struct razor_set *orig_set,
1.95 - struct array *orig_unsatisfied,
1.96 - struct razor_set *new_set,
1.97 - struct array *new_unsatisfied)
1.98 +gather_new_requires(struct razor_set *system, struct razor_set *upstream,
1.99 + struct razor_package *pkg, struct array *new_requires)
1.100 {
1.101 - uint32_t *nu, *nuend, *ou, *ouend;
1.102 - struct razor_property *new_props, *orig_props;
1.103 - char *new_pool, *orig_pool;
1.104 + struct razor_property *uprops = upstream->properties.data, *prop;
1.105 + char *upool = upstream->string_pool.data;
1.106 + struct list *p;
1.107 + uint32_t *new;
1.108
1.109 - razor_set_validate(new_set, new_unsatisfied);
1.110 + for (p = list_first(&pkg->properties, &upstream->property_pool); p; p = list_next(p)) {
1.111 + prop = &uprops[p->data];
1.112 + if (prop->type != RAZOR_PROPERTY_REQUIRES)
1.113 + continue;
1.114 + if (!strncmp(&upool[prop->name], "rpmlib(", 7))
1.115 + continue;
1.116
1.117 - ouend = orig_unsatisfied->data + orig_unsatisfied->size;
1.118 - nuend = new_unsatisfied->data + new_unsatisfied->size;
1.119 - new_props = new_set->properties.data;
1.120 - orig_props = orig_set->properties.data;
1.121 - new_pool = new_set->string_pool.data;
1.122 - orig_pool = orig_set->string_pool.data;
1.123 -
1.124 - for (nu = new_unsatisfied->data; nu < nuend; nu++) {
1.125 - for (ou = orig_unsatisfied->data; ou < ouend; ou++) {
1.126 - if (!strcmp (&new_pool[new_props[*nu].name],
1.127 - &orig_pool[orig_props[*ou].name]) &&
1.128 - new_props[*nu].relation == orig_props[*ou].relation &&
1.129 - !strcmp (&new_pool[new_props[*nu].version],
1.130 - &orig_pool[orig_props[*ou].version])) {
1.131 - *(nu--) = *(--nuend);
1.132 - break;
1.133 - }
1.134 + if (find_provider(system, &upool[prop->name],
1.135 + prop->relation, &upool[prop->version]) == -1) {
1.136 + new = array_add(new_requires, sizeof *new);
1.137 + *new = p->data;
1.138 }
1.139 }
1.140 -
1.141 - new_unsatisfied->size = (void *)nuend - new_unsatisfied->data;
1.142 }
1.143
1.144 struct razor_set *
1.145 razor_set_update(struct razor_set *set, struct razor_set *upstream,
1.146 int count, const char **packages)
1.147 {
1.148 - struct razor_set *new;
1.149 - struct array list, unsatisfied_before, unsatisfied;
1.150 + struct razor_set *new_set;
1.151 + struct array list;
1.152 + struct razor_package *pkgs;
1.153 + int update_count, u, provider, already;
1.154 + uint32_t *update, *new, *new_end, *required;
1.155 + struct razor_property *props, *prop_end;
1.156 + struct array new_requires;
1.157 + char *pool;
1.158 +
1.159 + pkgs = upstream->packages.data;
1.160 + props = upstream->properties.data;
1.161 + prop_end = upstream->properties.data + set->properties.size;
1.162 + pool = upstream->string_pool.data;
1.163
1.164 array_init(&list);
1.165 if (count > 0)
1.166 @@ -1873,37 +1953,46 @@
1.167 else
1.168 find_all_packages(set, upstream, &list);
1.169
1.170 - array_init(&unsatisfied_before);
1.171 - razor_set_validate(set, &unsatisfied_before);
1.172 + update = list.data;
1.173 + update_count = list.size / sizeof (uint32_t);
1.174 + u = 0;
1.175 + while (u < update_count) {
1.176 + array_init(&new_requires);
1.177 + for (; u < update_count; u++)
1.178 + gather_new_requires(set, upstream, &pkgs[update[u]], &new_requires);
1.179
1.180 - while (list.size > 0) {
1.181 - new = razor_set_add(set, upstream, &list);
1.182 - array_release(&list);
1.183 + new_end = new_requires.data + new_requires.size;
1.184 + for (new = new_requires.data; new < new_end; new++) {
1.185 + provider = find_provider(upstream, &pool[props[*new].name],
1.186 + props[*new].relation,
1.187 + &pool[props[*new].version]);
1.188
1.189 - array_init(&unsatisfied);
1.190 - razor_set_revalidate(set, &unsatisfied_before,
1.191 - new, &unsatisfied);
1.192 + /* FIXME */
1.193 + if (provider == -1)
1.194 + continue;
1.195
1.196 - array_init(&list);
1.197 - razor_set_satisfy(new, &unsatisfied, upstream, &list);
1.198 + update = list.data;
1.199 + update_count = list.size / sizeof (uint32_t);
1.200 + for (already = 0; already < update_count; already++) {
1.201 + if (provider == update[already])
1.202 + break;
1.203 + }
1.204 + if (already < update_count)
1.205 + continue;
1.206
1.207 - if (unsatisfied.size) {
1.208 - /* FIXME: need to return this list */
1.209 - array_release(&unsatisfied);
1.210 - razor_set_destroy(new);
1.211 - razor_set_destroy(set);
1.212 - set = NULL;
1.213 - break;
1.214 + required = array_add(&list, sizeof *required);
1.215 + *required = provider;
1.216 }
1.217 + array_release(&new_requires);
1.218
1.219 - razor_set_destroy(set);
1.220 - set = new;
1.221 + update = list.data;
1.222 + update_count = list.size / sizeof (uint32_t);
1.223 }
1.224
1.225 + new_set = razor_set_add(set, upstream, &list);
1.226 array_release(&list);
1.227 - array_release(&unsatisfied_before);
1.228 -
1.229 - return set;
1.230 + razor_set_destroy(set);
1.231 + return new_set;
1.232 }
1.233
1.234 /* Look through pkg's PROVIDES, and for each one that no other package