razor.c
changeset 66 bb4ca4a47f66
parent 64 8e37a9f8fd70
child 69 35ca1ba469ec
     1.1 --- a/razor.c	Thu Oct 25 23:35:42 2007 -0400
     1.2 +++ b/razor.c	Wed Oct 31 22:41:27 2007 -0400
     1.3 @@ -39,21 +39,18 @@
     1.4  #define RAZOR_IMMEDIATE		0x80000000ul
     1.5  #define RAZOR_ENTRY_MASK	0x00fffffful
     1.6  
     1.7 -#define RAZOR_STRING_POOL 0
     1.8 -#define RAZOR_PACKAGES 1
     1.9 -#define RAZOR_REQUIRES 2
    1.10 -#define RAZOR_PROVIDES 3
    1.11 -#define RAZOR_FILES 4
    1.12 -#define RAZOR_PACKAGE_POOL 5
    1.13 -#define RAZOR_REQUIRES_POOL 6
    1.14 -#define RAZOR_PROVIDES_POOL 7
    1.15 -#define RAZOR_FILE_POOL 8
    1.16 +#define RAZOR_STRING_POOL	0
    1.17 +#define RAZOR_PACKAGES		1
    1.18 +#define RAZOR_PROPERTIES	2
    1.19 +#define RAZOR_FILES		3
    1.20 +#define RAZOR_PACKAGE_POOL	4
    1.21 +#define RAZOR_PROPERTY_POOL	5
    1.22 +#define RAZOR_FILE_POOL		6
    1.23  
    1.24  struct razor_package {
    1.25  	unsigned long name;
    1.26  	unsigned long version;
    1.27 -	unsigned long requires;
    1.28 -	unsigned long provides;
    1.29 +	unsigned long properties;
    1.30  	unsigned long files;
    1.31  };
    1.32  
    1.33 @@ -72,12 +69,10 @@
    1.34  struct razor_set {
    1.35  	struct array string_pool;
    1.36   	struct array packages;
    1.37 - 	struct array requires;
    1.38 - 	struct array provides;
    1.39 + 	struct array properties;
    1.40   	struct array files;
    1.41  	struct array package_pool;
    1.42 - 	struct array requires_pool;
    1.43 - 	struct array provides_pool;
    1.44 + 	struct array property_pool;
    1.45   	struct array file_pool;
    1.46  	struct razor_set_header *header;
    1.47  };
    1.48 @@ -94,17 +89,11 @@
    1.49  	struct import_directory *last;
    1.50  };
    1.51  
    1.52 -struct import_property_context {
    1.53 -	struct array *all;
    1.54 -	struct array package;
    1.55 -};
    1.56 -
    1.57  struct razor_importer {
    1.58  	struct razor_set *set;
    1.59  	struct array buckets;
    1.60 -	struct import_property_context requires;
    1.61 -	struct import_property_context provides;
    1.62  	struct razor_package *package;
    1.63 +	struct array properties;
    1.64  	struct array files;
    1.65  };
    1.66  
    1.67 @@ -178,12 +167,10 @@
    1.68  struct razor_set_section razor_sections[] = {
    1.69  	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
    1.70  	{ RAZOR_PACKAGES,	offsetof(struct razor_set, packages) },
    1.71 -	{ RAZOR_REQUIRES,	offsetof(struct razor_set, requires) },
    1.72 -	{ RAZOR_PROVIDES,	offsetof(struct razor_set, provides) },
    1.73 +	{ RAZOR_PROPERTIES,	offsetof(struct razor_set, properties) },
    1.74  	{ RAZOR_FILES,		offsetof(struct razor_set, files) },
    1.75  	{ RAZOR_PACKAGE_POOL,	offsetof(struct razor_set, package_pool) },
    1.76 -	{ RAZOR_REQUIRES_POOL,	offsetof(struct razor_set, requires_pool) },
    1.77 -	{ RAZOR_PROVIDES_POOL,	offsetof(struct razor_set, provides_pool) },
    1.78 +	{ RAZOR_PROPERTY_POOL,	offsetof(struct razor_set, property_pool) },
    1.79  	{ RAZOR_FILE_POOL,	offsetof(struct razor_set, file_pool) },
    1.80  };
    1.81  
    1.82 @@ -427,8 +414,7 @@
    1.83  	p->version = razor_importer_tokenize(importer, version);
    1.84  
    1.85  	importer->package = p;
    1.86 -	array_init(&importer->requires.package);
    1.87 -	array_init(&importer->provides.package);
    1.88 +	array_init(&importer->properties);
    1.89  }
    1.90  
    1.91  void
    1.92 @@ -437,47 +423,28 @@
    1.93  	struct razor_package *p;
    1.94  
    1.95  	p = importer->package;
    1.96 -	p->requires = add_to_property_pool(&importer->set->requires_pool,
    1.97 -					   &importer->requires.package);
    1.98 -	p->provides = add_to_property_pool(&importer->set->provides_pool,
    1.99 -					   &importer->provides.package);
   1.100 +	p->properties = add_to_property_pool(&importer->set->property_pool,
   1.101 +					     &importer->properties);
   1.102  
   1.103 -	array_release(&importer->requires.package);
   1.104 -	array_release(&importer->provides.package);
   1.105 +	array_release(&importer->properties);
   1.106  }
   1.107  
   1.108 -static void
   1.109 +void
   1.110  razor_importer_add_property(struct razor_importer *importer,
   1.111 -			    struct import_property_context *pctx,
   1.112 -			    const char *name, const char *version)
   1.113 +			    const char *name, const char *version,
   1.114 +			    enum razor_property_type type)
   1.115  {
   1.116  	struct razor_property *p;
   1.117  	unsigned long *r;
   1.118  
   1.119 -	p = array_add(pctx->all, sizeof *p);
   1.120 -	p->name = razor_importer_tokenize(importer, name);
   1.121 +	p = array_add(&importer->set->properties, sizeof *p);
   1.122 +	p->name = razor_importer_tokenize(importer, name) | (type << 30);
   1.123  	p->version = razor_importer_tokenize(importer, version);
   1.124  	p->packages = importer->package -
   1.125  		(struct razor_package *) importer->set->packages.data;
   1.126  
   1.127 -	r = array_add(&pctx->package, sizeof *r);
   1.128 -	*r = p - (struct razor_property *) pctx->all->data;
   1.129 -}
   1.130 -
   1.131 -void
   1.132 -razor_importer_add_requires(struct razor_importer *importer,
   1.133 -			    const char *name, const char *version)
   1.134 -{
   1.135 -	razor_importer_add_property(importer,
   1.136 -				    &importer->requires, name, version);
   1.137 -}
   1.138 -
   1.139 -void
   1.140 -razor_importer_add_provides(struct razor_importer *importer,
   1.141 -			    const char *name, const char *version)
   1.142 -{
   1.143 -	razor_importer_add_property(importer,
   1.144 -				    &importer->provides, name, version);
   1.145 +	r = array_add(&importer->properties, sizeof *r);
   1.146 +	*r = p - (struct razor_property *) importer->set->properties.data;
   1.147  }
   1.148  
   1.149  void
   1.150 @@ -499,8 +466,6 @@
   1.151  
   1.152  	importer = zalloc(sizeof *importer);
   1.153  	importer->set = razor_set_create();
   1.154 -	importer->requires.all = &importer->set->requires;
   1.155 -	importer->provides.all = &importer->set->provides;
   1.156  
   1.157  	return importer;
   1.158  }
   1.159 @@ -658,37 +623,41 @@
   1.160  	char *pool = set->string_pool.data;
   1.161  
   1.162  	if (prop1->name == prop2->name)
   1.163 -		return versioncmp(&pool[prop1->version], &pool[prop2->version]);
   1.164 +		return versioncmp(&pool[prop1->version],
   1.165 +				  &pool[prop2->version]);
   1.166 +	else if ((prop1->name & RAZOR_ENTRY_MASK) == (prop2->name & RAZOR_ENTRY_MASK))
   1.167 +		return (prop1->name >> 30) - (prop2->name >> 30);
   1.168  	else
   1.169 -		return strcmp(&pool[prop1->name], &pool[prop2->name]);
   1.170 +		return strcmp(&pool[prop1->name & RAZOR_ENTRY_MASK],
   1.171 +			      &pool[prop2->name & RAZOR_ENTRY_MASK]);
   1.172  }
   1.173  
   1.174  static unsigned long *
   1.175 -uniqueify_properties(struct razor_set *set, struct array *properties)
   1.176 +uniqueify_properties(struct razor_set *set)
   1.177  {
   1.178  	struct razor_property *rp, *up, *rp_end;
   1.179  	struct array *pkgs, *p;
   1.180  	unsigned long *map, *rmap, *r;
   1.181  	int i, count, unique;
   1.182  
   1.183 -	count = properties->size / sizeof(struct razor_property);
   1.184 -	map = qsort_with_data(properties->data,
   1.185 +	count = set->properties.size / sizeof(struct razor_property);
   1.186 +	map = qsort_with_data(set->properties.data,
   1.187  			      count,
   1.188  			      sizeof(struct razor_property),
   1.189  			      compare_properties,
   1.190  			      set);
   1.191  
   1.192 -	rp_end = properties->data + properties->size;
   1.193 +	rp_end = set->properties.data + set->properties.size;
   1.194  	rmap = malloc(count * sizeof *map);
   1.195  	pkgs = zalloc(count * sizeof *pkgs);
   1.196 -	for (rp = properties->data, up = rp, i = 0; rp < rp_end; rp++, i++) {
   1.197 +	for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
   1.198  		if (rp->name != up->name || rp->version != up->version) {
   1.199  			up++;
   1.200  			up->name = rp->name;
   1.201  			up->version = rp->version;
   1.202  		}
   1.203  
   1.204 -		unique = up - (struct razor_property *) properties->data;
   1.205 +		unique = up - (struct razor_property *) set->properties.data;
   1.206  		rmap[map[i]] = unique;
   1.207  		r = array_add(&pkgs[unique], sizeof *r);
   1.208  		*r = rp->packages;
   1.209 @@ -696,9 +665,9 @@
   1.210  	free(map);
   1.211  
   1.212  	up++;
   1.213 -	properties->size = (void *) up - properties->data;
   1.214 +	set->properties.size = (void *) up - set->properties.data;
   1.215  	rp_end = up;
   1.216 -	for (rp = properties->data, p = pkgs; rp < rp_end; rp++, p++) {
   1.217 +	for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
   1.218  		if (p->size / sizeof *r == 1) {
   1.219  			r = p->data;
   1.220  			rp->packages = *r | RAZOR_IMMEDIATE;
   1.221 @@ -920,12 +889,8 @@
   1.222  	unsigned long *map, *rmap;
   1.223  	int i, count;
   1.224  
   1.225 -	map = uniqueify_properties(importer->set, &importer->set->requires);
   1.226 -	remap_links(&importer->set->requires_pool, map);
   1.227 -	free(map);
   1.228 -
   1.229 -	map = uniqueify_properties(importer->set, &importer->set->provides);
   1.230 -	remap_links(&importer->set->provides_pool, map);
   1.231 +	map = uniqueify_properties(importer->set);
   1.232 +	remap_links(&importer->set->property_pool, map);
   1.233  	free(map);
   1.234  
   1.235  	count = importer->set->packages.size / sizeof(struct razor_package);
   1.236 @@ -943,8 +908,7 @@
   1.237  	build_file_tree(importer);
   1.238  	remap_links(&importer->set->package_pool, rmap);
   1.239  	build_package_file_lists(importer->set, rmap);
   1.240 -	remap_property_package_links(&importer->set->requires, rmap);
   1.241 -	remap_property_package_links(&importer->set->provides, rmap);
   1.242 +	remap_property_package_links(&importer->set->properties, rmap);
   1.243  	free(rmap);
   1.244  
   1.245  	set = importer->set;
   1.246 @@ -1003,93 +967,80 @@
   1.247  
   1.248  	pool = bsearch_set->string_pool.data;
   1.249  
   1.250 -	return strcmp(key, &pool[p->name]);
   1.251 +	return strcmp(key, &pool[p->name & RAZOR_ENTRY_MASK]);
   1.252  }
   1.253  
   1.254  struct razor_property *
   1.255 -razor_set_get_property(struct razor_set *set,
   1.256 -		       struct array *properties,
   1.257 -		       const char *property)
   1.258 +razor_set_get_property(struct razor_set *set, const char *property)
   1.259  {
   1.260  	struct razor_property *p, *start;
   1.261  
   1.262  	bsearch_set = set;
   1.263 -	p = bsearch(property, properties->data,
   1.264 -		    properties->size / sizeof(struct razor_property),
   1.265 +	p = bsearch(property, set->properties.data,
   1.266 +		    set->properties.size / sizeof(struct razor_property),
   1.267  		    sizeof(struct razor_property), compare_property_name);
   1.268  
   1.269 -	start = properties->data;
   1.270 -	while (p > start && (p - 1)->name == p->name)
   1.271 +	start = set->properties.data;
   1.272 +	while (p > start &&
   1.273 +	       ((p - 1)->name & RAZOR_ENTRY_MASK) ==
   1.274 +	       (p->name & RAZOR_ENTRY_MASK))
   1.275  		p--;
   1.276  
   1.277  	return p;
   1.278  }
   1.279  
   1.280 -static void
   1.281 -razor_set_list_all_properties(struct razor_set *set, struct array *properties)
   1.282 +void
   1.283 +razor_set_list_properties(struct razor_set *set, const char *name,
   1.284 +			  enum razor_property_type type)
   1.285  {
   1.286 -	struct razor_property *p, *end;
   1.287 -	char *pool;
   1.288 -
   1.289 -	pool = set->string_pool.data;
   1.290 -	end = properties->data + properties->size;
   1.291 -	for (p = properties->data; p < end; p++)
   1.292 -		printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   1.293 -}
   1.294 -
   1.295 -void
   1.296 -razor_set_list_requires(struct razor_set *set, const char *name)
   1.297 -{
   1.298 -	struct razor_property *p, *requires;
   1.299 +	struct razor_property *p, *properties, *end;
   1.300  	struct razor_package *package;
   1.301  	unsigned long *r;
   1.302  	char *pool;
   1.303  
   1.304 +	pool = set->string_pool.data;
   1.305 +
   1.306  	if (name) {
   1.307  		package = razor_set_get_package(set, name);
   1.308 -		r = (unsigned long *) set->requires_pool.data +
   1.309 -			package->requires;
   1.310 -		requires = set->requires.data;
   1.311 -		pool = set->string_pool.data;
   1.312 +		r = (unsigned long *) set->property_pool.data +
   1.313 +			package->properties;
   1.314 +		properties = set->properties.data;
   1.315  		while (1) {
   1.316 -			p = &requires[*r & RAZOR_ENTRY_MASK];
   1.317 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   1.318 +			p = &properties[*r & RAZOR_ENTRY_MASK];
   1.319 +			if ((p->name >> 30) != type)
   1.320 +				goto next;
   1.321 +			if (pool[p->version] == '\0')
   1.322 +				printf("%s\n",
   1.323 +				       &pool[p->name & RAZOR_ENTRY_MASK]);
   1.324 +			else
   1.325 +				printf("%s-%s\n",
   1.326 +				       &pool[p->name & RAZOR_ENTRY_MASK],
   1.327 +				       &pool[p->version]);
   1.328 +		next:
   1.329  			if (*r++ & RAZOR_IMMEDIATE)
   1.330  				break;
   1.331  		}
   1.332 -	} else
   1.333 -		razor_set_list_all_properties(set, &set->requires);
   1.334 +	} else {
   1.335 +		end = set->properties.data + set->properties.size;
   1.336 +		for (p = set->properties.data; p < end; p++) {
   1.337 +			if ((p->name >> 30) != type)
   1.338 +				continue;
   1.339 +			if (pool[p->version] == '\0')
   1.340 +				printf("%s\n",
   1.341 +				       &pool[p->name & RAZOR_ENTRY_MASK]);
   1.342 +			else
   1.343 +				printf("%s-%s\n",
   1.344 +				       &pool[p->name & RAZOR_ENTRY_MASK],
   1.345 +				       &pool[p->version]);
   1.346 +		}
   1.347 +	}
   1.348  }
   1.349  
   1.350  void
   1.351 -razor_set_list_provides(struct razor_set *set, const char *name)
   1.352 -{
   1.353 -	struct razor_property *p, *provides;
   1.354 -	struct razor_package *package;
   1.355 -	unsigned long *r;
   1.356 -	char *pool;
   1.357 -
   1.358 -	if (name) {
   1.359 -		package = razor_set_get_package(set, name);
   1.360 -		r = (unsigned long *) set->provides_pool.data +
   1.361 -			package->provides;
   1.362 -		provides = set->provides.data;
   1.363 -		pool = set->string_pool.data;
   1.364 -		while (1) {
   1.365 -			p = &provides[*r & RAZOR_ENTRY_MASK];
   1.366 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   1.367 -			if (*r++ & RAZOR_IMMEDIATE)
   1.368 -				break;
   1.369 -		}
   1.370 -	} else 
   1.371 -		razor_set_list_all_properties(set, &set->provides);
   1.372 -}
   1.373 -
   1.374 -static void
   1.375  razor_set_list_property_packages(struct razor_set *set,
   1.376 -				 struct array *properties,
   1.377  				 const char *name,
   1.378 -				 const char *version)
   1.379 +				 const char *version,
   1.380 +				 enum razor_property_type type)
   1.381  {
   1.382  	struct razor_property *property, *end;
   1.383  	struct razor_package *p, *packages;
   1.384 @@ -1099,12 +1050,16 @@
   1.385  	if (name == NULL)
   1.386  		return;
   1.387  
   1.388 -	property = razor_set_get_property(set, properties, name);
   1.389 +	property = razor_set_get_property(set, name);
   1.390  	packages = set->packages.data;
   1.391  	pool = set->string_pool.data;
   1.392 -	end = properties->data + properties->size;
   1.393 -	while (property < end && strcmp(name, &pool[property->name]) == 0) {
   1.394 -		if (version && versioncmp(version, &pool[property->version]) != 0)
   1.395 +	end = set->properties.data + set->properties.size;
   1.396 +	while (property < end &&
   1.397 +	       strcmp(name, &pool[property->name & RAZOR_ENTRY_MASK]) == 0) {
   1.398 +		if (version &&
   1.399 +		    versioncmp(version, &pool[property->version]) != 0)
   1.400 +			goto next;
   1.401 +		if (type != (property->name >> 30))
   1.402  			goto next;
   1.403  		
   1.404  		if (property->packages & RAZOR_IMMEDIATE)
   1.405 @@ -1114,7 +1069,9 @@
   1.406  				set->package_pool.data + property->packages;
   1.407  		while (1) {
   1.408  			p = &packages[*r & RAZOR_ENTRY_MASK];
   1.409 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   1.410 +			printf("%s-%s\n",
   1.411 +			       &pool[p->name & RAZOR_ENTRY_MASK],
   1.412 +			       &pool[p->version]);
   1.413  			if (*r++ & RAZOR_IMMEDIATE)
   1.414  				break;
   1.415  		}
   1.416 @@ -1123,22 +1080,6 @@
   1.417  	}
   1.418  }
   1.419  
   1.420 -void
   1.421 -razor_set_list_requires_packages(struct razor_set *set,
   1.422 -				 const char *name,
   1.423 -				 const char *version)
   1.424 -{
   1.425 -	razor_set_list_property_packages(set, &set->requires, name, version);
   1.426 -}
   1.427 -
   1.428 -void
   1.429 -razor_set_list_provides_packages(struct razor_set *set,
   1.430 -				 const char *name,
   1.431 -				 const char *version)
   1.432 -{
   1.433 -	razor_set_list_property_packages(set, &set->provides, name, version);
   1.434 -}
   1.435 -
   1.436  static struct razor_entry *
   1.437  find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
   1.438  {
   1.439 @@ -1305,22 +1246,30 @@
   1.440  static void
   1.441  razor_set_validate(struct razor_set *set, struct array *unsatisfied)
   1.442  {
   1.443 -	struct razor_property *r, *p, *rend, *pend;
   1.444 +	struct razor_property *r, *p, *end;
   1.445  	unsigned long *u;
   1.446  	char *pool;
   1.447  
   1.448 -	p = set->provides.data;
   1.449 -	rend = set->requires.data + set->requires.size;
   1.450 -	pend = set->provides.data + set->provides.size;
   1.451 +	end = set->properties.data + set->properties.size;
   1.452  	pool = set->string_pool.data;
   1.453  	
   1.454 -	for (r = set->requires.data; r < rend; r++) {
   1.455 -		while (p < pend && strcmp(&pool[r->name], &pool[p->name]) > 0)
   1.456 -			p++;
   1.457 +	for (r = set->properties.data, p = r; r < end; r++) {
   1.458 +		if (r->name >> 30 != RAZOR_PROPERTY_REQUIRES)
   1.459 +			continue;
   1.460 +
   1.461 +		if ((r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK)) {
   1.462 +			p = r;
   1.463 +			while (p < end && p->name == r->name)
   1.464 +				p++;
   1.465 +		}
   1.466  
   1.467  		/* If there is more than one version of a provides,
   1.468  		 * seek to the end for the highest version. */
   1.469 -		while (p + 1 < pend && p->name == (p + 1)->name)
   1.470 +		/* FIXME: This doesn't work if we have a series of
   1.471 +		 * requires a = 1, provides a = 1, requires a = 2,
   1.472 +		 * provides a = 2, as the kernel and kernel-devel
   1.473 +		 * does.*/
   1.474 +		while (p + 1 < end && p->name == (p + 1)->name)
   1.475  			p++;
   1.476  
   1.477  		/* FIXME: We need to track property flags (<, <=, =
   1.478 @@ -1328,13 +1277,15 @@
   1.479  		 * satisfied.  The current code doesn't track that the
   1.480  		 * requires a = 1 isn't satisfied by a = 2 provides. */
   1.481  
   1.482 -		if (p == pend || strcmp(&pool[r->name], &pool[p->name]) != 0 ||
   1.483 +		if (p == end ||
   1.484 +		    (p->name >> 30) != RAZOR_PROPERTY_PROVIDES ||
   1.485 +		    (r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK) ||
   1.486  		    versioncmp(&pool[r->version], &pool[p->version]) > 0) {
   1.487  			/* FIXME: We ignore file requires for now. */
   1.488 -			if (pool[r->name] == '/')
   1.489 +			if (pool[r->name & RAZOR_ENTRY_MASK] == '/')
   1.490  				continue;
   1.491  			u = array_add(unsatisfied, sizeof *u);
   1.492 -			*u = r - (struct razor_property *) set->requires.data;
   1.493 +			*u = r - (struct razor_property *) set->properties.data;
   1.494  		}
   1.495  	}
   1.496  }
   1.497 @@ -1343,7 +1294,7 @@
   1.498  razor_set_list_unsatisfied(struct razor_set *set)
   1.499  {
   1.500  	struct array unsatisfied;
   1.501 -	struct razor_property *requires, *r;
   1.502 +	struct razor_property *properties, *r;
   1.503  	unsigned long *u, *end;
   1.504  	char *pool;
   1.505  
   1.506 @@ -1351,13 +1302,18 @@
   1.507  	razor_set_validate(set, &unsatisfied);
   1.508  
   1.509  	end = unsatisfied.data + unsatisfied.size;
   1.510 -	requires = set->requires.data;
   1.511 +	properties = set->properties.data;
   1.512  	pool = set->string_pool.data;
   1.513  
   1.514  	for (u = unsatisfied.data; u < end; u++) {
   1.515 -		r = requires + *u;
   1.516 -		printf("%s-%s not satisfied\n",
   1.517 -		       &pool[r->name], &pool[r->version]);
   1.518 +		r = properties + *u;
   1.519 +		if (pool[r->version] == '\0')
   1.520 +			printf("%ss not satisfied\n",
   1.521 +			       &pool[r->name & RAZOR_ENTRY_MASK]);
   1.522 +		else
   1.523 +			printf("%s-%s not satisfied\n",
   1.524 +			       &pool[r->name & RAZOR_ENTRY_MASK],
   1.525 +			       &pool[r->version]);
   1.526  	}
   1.527  
   1.528  	array_release(&unsatisfied);
   1.529 @@ -1368,8 +1324,7 @@
   1.530  
   1.531  struct source {
   1.532  	struct razor_set *set;
   1.533 -	unsigned long *requires_map;
   1.534 -	unsigned long *provides_map;
   1.535 +	unsigned long *property_map;
   1.536  };
   1.537  
   1.538  static void
   1.539 @@ -1380,13 +1335,9 @@
   1.540  
   1.541  	source->set = set;
   1.542  
   1.543 -	count = set->requires.size / sizeof (struct razor_property);
   1.544 -	size = count * sizeof *source->requires_map;
   1.545 -	source->requires_map = zalloc(size);
   1.546 -
   1.547 -	count = set->provides.size / sizeof (struct razor_property);
   1.548 -	size = count * sizeof *source->provides_map;
   1.549 -	source->provides_map = zalloc(size);
   1.550 +	count = set->properties.size / sizeof (struct razor_property);
   1.551 +	size = count * sizeof *source->property_map;
   1.552 +	source->property_map = zalloc(size);
   1.553  }
   1.554  
   1.555  static void
   1.556 @@ -1404,27 +1355,15 @@
   1.557  	p->name |= flags;
   1.558  	p->version = razor_importer_tokenize(importer,
   1.559  					     &pool[package->version]);
   1.560 -	p->requires = package->requires;
   1.561 -	p->provides = package->provides;
   1.562 +	p->properties = package->properties;
   1.563  
   1.564 -	if (package->requires & RAZOR_IMMEDIATE)
   1.565 -		r = &package->requires;
   1.566 +	if (package->properties & RAZOR_IMMEDIATE)
   1.567 +		r = &package->properties;
   1.568  	else
   1.569  		r = (unsigned long *)
   1.570 -			source->set->requires_pool.data + package->requires;
   1.571 +			source->set->property_pool.data + package->properties;
   1.572  	while (1) {
   1.573 -		source->requires_map[*r & RAZOR_ENTRY_MASK] = 1;
   1.574 -		if (*r++ & RAZOR_IMMEDIATE)
   1.575 -			break;
   1.576 -	}
   1.577 -
   1.578 -	if (package->provides & RAZOR_IMMEDIATE)
   1.579 -		r = &package->requires;
   1.580 -	else
   1.581 -		r = (unsigned long *)
   1.582 -			source->set->provides_pool.data + package->provides;
   1.583 -	while (1) {
   1.584 -		source->provides_map[*r & RAZOR_ENTRY_MASK] = 1;
   1.585 +		source->property_map[*r & RAZOR_ENTRY_MASK] = 1;
   1.586  		if (*r++ & RAZOR_IMMEDIATE)
   1.587  			break;
   1.588  	}
   1.589 @@ -1474,26 +1413,23 @@
   1.590  }
   1.591  
   1.592  static unsigned long
   1.593 -add_property(struct razor_importer *importer, struct array *properties,
   1.594 +add_property(struct razor_importer *importer,
   1.595  	     const char *name, const char *version)
   1.596  {
   1.597  	struct razor_property *p;
   1.598  
   1.599 -	p = array_add(properties, sizeof *p);
   1.600 +	p = array_add(&importer->set->properties, sizeof *p);
   1.601  	p->name = razor_importer_tokenize(importer, name);
   1.602  	p->version = razor_importer_tokenize(importer, version);
   1.603  
   1.604 -	return p - (struct razor_property *) properties->data;
   1.605 +	return p - (struct razor_property *) importer->set->properties.data;
   1.606  }
   1.607  
   1.608  static void
   1.609 -merge_properties(struct array *properties,
   1.610 -		 struct razor_importer *importer,
   1.611 +merge_properties(struct razor_importer *importer,
   1.612  		 struct razor_set *set1,
   1.613 -		 struct array *properties1,
   1.614  		 unsigned long *map1,
   1.615  		 struct razor_set *set2,
   1.616 -		 struct array *properties2,
   1.617  		 unsigned long *map2)
   1.618  {
   1.619  	struct razor_property *p1, *p2;
   1.620 @@ -1505,8 +1441,8 @@
   1.621  	pool1 = set1->string_pool.data;
   1.622  	pool2 = set2->string_pool.data;
   1.623  
   1.624 -	count1 = properties1->size / sizeof *p1;
   1.625 -	count2 = properties2->size / sizeof *p2;
   1.626 +	count1 = set1->properties.size / sizeof *p1;
   1.627 +	count2 = set2->properties.size / sizeof *p2;
   1.628  	while (i < count1 || j < count2) {
   1.629  		if (i < count1 && map1[i] == 0) {
   1.630  			i++;
   1.631 @@ -1516,10 +1452,11 @@
   1.632  			j++;
   1.633  			continue;
   1.634  		}
   1.635 -		p1 = (struct razor_property *) properties1->data + i;
   1.636 -		p2 = (struct razor_property *) properties2->data + j;
   1.637 +		p1 = (struct razor_property *) set1->properties.data + i;
   1.638 +		p2 = (struct razor_property *) set2->properties.data + j;
   1.639  		if (i < count1 && j < count2)
   1.640 -			cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
   1.641 +			cmp = strcmp(&pool1[p1->name & RAZOR_ENTRY_MASK],
   1.642 +				     &pool2[p2->name & RAZOR_ENTRY_MASK]);
   1.643  		else if (i < count1)
   1.644  			cmp = -1;
   1.645  		else
   1.646 @@ -1529,18 +1466,15 @@
   1.647  					 &pool2[p2->version]);
   1.648  		if (cmp < 0) {
   1.649  			map1[i++] = add_property(importer,
   1.650 -						 properties,
   1.651 -						 &pool1[p1->name],
   1.652 +						 &pool1[p1->name & RAZOR_ENTRY_MASK],
   1.653  						 &pool1[p1->version]);
   1.654  		} else if (cmp > 0) {
   1.655  			map2[j++] = add_property(importer,
   1.656 -						 properties,
   1.657 -						 &pool2[p2->name],
   1.658 +						 &pool2[p2->name & RAZOR_ENTRY_MASK],
   1.659  						 &pool2[p2->version]);
   1.660  		} else  {
   1.661  			map1[i++] = map2[j++] = add_property(importer,
   1.662 -							     properties,
   1.663 -							     &pool1[p1->name],
   1.664 +							     &pool1[p1->name & RAZOR_ENTRY_MASK],
   1.665  							     &pool1[p1->version]);
   1.666  		}
   1.667  	}
   1.668 @@ -1571,62 +1505,39 @@
   1.669  static void
   1.670  rebuild_package_lists(struct razor_set *set)
   1.671  {
   1.672 -	int requires_count, provides_count;
   1.673 -	struct array *requires_pkgs, *provides_pkgs, *a;
   1.674 +	struct array *pkgs, *a;
   1.675  	struct razor_package *pkg, *pkg_end;
   1.676  	struct razor_property *prop, *prop_end;
   1.677 -	unsigned long *r, *q, *rpool, *ppool;
   1.678 +	unsigned long *r, *q, *pool;
   1.679 +	int count;
   1.680  
   1.681 -	requires_count = set->requires.size / sizeof (struct razor_property);
   1.682 -	provides_count = set->provides.size / sizeof (struct razor_property);
   1.683 -	requires_pkgs = zalloc(requires_count * sizeof *requires_pkgs);
   1.684 -	provides_pkgs = zalloc(provides_count * sizeof *provides_pkgs);
   1.685 +	count = set->properties.size / sizeof (struct razor_property);
   1.686 +	pkgs = zalloc(count * sizeof *pkgs);
   1.687  	pkg_end = set->packages.data + set->packages.size;
   1.688 -	rpool = set->requires_pool.data;
   1.689 -	ppool = set->provides_pool.data;
   1.690 +	pool = set->property_pool.data;
   1.691  
   1.692  	for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
   1.693 -		for (r = &rpool[pkg->requires]; ; r++) {
   1.694 -			q = array_add(&requires_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   1.695 -			*q = pkg - (struct razor_package *) set->packages.data;
   1.696 -			if (*r & RAZOR_IMMEDIATE)
   1.697 -				break;
   1.698 -		}
   1.699 -		for (r = &ppool[pkg->provides]; ; r++) {
   1.700 -			q = array_add(&provides_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   1.701 +		for (r = &pool[pkg->properties]; ; r++) {
   1.702 +			q = array_add(&pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   1.703  			*q = pkg - (struct razor_package *) set->packages.data;
   1.704  			if (*r & RAZOR_IMMEDIATE)
   1.705  				break;
   1.706  		}
   1.707  	}
   1.708  
   1.709 -	prop_end = set->requires.data + set->requires.size;
   1.710 -	a = requires_pkgs;
   1.711 -	for (prop = set->requires.data; prop < prop_end; prop++, a++) {
   1.712 +	prop_end = set->properties.data + set->properties.size;
   1.713 +	a = pkgs;
   1.714 +	for (prop = set->properties.data; prop < prop_end; prop++, a++) {
   1.715  		if (a->size / sizeof *r == 1) {
   1.716  			r = a->data;
   1.717  			prop->packages = *r | RAZOR_IMMEDIATE;
   1.718  		} else {
   1.719  			prop->packages =
   1.720 -				add_to_property_pool(&set->requires_pool, a);
   1.721 +				add_to_property_pool(&set->property_pool, a);
   1.722  		}
   1.723  		array_release(a);
   1.724  	}
   1.725 -	free(requires_pkgs);
   1.726 -
   1.727 -	prop_end = set->provides.data + set->provides.size;
   1.728 -	a = provides_pkgs;
   1.729 -	for (prop = set->provides.data; prop < prop_end; prop++, a++) {
   1.730 -		if (a->size / sizeof *r == 1) {
   1.731 -			r = a->data;
   1.732 -			prop->packages = *r | RAZOR_IMMEDIATE;
   1.733 -		} else {
   1.734 -			prop->packages =
   1.735 -				add_to_property_pool(&set->provides_pool, a);
   1.736 -		}
   1.737 -		array_release(a);
   1.738 -	}
   1.739 -	free(provides_pkgs);
   1.740 +	free(pkgs);
   1.741  }
   1.742  
   1.743  /* Add packages from 'upstream' to 'set'.  The packages to add are
   1.744 @@ -1663,14 +1574,9 @@
   1.745  	 * indices in the old property list to indices in the new
   1.746  	 * property list for both sets. */
   1.747  
   1.748 -	merge_properties(&importer->set->requires, importer,
   1.749 -			 set, &set->requires, source.requires_map,
   1.750 -			 upstream, &upstream->requires,
   1.751 -			 upstream_source.requires_map);
   1.752 -	merge_properties(&importer->set->provides, importer,
   1.753 -			 set, &set->provides, source.provides_map,
   1.754 -			 upstream, &upstream->provides,
   1.755 -			 upstream_source.provides_map);
   1.756 +	merge_properties(importer,
   1.757 +			 set, source.property_map,
   1.758 +			 upstream, upstream_source.property_map);
   1.759  
   1.760  	/* Now we loop through the packages again and emit the
   1.761  	 * property lists, remapped to point to the new properties. */
   1.762 @@ -1684,14 +1590,10 @@
   1.763  		else
   1.764  			src = &source;
   1.765  
   1.766 -		p->requires = emit_properties(&src->set->requires_pool,
   1.767 -					      p->requires,
   1.768 -					      src->requires_map,
   1.769 -					      &importer->set->requires_pool);
   1.770 -		p->provides = emit_properties(&src->set->provides_pool,
   1.771 -					      p->provides,
   1.772 -					      src->provides_map,
   1.773 -					      &importer->set->provides_pool);
   1.774 +		p->properties = emit_properties(&src->set->property_pool,
   1.775 +						p->properties,
   1.776 +						src->property_map,
   1.777 +						&importer->set->property_pool);
   1.778  		p->name &= INDEX_MASK;
   1.779  	}
   1.780  
   1.781 @@ -1714,18 +1616,21 @@
   1.782  	char *pool, *upool;
   1.783  
   1.784  	end = unsatisfied->data + unsatisfied->size;
   1.785 -	requires = set->requires.data;
   1.786 +	requires = set->properties.data;
   1.787  	pool = set->string_pool.data;
   1.788  
   1.789 -	p = upstream->provides.data;
   1.790 -	pend = upstream->provides.data + upstream->provides.size;
   1.791 +	p = upstream->properties.data;
   1.792 +	pend = upstream->properties.data + upstream->properties.size;
   1.793  	upool = upstream->string_pool.data;
   1.794  	package_pool = upstream->package_pool.data;
   1.795  
   1.796  	for (u = unsatisfied->data; u < end; u++) {
   1.797  		r = requires + *u;
   1.798  
   1.799 -		while (p < pend && strcmp(&pool[r->name], &upool[p->name]) > 0)
   1.800 +		while (p < pend &&
   1.801 +		       strcmp(&pool[r->name & RAZOR_ENTRY_MASK],
   1.802 +			      &upool[p->name & RAZOR_ENTRY_MASK]) > 0 &&
   1.803 +		       (p->name >> 30) != RAZOR_PROPERTY_PROVIDES)
   1.804  			p++;
   1.805  		/* If there is more than one version of a provides,
   1.806  		 * seek to the end for the highest version. */
   1.807 @@ -1733,7 +1638,8 @@
   1.808  			p++;
   1.809  
   1.810  		if (p == pend ||
   1.811 -		    strcmp(&pool[r->name], &upool[p->name]) != 0 ||
   1.812 +		    strcmp(&pool[r->name & RAZOR_ENTRY_MASK],
   1.813 +			   &upool[p->name & RAZOR_ENTRY_MASK]) != 0 ||
   1.814  		    versioncmp(&pool[r->version], &upool[p->version]) > 0) {
   1.815  			/* Do we need to track unsatisfiable requires
   1.816  			 * as we go, or should we just do a