razor.c
changeset 136 eef2b734f2cc
parent 132 f2c0c5993ff7
child 137 4722cd3437cb
     1.1 --- a/razor.c	Fri Feb 22 12:53:07 2008 -0500
     1.2 +++ b/razor.c	Fri Feb 29 11:51:58 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