redo razor_set_remove() to only do a single merge
authorDan Winship <danw@gnome.org>
Fri Feb 22 12:49:13 2008 -0500 (2008-02-22)
changeset 13010e6914910dd
parent 129 d221757574c1
child 132 f2c0c5993ff7
redo razor_set_remove() to only do a single merge
razor.c
     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