1.1 --- a/razor.c Thu Feb 21 12:09:13 2008 -0500
1.2 +++ b/razor.c Fri Feb 22 12:49:13 2008 -0500
1.3 @@ -1847,65 +1847,110 @@
1.4 return set;
1.5 }
1.6
1.7 +/* Look through pkg's PROVIDES, and for each one that no other package
1.8 + * provides, add its property index to lost_provides.
1.9 + */
1.10 +static void
1.11 +gather_lost_provides(struct razor_set *set, struct razor_package *pkg,
1.12 + struct array *lost_provides)
1.13 +{
1.14 + struct razor_property *props = set->properties.data, *prop;
1.15 + struct list *p, *providers;
1.16 + uint32_t *lost;
1.17 +
1.18 + for (p = list_first(&pkg->properties, &set->property_pool); p; p = list_next(p)) {
1.19 + prop = &props[p->data];
1.20 + if (prop->type != RAZOR_PROPERTY_PROVIDES)
1.21 + continue;
1.22 +
1.23 + providers = list_first(&prop->packages, &set->package_pool);
1.24 + if (providers && !list_next(providers)) {
1.25 + lost = array_add(lost_provides, sizeof *lost);
1.26 + *lost = p->data;
1.27 + }
1.28 + }
1.29 +}
1.30 +
1.31 +/* Add the index of each package required by req that isn't already in
1.32 + * lost_requires, to lost_requires
1.33 + */
1.34 +static void
1.35 +gather_lost_requires(struct razor_set *set, struct razor_property *req,
1.36 + struct array *lost_requires)
1.37 +{
1.38 + struct list *p;
1.39 + uint32_t *lost, *already_lost, *already_end;
1.40 +
1.41 + for (p = list_first(&req->packages, &set->package_pool); p; p = list_next(p)) {
1.42 + already_end = lost_requires->data + lost_requires->size;
1.43 + for (already_lost = lost_requires->data; already_lost < already_end; already_lost++) {
1.44 + if (*already_lost == p->data)
1.45 + break;
1.46 + }
1.47 +
1.48 + if (already_lost == already_end) {
1.49 + lost = array_add(lost_requires, sizeof *lost);
1.50 + *lost = p->data;
1.51 + }
1.52 + }
1.53 +}
1.54 +
1.55 static struct razor_set *
1.56 -razor_set_remove_internal(struct razor_set *set, struct array *list,
1.57 - struct array *unsatisfied)
1.58 +razor_set_remove_internal(struct razor_set *set, struct array *list)
1.59 {
1.60 struct razor_set *empty, *new;
1.61 struct razor_merger *merger;
1.62 struct razor_package *pkgs;
1.63 int pkg_count, remove_count, p, r;
1.64 - struct array unsatisfied_before;
1.65 - uint32_t *u, *uend, *ub, *ubend;
1.66 - struct razor_property *props, *propsb;
1.67 - char *pool, *poolb;
1.68 + uint32_t *remove, *lost, *lost_end;
1.69 + struct razor_property *props, *prop_end, *req;
1.70 + struct array lost_provides;
1.71
1.72 - array_init(&unsatisfied_before);
1.73 - razor_set_validate(set, &unsatisfied_before);
1.74 + pkgs = set->packages.data;
1.75 + pkg_count = set->packages.size / sizeof (struct razor_package);
1.76 + props = set->properties.data;
1.77 + prop_end = set->properties.data + set->properties.size;
1.78 +
1.79 + remove = list->data;
1.80 + remove_count = list->size / sizeof (uint32_t);
1.81 + r = 0;
1.82 + while (r < remove_count) {
1.83 + array_init(&lost_provides);
1.84 + for (; r < remove_count; r++)
1.85 + gather_lost_provides(set, &pkgs[remove[r]], &lost_provides);
1.86 +
1.87 + lost_end = lost_provides.data + lost_provides.size;
1.88 + for (lost = lost_provides.data; lost < lost_end; lost++) {
1.89 + /* Requires FOO will appear before Provides FOO */
1.90 + for (req = &props[*lost]; req > props && req->name == props[*lost].name && req->type != RAZOR_PROPERTY_REQUIRES; req--)
1.91 + ;
1.92 + /* FIXME: versioned deps... */
1.93 + while (req > props && req->name == props[*lost].name) {
1.94 + gather_lost_requires(set, req, list);
1.95 + req--;
1.96 + }
1.97 + }
1.98 + array_release(&lost_provides);
1.99 +
1.100 + remove = list->data;
1.101 + remove_count = list->size / sizeof (uint32_t);
1.102 + }
1.103
1.104 empty = razor_set_create();
1.105 merger = razor_merger_create(set, empty);
1.106
1.107 - remove_count = list->size / sizeof (uint32_t);
1.108 - pkg_count = set->packages.size / sizeof (struct razor_package);
1.109 - pkgs = set->packages.data;
1.110 -
1.111 for (p = 0; p < pkg_count; p++) {
1.112 for (r = 0; r < remove_count; r++) {
1.113 - if (p == ((uint32_t *)list->data)[r])
1.114 + if (p == remove[r])
1.115 goto skip;
1.116 }
1.117 -
1.118 add_package(merger, &pkgs[p], &merger->source1, 0);
1.119 skip:
1.120 ;
1.121 }
1.122
1.123 new = razor_merger_finish(merger);
1.124 -
1.125 - razor_set_validate(new, unsatisfied);
1.126 -
1.127 - ubend = unsatisfied_before.data + unsatisfied_before.size;
1.128 - uend = unsatisfied->data + unsatisfied->size;
1.129 - props = new->properties.data;
1.130 - propsb = set->properties.data;
1.131 - pool = new->string_pool.data;
1.132 - poolb = set->string_pool.data;
1.133 -
1.134 - for (u = unsatisfied->data; u < uend; u++) {
1.135 - for (ub = unsatisfied_before.data; ub < ubend; ub++) {
1.136 - if (!strcmp (&pool[props[*u].name],
1.137 - &poolb[propsb[*ub].name]) &&
1.138 - props[*u].relation == propsb[*ub].relation &&
1.139 - !strcmp (&pool[props[*u].version],
1.140 - &poolb[propsb[*ub].version])) {
1.141 - *(u--) = *(--uend);
1.142 - break;
1.143 - }
1.144 - }
1.145 - }
1.146 -
1.147 - unsatisfied->size = (void *)uend - unsatisfied->data;
1.148 + razor_set_destroy(empty);
1.149 return new;
1.150 }
1.151
1.152 @@ -1913,40 +1958,14 @@
1.153 razor_set_remove(struct razor_set *set, int count, const char **packages)
1.154 {
1.155 struct razor_set *new;
1.156 - struct array list, unsatisfied;
1.157 - struct razor_property *props;
1.158 - uint32_t *u, *uend, *p;
1.159 - struct list *r;
1.160 + struct array list;
1.161
1.162 array_init(&list);
1.163 find_packages(set, count, packages, &list);
1.164 -
1.165 - while (list.size > 0) {
1.166 - array_init(&unsatisfied);
1.167 - new = razor_set_remove_internal(set, &list, &unsatisfied);
1.168 - array_release(&list);
1.169 - razor_set_destroy(set);
1.170 - set = new;
1.171 -
1.172 - props = set->properties.data;
1.173 - array_init(&list);
1.174 - uend = unsatisfied.data + unsatisfied.size;
1.175 - for (u = unsatisfied.data; u < uend; u++) {
1.176 - if (props[*u].type == RAZOR_PROPERTY_REQUIRES) {
1.177 - r = list_first(&props[*u].packages, &set->package_pool);
1.178 - while (r) {
1.179 - p = array_add(&list, sizeof *p);
1.180 - *p = r->data;
1.181 - r = list_next(r);
1.182 - }
1.183 - }
1.184 - }
1.185 -
1.186 - array_release(&unsatisfied);
1.187 - }
1.188 -
1.189 + new = razor_set_remove_internal(set, &list);
1.190 array_release(&list);
1.191 - return set;
1.192 + razor_set_destroy(set);
1.193 + return new;
1.194 }
1.195
1.196 /* The diff order matters. We should sort the packages so that a