Store requires and provides in the same list.
authorKristian H?gsberg <krh@redhat.com>
Wed Oct 31 22:41:27 2007 -0400 (2007-10-31)
changeset 66bb4ca4a47f66
parent 65 8fec3db93757
child 67 cfe57117efee
Store requires and provides in the same list.
TODO
import.c
main.c
razor.c
razor.h
     1.1 --- a/TODO	Sun Oct 28 22:50:57 2007 -0400
     1.2 +++ b/TODO	Wed Oct 31 22:41:27 2007 -0400
     1.3 @@ -20,6 +20,8 @@
     1.4  
     1.5  Misc ideas:
     1.6  
     1.7 +- eliminate duplicate entries in package property lists.
     1.8 +
     1.9  - keep history of installed packages/journal of package transaction,
    1.10    so we can roll back to yesterday, or see what got installed in the
    1.11    latest yum update.
     2.1 --- a/import.c	Sun Oct 28 22:50:57 2007 -0400
     2.2 +++ b/import.c	Wed Oct 31 22:41:27 2007 -0400
     2.3 @@ -60,10 +60,12 @@
     2.4  
     2.5  	switch ((int) data) {
     2.6  	case RZR_REQUIRES:
     2.7 -		razor_importer_add_requires(importer, name, version);
     2.8 +		razor_importer_add_property(importer, name, version,
     2.9 +					    RAZOR_PROPERTY_REQUIRES);
    2.10  		break;
    2.11  	case RZR_PROVIDES:
    2.12 -		razor_importer_add_provides(importer, name, version);
    2.13 +		razor_importer_add_property(importer, name, version,
    2.14 +					    RAZOR_PROPERTY_PROVIDES);
    2.15  		break;
    2.16  	}
    2.17  }
    2.18 @@ -229,10 +231,12 @@
    2.19  			
    2.20  		switch (ctx->state) {
    2.21  		case YUM_STATE_REQUIRES:
    2.22 -			razor_importer_add_requires(ctx->importer, n, buffer);
    2.23 +			razor_importer_add_property(ctx->importer, n, buffer,
    2.24 +						    RAZOR_PROPERTY_REQUIRES);
    2.25  			break;
    2.26  		case YUM_STATE_PROVIDES:
    2.27 -			razor_importer_add_provides(ctx->importer, n, buffer);
    2.28 +			razor_importer_add_property(ctx->importer, n, buffer,
    2.29 +						    RAZOR_PROPERTY_PROVIDES);
    2.30  			break;
    2.31  		}
    2.32  	} else if (strcmp(name, "file") == 0) {
    2.33 @@ -352,18 +356,20 @@
    2.34  		headerGetEntry(h, RPMTAG_REQUIREFLAGS, &type,
    2.35  			       &property_flags.p, &count);
    2.36  		for (i = 0; i < count; i++)
    2.37 -			razor_importer_add_requires(importer,
    2.38 +			razor_importer_add_property(importer,
    2.39  						    property_names.list[i],
    2.40 -						    property_versions.list[i]);
    2.41 +						    property_versions.list[i],
    2.42 +						    RAZOR_PROPERTY_REQUIRES);
    2.43  
    2.44  		headerGetEntry(h, RPMTAG_PROVIDENAME, &type,
    2.45  			       &property_names.p, &count);
    2.46  		headerGetEntry(h, RPMTAG_PROVIDEVERSION, &type,
    2.47  			       &property_versions.p, &count);
    2.48  		for (i = 0; i < count; i++)
    2.49 -			razor_importer_add_provides(importer,
    2.50 +			razor_importer_add_property(importer,
    2.51  						    property_names.list[i],
    2.52 -						    property_versions.list[i]);
    2.53 +						    property_versions.list[i],
    2.54 +						    RAZOR_PROPERTY_PROVIDES);
    2.55  
    2.56  		headerGetEntry(h, RPMTAG_BASENAMES, &type,
    2.57  			       &basenames.p, &count);
     3.1 --- a/main.c	Sun Oct 28 22:50:57 2007 -0400
     3.2 +++ b/main.c	Wed Oct 31 22:41:27 2007 -0400
     3.3 @@ -28,7 +28,7 @@
     3.4  	struct razor_set *set;
     3.5  
     3.6  	set = razor_set_open(repo_filename);
     3.7 -	razor_set_list_requires(set, argv[0]);
     3.8 +	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_REQUIRES);
     3.9  	razor_set_destroy(set);
    3.10  
    3.11  	return 0;
    3.12 @@ -40,7 +40,7 @@
    3.13  	struct razor_set *set;
    3.14  
    3.15  	set = razor_set_open(repo_filename);
    3.16 -	razor_set_list_provides(set, argv[0]);
    3.17 +	razor_set_list_properties(set, argv[0], RAZOR_PROPERTY_PROVIDES);
    3.18  	razor_set_destroy(set);
    3.19  
    3.20  	return 0;
    3.21 @@ -94,7 +94,8 @@
    3.22  	struct razor_set *set;
    3.23  
    3.24  	set = razor_set_open(repo_filename);
    3.25 -	razor_set_list_requires_packages(set, argv[0], argv[1]);
    3.26 +	razor_set_list_property_packages(set, argv[0], argv[1],
    3.27 +					 RAZOR_PROPERTY_REQUIRES);
    3.28  	razor_set_destroy(set);
    3.29  
    3.30  	return 0;
    3.31 @@ -106,7 +107,8 @@
    3.32  	struct razor_set *set;
    3.33  
    3.34  	set = razor_set_open(repo_filename);
    3.35 -	razor_set_list_provides_packages(set, argv[0], argv[1]);
    3.36 +	razor_set_list_property_packages(set, argv[0], argv[1],
    3.37 +					 RAZOR_PROPERTY_PROVIDES);
    3.38  	razor_set_destroy(set);
    3.39  
    3.40  	return 0;
     4.1 --- a/razor.c	Sun Oct 28 22:50:57 2007 -0400
     4.2 +++ b/razor.c	Wed Oct 31 22:41:27 2007 -0400
     4.3 @@ -39,21 +39,18 @@
     4.4  #define RAZOR_IMMEDIATE		0x80000000ul
     4.5  #define RAZOR_ENTRY_MASK	0x00fffffful
     4.6  
     4.7 -#define RAZOR_STRING_POOL 0
     4.8 -#define RAZOR_PACKAGES 1
     4.9 -#define RAZOR_REQUIRES 2
    4.10 -#define RAZOR_PROVIDES 3
    4.11 -#define RAZOR_FILES 4
    4.12 -#define RAZOR_PACKAGE_POOL 5
    4.13 -#define RAZOR_REQUIRES_POOL 6
    4.14 -#define RAZOR_PROVIDES_POOL 7
    4.15 -#define RAZOR_FILE_POOL 8
    4.16 +#define RAZOR_STRING_POOL	0
    4.17 +#define RAZOR_PACKAGES		1
    4.18 +#define RAZOR_PROPERTIES	2
    4.19 +#define RAZOR_FILES		3
    4.20 +#define RAZOR_PACKAGE_POOL	4
    4.21 +#define RAZOR_PROPERTY_POOL	5
    4.22 +#define RAZOR_FILE_POOL		6
    4.23  
    4.24  struct razor_package {
    4.25  	unsigned long name;
    4.26  	unsigned long version;
    4.27 -	unsigned long requires;
    4.28 -	unsigned long provides;
    4.29 +	unsigned long properties;
    4.30  	unsigned long files;
    4.31  };
    4.32  
    4.33 @@ -72,12 +69,10 @@
    4.34  struct razor_set {
    4.35  	struct array string_pool;
    4.36   	struct array packages;
    4.37 - 	struct array requires;
    4.38 - 	struct array provides;
    4.39 + 	struct array properties;
    4.40   	struct array files;
    4.41  	struct array package_pool;
    4.42 - 	struct array requires_pool;
    4.43 - 	struct array provides_pool;
    4.44 + 	struct array property_pool;
    4.45   	struct array file_pool;
    4.46  	struct razor_set_header *header;
    4.47  };
    4.48 @@ -94,17 +89,11 @@
    4.49  	struct import_directory *last;
    4.50  };
    4.51  
    4.52 -struct import_property_context {
    4.53 -	struct array *all;
    4.54 -	struct array package;
    4.55 -};
    4.56 -
    4.57  struct razor_importer {
    4.58  	struct razor_set *set;
    4.59  	struct array buckets;
    4.60 -	struct import_property_context requires;
    4.61 -	struct import_property_context provides;
    4.62  	struct razor_package *package;
    4.63 +	struct array properties;
    4.64  	struct array files;
    4.65  };
    4.66  
    4.67 @@ -178,12 +167,10 @@
    4.68  struct razor_set_section razor_sections[] = {
    4.69  	{ RAZOR_STRING_POOL,	offsetof(struct razor_set, string_pool) },
    4.70  	{ RAZOR_PACKAGES,	offsetof(struct razor_set, packages) },
    4.71 -	{ RAZOR_REQUIRES,	offsetof(struct razor_set, requires) },
    4.72 -	{ RAZOR_PROVIDES,	offsetof(struct razor_set, provides) },
    4.73 +	{ RAZOR_PROPERTIES,	offsetof(struct razor_set, properties) },
    4.74  	{ RAZOR_FILES,		offsetof(struct razor_set, files) },
    4.75  	{ RAZOR_PACKAGE_POOL,	offsetof(struct razor_set, package_pool) },
    4.76 -	{ RAZOR_REQUIRES_POOL,	offsetof(struct razor_set, requires_pool) },
    4.77 -	{ RAZOR_PROVIDES_POOL,	offsetof(struct razor_set, provides_pool) },
    4.78 +	{ RAZOR_PROPERTY_POOL,	offsetof(struct razor_set, property_pool) },
    4.79  	{ RAZOR_FILE_POOL,	offsetof(struct razor_set, file_pool) },
    4.80  };
    4.81  
    4.82 @@ -427,8 +414,7 @@
    4.83  	p->version = razor_importer_tokenize(importer, version);
    4.84  
    4.85  	importer->package = p;
    4.86 -	array_init(&importer->requires.package);
    4.87 -	array_init(&importer->provides.package);
    4.88 +	array_init(&importer->properties);
    4.89  }
    4.90  
    4.91  void
    4.92 @@ -437,47 +423,28 @@
    4.93  	struct razor_package *p;
    4.94  
    4.95  	p = importer->package;
    4.96 -	p->requires = add_to_property_pool(&importer->set->requires_pool,
    4.97 -					   &importer->requires.package);
    4.98 -	p->provides = add_to_property_pool(&importer->set->provides_pool,
    4.99 -					   &importer->provides.package);
   4.100 +	p->properties = add_to_property_pool(&importer->set->property_pool,
   4.101 +					     &importer->properties);
   4.102  
   4.103 -	array_release(&importer->requires.package);
   4.104 -	array_release(&importer->provides.package);
   4.105 +	array_release(&importer->properties);
   4.106  }
   4.107  
   4.108 -static void
   4.109 +void
   4.110  razor_importer_add_property(struct razor_importer *importer,
   4.111 -			    struct import_property_context *pctx,
   4.112 -			    const char *name, const char *version)
   4.113 +			    const char *name, const char *version,
   4.114 +			    enum razor_property_type type)
   4.115  {
   4.116  	struct razor_property *p;
   4.117  	unsigned long *r;
   4.118  
   4.119 -	p = array_add(pctx->all, sizeof *p);
   4.120 -	p->name = razor_importer_tokenize(importer, name);
   4.121 +	p = array_add(&importer->set->properties, sizeof *p);
   4.122 +	p->name = razor_importer_tokenize(importer, name) | (type << 30);
   4.123  	p->version = razor_importer_tokenize(importer, version);
   4.124  	p->packages = importer->package -
   4.125  		(struct razor_package *) importer->set->packages.data;
   4.126  
   4.127 -	r = array_add(&pctx->package, sizeof *r);
   4.128 -	*r = p - (struct razor_property *) pctx->all->data;
   4.129 -}
   4.130 -
   4.131 -void
   4.132 -razor_importer_add_requires(struct razor_importer *importer,
   4.133 -			    const char *name, const char *version)
   4.134 -{
   4.135 -	razor_importer_add_property(importer,
   4.136 -				    &importer->requires, name, version);
   4.137 -}
   4.138 -
   4.139 -void
   4.140 -razor_importer_add_provides(struct razor_importer *importer,
   4.141 -			    const char *name, const char *version)
   4.142 -{
   4.143 -	razor_importer_add_property(importer,
   4.144 -				    &importer->provides, name, version);
   4.145 +	r = array_add(&importer->properties, sizeof *r);
   4.146 +	*r = p - (struct razor_property *) importer->set->properties.data;
   4.147  }
   4.148  
   4.149  void
   4.150 @@ -499,8 +466,6 @@
   4.151  
   4.152  	importer = zalloc(sizeof *importer);
   4.153  	importer->set = razor_set_create();
   4.154 -	importer->requires.all = &importer->set->requires;
   4.155 -	importer->provides.all = &importer->set->provides;
   4.156  
   4.157  	return importer;
   4.158  }
   4.159 @@ -658,37 +623,41 @@
   4.160  	char *pool = set->string_pool.data;
   4.161  
   4.162  	if (prop1->name == prop2->name)
   4.163 -		return versioncmp(&pool[prop1->version], &pool[prop2->version]);
   4.164 +		return versioncmp(&pool[prop1->version],
   4.165 +				  &pool[prop2->version]);
   4.166 +	else if ((prop1->name & RAZOR_ENTRY_MASK) == (prop2->name & RAZOR_ENTRY_MASK))
   4.167 +		return (prop1->name >> 30) - (prop2->name >> 30);
   4.168  	else
   4.169 -		return strcmp(&pool[prop1->name], &pool[prop2->name]);
   4.170 +		return strcmp(&pool[prop1->name & RAZOR_ENTRY_MASK],
   4.171 +			      &pool[prop2->name & RAZOR_ENTRY_MASK]);
   4.172  }
   4.173  
   4.174  static unsigned long *
   4.175 -uniqueify_properties(struct razor_set *set, struct array *properties)
   4.176 +uniqueify_properties(struct razor_set *set)
   4.177  {
   4.178  	struct razor_property *rp, *up, *rp_end;
   4.179  	struct array *pkgs, *p;
   4.180  	unsigned long *map, *rmap, *r;
   4.181  	int i, count, unique;
   4.182  
   4.183 -	count = properties->size / sizeof(struct razor_property);
   4.184 -	map = qsort_with_data(properties->data,
   4.185 +	count = set->properties.size / sizeof(struct razor_property);
   4.186 +	map = qsort_with_data(set->properties.data,
   4.187  			      count,
   4.188  			      sizeof(struct razor_property),
   4.189  			      compare_properties,
   4.190  			      set);
   4.191  
   4.192 -	rp_end = properties->data + properties->size;
   4.193 +	rp_end = set->properties.data + set->properties.size;
   4.194  	rmap = malloc(count * sizeof *map);
   4.195  	pkgs = zalloc(count * sizeof *pkgs);
   4.196 -	for (rp = properties->data, up = rp, i = 0; rp < rp_end; rp++, i++) {
   4.197 +	for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
   4.198  		if (rp->name != up->name || rp->version != up->version) {
   4.199  			up++;
   4.200  			up->name = rp->name;
   4.201  			up->version = rp->version;
   4.202  		}
   4.203  
   4.204 -		unique = up - (struct razor_property *) properties->data;
   4.205 +		unique = up - (struct razor_property *) set->properties.data;
   4.206  		rmap[map[i]] = unique;
   4.207  		r = array_add(&pkgs[unique], sizeof *r);
   4.208  		*r = rp->packages;
   4.209 @@ -696,9 +665,9 @@
   4.210  	free(map);
   4.211  
   4.212  	up++;
   4.213 -	properties->size = (void *) up - properties->data;
   4.214 +	set->properties.size = (void *) up - set->properties.data;
   4.215  	rp_end = up;
   4.216 -	for (rp = properties->data, p = pkgs; rp < rp_end; rp++, p++) {
   4.217 +	for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
   4.218  		if (p->size / sizeof *r == 1) {
   4.219  			r = p->data;
   4.220  			rp->packages = *r | RAZOR_IMMEDIATE;
   4.221 @@ -920,12 +889,8 @@
   4.222  	unsigned long *map, *rmap;
   4.223  	int i, count;
   4.224  
   4.225 -	map = uniqueify_properties(importer->set, &importer->set->requires);
   4.226 -	remap_links(&importer->set->requires_pool, map);
   4.227 -	free(map);
   4.228 -
   4.229 -	map = uniqueify_properties(importer->set, &importer->set->provides);
   4.230 -	remap_links(&importer->set->provides_pool, map);
   4.231 +	map = uniqueify_properties(importer->set);
   4.232 +	remap_links(&importer->set->property_pool, map);
   4.233  	free(map);
   4.234  
   4.235  	count = importer->set->packages.size / sizeof(struct razor_package);
   4.236 @@ -943,8 +908,7 @@
   4.237  	build_file_tree(importer);
   4.238  	remap_links(&importer->set->package_pool, rmap);
   4.239  	build_package_file_lists(importer->set, rmap);
   4.240 -	remap_property_package_links(&importer->set->requires, rmap);
   4.241 -	remap_property_package_links(&importer->set->provides, rmap);
   4.242 +	remap_property_package_links(&importer->set->properties, rmap);
   4.243  	free(rmap);
   4.244  
   4.245  	set = importer->set;
   4.246 @@ -1003,93 +967,80 @@
   4.247  
   4.248  	pool = bsearch_set->string_pool.data;
   4.249  
   4.250 -	return strcmp(key, &pool[p->name]);
   4.251 +	return strcmp(key, &pool[p->name & RAZOR_ENTRY_MASK]);
   4.252  }
   4.253  
   4.254  struct razor_property *
   4.255 -razor_set_get_property(struct razor_set *set,
   4.256 -		       struct array *properties,
   4.257 -		       const char *property)
   4.258 +razor_set_get_property(struct razor_set *set, const char *property)
   4.259  {
   4.260  	struct razor_property *p, *start;
   4.261  
   4.262  	bsearch_set = set;
   4.263 -	p = bsearch(property, properties->data,
   4.264 -		    properties->size / sizeof(struct razor_property),
   4.265 +	p = bsearch(property, set->properties.data,
   4.266 +		    set->properties.size / sizeof(struct razor_property),
   4.267  		    sizeof(struct razor_property), compare_property_name);
   4.268  
   4.269 -	start = properties->data;
   4.270 -	while (p > start && (p - 1)->name == p->name)
   4.271 +	start = set->properties.data;
   4.272 +	while (p > start &&
   4.273 +	       ((p - 1)->name & RAZOR_ENTRY_MASK) ==
   4.274 +	       (p->name & RAZOR_ENTRY_MASK))
   4.275  		p--;
   4.276  
   4.277  	return p;
   4.278  }
   4.279  
   4.280 -static void
   4.281 -razor_set_list_all_properties(struct razor_set *set, struct array *properties)
   4.282 +void
   4.283 +razor_set_list_properties(struct razor_set *set, const char *name,
   4.284 +			  enum razor_property_type type)
   4.285  {
   4.286 -	struct razor_property *p, *end;
   4.287 -	char *pool;
   4.288 -
   4.289 -	pool = set->string_pool.data;
   4.290 -	end = properties->data + properties->size;
   4.291 -	for (p = properties->data; p < end; p++)
   4.292 -		printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   4.293 -}
   4.294 -
   4.295 -void
   4.296 -razor_set_list_requires(struct razor_set *set, const char *name)
   4.297 -{
   4.298 -	struct razor_property *p, *requires;
   4.299 +	struct razor_property *p, *properties, *end;
   4.300  	struct razor_package *package;
   4.301  	unsigned long *r;
   4.302  	char *pool;
   4.303  
   4.304 +	pool = set->string_pool.data;
   4.305 +
   4.306  	if (name) {
   4.307  		package = razor_set_get_package(set, name);
   4.308 -		r = (unsigned long *) set->requires_pool.data +
   4.309 -			package->requires;
   4.310 -		requires = set->requires.data;
   4.311 -		pool = set->string_pool.data;
   4.312 +		r = (unsigned long *) set->property_pool.data +
   4.313 +			package->properties;
   4.314 +		properties = set->properties.data;
   4.315  		while (1) {
   4.316 -			p = &requires[*r & RAZOR_ENTRY_MASK];
   4.317 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   4.318 +			p = &properties[*r & RAZOR_ENTRY_MASK];
   4.319 +			if ((p->name >> 30) != type)
   4.320 +				goto next;
   4.321 +			if (pool[p->version] == '\0')
   4.322 +				printf("%s\n",
   4.323 +				       &pool[p->name & RAZOR_ENTRY_MASK]);
   4.324 +			else
   4.325 +				printf("%s-%s\n",
   4.326 +				       &pool[p->name & RAZOR_ENTRY_MASK],
   4.327 +				       &pool[p->version]);
   4.328 +		next:
   4.329  			if (*r++ & RAZOR_IMMEDIATE)
   4.330  				break;
   4.331  		}
   4.332 -	} else
   4.333 -		razor_set_list_all_properties(set, &set->requires);
   4.334 +	} else {
   4.335 +		end = set->properties.data + set->properties.size;
   4.336 +		for (p = set->properties.data; p < end; p++) {
   4.337 +			if ((p->name >> 30) != type)
   4.338 +				continue;
   4.339 +			if (pool[p->version] == '\0')
   4.340 +				printf("%s\n",
   4.341 +				       &pool[p->name & RAZOR_ENTRY_MASK]);
   4.342 +			else
   4.343 +				printf("%s-%s\n",
   4.344 +				       &pool[p->name & RAZOR_ENTRY_MASK],
   4.345 +				       &pool[p->version]);
   4.346 +		}
   4.347 +	}
   4.348  }
   4.349  
   4.350  void
   4.351 -razor_set_list_provides(struct razor_set *set, const char *name)
   4.352 -{
   4.353 -	struct razor_property *p, *provides;
   4.354 -	struct razor_package *package;
   4.355 -	unsigned long *r;
   4.356 -	char *pool;
   4.357 -
   4.358 -	if (name) {
   4.359 -		package = razor_set_get_package(set, name);
   4.360 -		r = (unsigned long *) set->provides_pool.data +
   4.361 -			package->provides;
   4.362 -		provides = set->provides.data;
   4.363 -		pool = set->string_pool.data;
   4.364 -		while (1) {
   4.365 -			p = &provides[*r & RAZOR_ENTRY_MASK];
   4.366 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   4.367 -			if (*r++ & RAZOR_IMMEDIATE)
   4.368 -				break;
   4.369 -		}
   4.370 -	} else 
   4.371 -		razor_set_list_all_properties(set, &set->provides);
   4.372 -}
   4.373 -
   4.374 -static void
   4.375  razor_set_list_property_packages(struct razor_set *set,
   4.376 -				 struct array *properties,
   4.377  				 const char *name,
   4.378 -				 const char *version)
   4.379 +				 const char *version,
   4.380 +				 enum razor_property_type type)
   4.381  {
   4.382  	struct razor_property *property, *end;
   4.383  	struct razor_package *p, *packages;
   4.384 @@ -1099,12 +1050,16 @@
   4.385  	if (name == NULL)
   4.386  		return;
   4.387  
   4.388 -	property = razor_set_get_property(set, properties, name);
   4.389 +	property = razor_set_get_property(set, name);
   4.390  	packages = set->packages.data;
   4.391  	pool = set->string_pool.data;
   4.392 -	end = properties->data + properties->size;
   4.393 -	while (property < end && strcmp(name, &pool[property->name]) == 0) {
   4.394 -		if (version && versioncmp(version, &pool[property->version]) != 0)
   4.395 +	end = set->properties.data + set->properties.size;
   4.396 +	while (property < end &&
   4.397 +	       strcmp(name, &pool[property->name & RAZOR_ENTRY_MASK]) == 0) {
   4.398 +		if (version &&
   4.399 +		    versioncmp(version, &pool[property->version]) != 0)
   4.400 +			goto next;
   4.401 +		if (type != (property->name >> 30))
   4.402  			goto next;
   4.403  		
   4.404  		if (property->packages & RAZOR_IMMEDIATE)
   4.405 @@ -1114,7 +1069,9 @@
   4.406  				set->package_pool.data + property->packages;
   4.407  		while (1) {
   4.408  			p = &packages[*r & RAZOR_ENTRY_MASK];
   4.409 -			printf("%s-%s\n", &pool[p->name], &pool[p->version]);
   4.410 +			printf("%s-%s\n",
   4.411 +			       &pool[p->name & RAZOR_ENTRY_MASK],
   4.412 +			       &pool[p->version]);
   4.413  			if (*r++ & RAZOR_IMMEDIATE)
   4.414  				break;
   4.415  		}
   4.416 @@ -1123,22 +1080,6 @@
   4.417  	}
   4.418  }
   4.419  
   4.420 -void
   4.421 -razor_set_list_requires_packages(struct razor_set *set,
   4.422 -				 const char *name,
   4.423 -				 const char *version)
   4.424 -{
   4.425 -	razor_set_list_property_packages(set, &set->requires, name, version);
   4.426 -}
   4.427 -
   4.428 -void
   4.429 -razor_set_list_provides_packages(struct razor_set *set,
   4.430 -				 const char *name,
   4.431 -				 const char *version)
   4.432 -{
   4.433 -	razor_set_list_property_packages(set, &set->provides, name, version);
   4.434 -}
   4.435 -
   4.436  static struct razor_entry *
   4.437  find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
   4.438  {
   4.439 @@ -1305,22 +1246,30 @@
   4.440  static void
   4.441  razor_set_validate(struct razor_set *set, struct array *unsatisfied)
   4.442  {
   4.443 -	struct razor_property *r, *p, *rend, *pend;
   4.444 +	struct razor_property *r, *p, *end;
   4.445  	unsigned long *u;
   4.446  	char *pool;
   4.447  
   4.448 -	p = set->provides.data;
   4.449 -	rend = set->requires.data + set->requires.size;
   4.450 -	pend = set->provides.data + set->provides.size;
   4.451 +	end = set->properties.data + set->properties.size;
   4.452  	pool = set->string_pool.data;
   4.453  	
   4.454 -	for (r = set->requires.data; r < rend; r++) {
   4.455 -		while (p < pend && strcmp(&pool[r->name], &pool[p->name]) > 0)
   4.456 -			p++;
   4.457 +	for (r = set->properties.data, p = r; r < end; r++) {
   4.458 +		if (r->name >> 30 != RAZOR_PROPERTY_REQUIRES)
   4.459 +			continue;
   4.460 +
   4.461 +		if ((r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK)) {
   4.462 +			p = r;
   4.463 +			while (p < end && p->name == r->name)
   4.464 +				p++;
   4.465 +		}
   4.466  
   4.467  		/* If there is more than one version of a provides,
   4.468  		 * seek to the end for the highest version. */
   4.469 -		while (p + 1 < pend && p->name == (p + 1)->name)
   4.470 +		/* FIXME: This doesn't work if we have a series of
   4.471 +		 * requires a = 1, provides a = 1, requires a = 2,
   4.472 +		 * provides a = 2, as the kernel and kernel-devel
   4.473 +		 * does.*/
   4.474 +		while (p + 1 < end && p->name == (p + 1)->name)
   4.475  			p++;
   4.476  
   4.477  		/* FIXME: We need to track property flags (<, <=, =
   4.478 @@ -1328,13 +1277,15 @@
   4.479  		 * satisfied.  The current code doesn't track that the
   4.480  		 * requires a = 1 isn't satisfied by a = 2 provides. */
   4.481  
   4.482 -		if (p == pend || strcmp(&pool[r->name], &pool[p->name]) != 0 ||
   4.483 +		if (p == end ||
   4.484 +		    (p->name >> 30) != RAZOR_PROPERTY_PROVIDES ||
   4.485 +		    (r->name & RAZOR_ENTRY_MASK) != (p->name & RAZOR_ENTRY_MASK) ||
   4.486  		    versioncmp(&pool[r->version], &pool[p->version]) > 0) {
   4.487  			/* FIXME: We ignore file requires for now. */
   4.488 -			if (pool[r->name] == '/')
   4.489 +			if (pool[r->name & RAZOR_ENTRY_MASK] == '/')
   4.490  				continue;
   4.491  			u = array_add(unsatisfied, sizeof *u);
   4.492 -			*u = r - (struct razor_property *) set->requires.data;
   4.493 +			*u = r - (struct razor_property *) set->properties.data;
   4.494  		}
   4.495  	}
   4.496  }
   4.497 @@ -1343,7 +1294,7 @@
   4.498  razor_set_list_unsatisfied(struct razor_set *set)
   4.499  {
   4.500  	struct array unsatisfied;
   4.501 -	struct razor_property *requires, *r;
   4.502 +	struct razor_property *properties, *r;
   4.503  	unsigned long *u, *end;
   4.504  	char *pool;
   4.505  
   4.506 @@ -1351,13 +1302,18 @@
   4.507  	razor_set_validate(set, &unsatisfied);
   4.508  
   4.509  	end = unsatisfied.data + unsatisfied.size;
   4.510 -	requires = set->requires.data;
   4.511 +	properties = set->properties.data;
   4.512  	pool = set->string_pool.data;
   4.513  
   4.514  	for (u = unsatisfied.data; u < end; u++) {
   4.515 -		r = requires + *u;
   4.516 -		printf("%s-%s not satisfied\n",
   4.517 -		       &pool[r->name], &pool[r->version]);
   4.518 +		r = properties + *u;
   4.519 +		if (pool[r->version] == '\0')
   4.520 +			printf("%ss not satisfied\n",
   4.521 +			       &pool[r->name & RAZOR_ENTRY_MASK]);
   4.522 +		else
   4.523 +			printf("%s-%s not satisfied\n",
   4.524 +			       &pool[r->name & RAZOR_ENTRY_MASK],
   4.525 +			       &pool[r->version]);
   4.526  	}
   4.527  
   4.528  	array_release(&unsatisfied);
   4.529 @@ -1368,8 +1324,7 @@
   4.530  
   4.531  struct source {
   4.532  	struct razor_set *set;
   4.533 -	unsigned long *requires_map;
   4.534 -	unsigned long *provides_map;
   4.535 +	unsigned long *property_map;
   4.536  };
   4.537  
   4.538  static void
   4.539 @@ -1380,13 +1335,9 @@
   4.540  
   4.541  	source->set = set;
   4.542  
   4.543 -	count = set->requires.size / sizeof (struct razor_property);
   4.544 -	size = count * sizeof *source->requires_map;
   4.545 -	source->requires_map = zalloc(size);
   4.546 -
   4.547 -	count = set->provides.size / sizeof (struct razor_property);
   4.548 -	size = count * sizeof *source->provides_map;
   4.549 -	source->provides_map = zalloc(size);
   4.550 +	count = set->properties.size / sizeof (struct razor_property);
   4.551 +	size = count * sizeof *source->property_map;
   4.552 +	source->property_map = zalloc(size);
   4.553  }
   4.554  
   4.555  static void
   4.556 @@ -1404,27 +1355,15 @@
   4.557  	p->name |= flags;
   4.558  	p->version = razor_importer_tokenize(importer,
   4.559  					     &pool[package->version]);
   4.560 -	p->requires = package->requires;
   4.561 -	p->provides = package->provides;
   4.562 +	p->properties = package->properties;
   4.563  
   4.564 -	if (package->requires & RAZOR_IMMEDIATE)
   4.565 -		r = &package->requires;
   4.566 +	if (package->properties & RAZOR_IMMEDIATE)
   4.567 +		r = &package->properties;
   4.568  	else
   4.569  		r = (unsigned long *)
   4.570 -			source->set->requires_pool.data + package->requires;
   4.571 +			source->set->property_pool.data + package->properties;
   4.572  	while (1) {
   4.573 -		source->requires_map[*r & RAZOR_ENTRY_MASK] = 1;
   4.574 -		if (*r++ & RAZOR_IMMEDIATE)
   4.575 -			break;
   4.576 -	}
   4.577 -
   4.578 -	if (package->provides & RAZOR_IMMEDIATE)
   4.579 -		r = &package->requires;
   4.580 -	else
   4.581 -		r = (unsigned long *)
   4.582 -			source->set->provides_pool.data + package->provides;
   4.583 -	while (1) {
   4.584 -		source->provides_map[*r & RAZOR_ENTRY_MASK] = 1;
   4.585 +		source->property_map[*r & RAZOR_ENTRY_MASK] = 1;
   4.586  		if (*r++ & RAZOR_IMMEDIATE)
   4.587  			break;
   4.588  	}
   4.589 @@ -1474,26 +1413,23 @@
   4.590  }
   4.591  
   4.592  static unsigned long
   4.593 -add_property(struct razor_importer *importer, struct array *properties,
   4.594 +add_property(struct razor_importer *importer,
   4.595  	     const char *name, const char *version)
   4.596  {
   4.597  	struct razor_property *p;
   4.598  
   4.599 -	p = array_add(properties, sizeof *p);
   4.600 +	p = array_add(&importer->set->properties, sizeof *p);
   4.601  	p->name = razor_importer_tokenize(importer, name);
   4.602  	p->version = razor_importer_tokenize(importer, version);
   4.603  
   4.604 -	return p - (struct razor_property *) properties->data;
   4.605 +	return p - (struct razor_property *) importer->set->properties.data;
   4.606  }
   4.607  
   4.608  static void
   4.609 -merge_properties(struct array *properties,
   4.610 -		 struct razor_importer *importer,
   4.611 +merge_properties(struct razor_importer *importer,
   4.612  		 struct razor_set *set1,
   4.613 -		 struct array *properties1,
   4.614  		 unsigned long *map1,
   4.615  		 struct razor_set *set2,
   4.616 -		 struct array *properties2,
   4.617  		 unsigned long *map2)
   4.618  {
   4.619  	struct razor_property *p1, *p2;
   4.620 @@ -1505,8 +1441,8 @@
   4.621  	pool1 = set1->string_pool.data;
   4.622  	pool2 = set2->string_pool.data;
   4.623  
   4.624 -	count1 = properties1->size / sizeof *p1;
   4.625 -	count2 = properties2->size / sizeof *p2;
   4.626 +	count1 = set1->properties.size / sizeof *p1;
   4.627 +	count2 = set2->properties.size / sizeof *p2;
   4.628  	while (i < count1 || j < count2) {
   4.629  		if (i < count1 && map1[i] == 0) {
   4.630  			i++;
   4.631 @@ -1516,10 +1452,11 @@
   4.632  			j++;
   4.633  			continue;
   4.634  		}
   4.635 -		p1 = (struct razor_property *) properties1->data + i;
   4.636 -		p2 = (struct razor_property *) properties2->data + j;
   4.637 +		p1 = (struct razor_property *) set1->properties.data + i;
   4.638 +		p2 = (struct razor_property *) set2->properties.data + j;
   4.639  		if (i < count1 && j < count2)
   4.640 -			cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
   4.641 +			cmp = strcmp(&pool1[p1->name & RAZOR_ENTRY_MASK],
   4.642 +				     &pool2[p2->name & RAZOR_ENTRY_MASK]);
   4.643  		else if (i < count1)
   4.644  			cmp = -1;
   4.645  		else
   4.646 @@ -1529,18 +1466,15 @@
   4.647  					 &pool2[p2->version]);
   4.648  		if (cmp < 0) {
   4.649  			map1[i++] = add_property(importer,
   4.650 -						 properties,
   4.651 -						 &pool1[p1->name],
   4.652 +						 &pool1[p1->name & RAZOR_ENTRY_MASK],
   4.653  						 &pool1[p1->version]);
   4.654  		} else if (cmp > 0) {
   4.655  			map2[j++] = add_property(importer,
   4.656 -						 properties,
   4.657 -						 &pool2[p2->name],
   4.658 +						 &pool2[p2->name & RAZOR_ENTRY_MASK],
   4.659  						 &pool2[p2->version]);
   4.660  		} else  {
   4.661  			map1[i++] = map2[j++] = add_property(importer,
   4.662 -							     properties,
   4.663 -							     &pool1[p1->name],
   4.664 +							     &pool1[p1->name & RAZOR_ENTRY_MASK],
   4.665  							     &pool1[p1->version]);
   4.666  		}
   4.667  	}
   4.668 @@ -1571,62 +1505,39 @@
   4.669  static void
   4.670  rebuild_package_lists(struct razor_set *set)
   4.671  {
   4.672 -	int requires_count, provides_count;
   4.673 -	struct array *requires_pkgs, *provides_pkgs, *a;
   4.674 +	struct array *pkgs, *a;
   4.675  	struct razor_package *pkg, *pkg_end;
   4.676  	struct razor_property *prop, *prop_end;
   4.677 -	unsigned long *r, *q, *rpool, *ppool;
   4.678 +	unsigned long *r, *q, *pool;
   4.679 +	int count;
   4.680  
   4.681 -	requires_count = set->requires.size / sizeof (struct razor_property);
   4.682 -	provides_count = set->provides.size / sizeof (struct razor_property);
   4.683 -	requires_pkgs = zalloc(requires_count * sizeof *requires_pkgs);
   4.684 -	provides_pkgs = zalloc(provides_count * sizeof *provides_pkgs);
   4.685 +	count = set->properties.size / sizeof (struct razor_property);
   4.686 +	pkgs = zalloc(count * sizeof *pkgs);
   4.687  	pkg_end = set->packages.data + set->packages.size;
   4.688 -	rpool = set->requires_pool.data;
   4.689 -	ppool = set->provides_pool.data;
   4.690 +	pool = set->property_pool.data;
   4.691  
   4.692  	for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
   4.693 -		for (r = &rpool[pkg->requires]; ; r++) {
   4.694 -			q = array_add(&requires_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   4.695 -			*q = pkg - (struct razor_package *) set->packages.data;
   4.696 -			if (*r & RAZOR_IMMEDIATE)
   4.697 -				break;
   4.698 -		}
   4.699 -		for (r = &ppool[pkg->provides]; ; r++) {
   4.700 -			q = array_add(&provides_pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   4.701 +		for (r = &pool[pkg->properties]; ; r++) {
   4.702 +			q = array_add(&pkgs[*r & RAZOR_ENTRY_MASK], sizeof *q);
   4.703  			*q = pkg - (struct razor_package *) set->packages.data;
   4.704  			if (*r & RAZOR_IMMEDIATE)
   4.705  				break;
   4.706  		}
   4.707  	}
   4.708  
   4.709 -	prop_end = set->requires.data + set->requires.size;
   4.710 -	a = requires_pkgs;
   4.711 -	for (prop = set->requires.data; prop < prop_end; prop++, a++) {
   4.712 +	prop_end = set->properties.data + set->properties.size;
   4.713 +	a = pkgs;
   4.714 +	for (prop = set->properties.data; prop < prop_end; prop++, a++) {
   4.715  		if (a->size / sizeof *r == 1) {
   4.716  			r = a->data;
   4.717  			prop->packages = *r | RAZOR_IMMEDIATE;
   4.718  		} else {
   4.719  			prop->packages =
   4.720 -				add_to_property_pool(&set->requires_pool, a);
   4.721 +				add_to_property_pool(&set->property_pool, a);
   4.722  		}
   4.723  		array_release(a);
   4.724  	}
   4.725 -	free(requires_pkgs);
   4.726 -
   4.727 -	prop_end = set->provides.data + set->provides.size;
   4.728 -	a = provides_pkgs;
   4.729 -	for (prop = set->provides.data; prop < prop_end; prop++, a++) {
   4.730 -		if (a->size / sizeof *r == 1) {
   4.731 -			r = a->data;
   4.732 -			prop->packages = *r | RAZOR_IMMEDIATE;
   4.733 -		} else {
   4.734 -			prop->packages =
   4.735 -				add_to_property_pool(&set->provides_pool, a);
   4.736 -		}
   4.737 -		array_release(a);
   4.738 -	}
   4.739 -	free(provides_pkgs);
   4.740 +	free(pkgs);
   4.741  }
   4.742  
   4.743  /* Add packages from 'upstream' to 'set'.  The packages to add are
   4.744 @@ -1663,14 +1574,9 @@
   4.745  	 * indices in the old property list to indices in the new
   4.746  	 * property list for both sets. */
   4.747  
   4.748 -	merge_properties(&importer->set->requires, importer,
   4.749 -			 set, &set->requires, source.requires_map,
   4.750 -			 upstream, &upstream->requires,
   4.751 -			 upstream_source.requires_map);
   4.752 -	merge_properties(&importer->set->provides, importer,
   4.753 -			 set, &set->provides, source.provides_map,
   4.754 -			 upstream, &upstream->provides,
   4.755 -			 upstream_source.provides_map);
   4.756 +	merge_properties(importer,
   4.757 +			 set, source.property_map,
   4.758 +			 upstream, upstream_source.property_map);
   4.759  
   4.760  	/* Now we loop through the packages again and emit the
   4.761  	 * property lists, remapped to point to the new properties. */
   4.762 @@ -1684,14 +1590,10 @@
   4.763  		else
   4.764  			src = &source;
   4.765  
   4.766 -		p->requires = emit_properties(&src->set->requires_pool,
   4.767 -					      p->requires,
   4.768 -					      src->requires_map,
   4.769 -					      &importer->set->requires_pool);
   4.770 -		p->provides = emit_properties(&src->set->provides_pool,
   4.771 -					      p->provides,
   4.772 -					      src->provides_map,
   4.773 -					      &importer->set->provides_pool);
   4.774 +		p->properties = emit_properties(&src->set->property_pool,
   4.775 +						p->properties,
   4.776 +						src->property_map,
   4.777 +						&importer->set->property_pool);
   4.778  		p->name &= INDEX_MASK;
   4.779  	}
   4.780  
   4.781 @@ -1714,18 +1616,21 @@
   4.782  	char *pool, *upool;
   4.783  
   4.784  	end = unsatisfied->data + unsatisfied->size;
   4.785 -	requires = set->requires.data;
   4.786 +	requires = set->properties.data;
   4.787  	pool = set->string_pool.data;
   4.788  
   4.789 -	p = upstream->provides.data;
   4.790 -	pend = upstream->provides.data + upstream->provides.size;
   4.791 +	p = upstream->properties.data;
   4.792 +	pend = upstream->properties.data + upstream->properties.size;
   4.793  	upool = upstream->string_pool.data;
   4.794  	package_pool = upstream->package_pool.data;
   4.795  
   4.796  	for (u = unsatisfied->data; u < end; u++) {
   4.797  		r = requires + *u;
   4.798  
   4.799 -		while (p < pend && strcmp(&pool[r->name], &upool[p->name]) > 0)
   4.800 +		while (p < pend &&
   4.801 +		       strcmp(&pool[r->name & RAZOR_ENTRY_MASK],
   4.802 +			      &upool[p->name & RAZOR_ENTRY_MASK]) > 0 &&
   4.803 +		       (p->name >> 30) != RAZOR_PROPERTY_PROVIDES)
   4.804  			p++;
   4.805  		/* If there is more than one version of a provides,
   4.806  		 * seek to the end for the highest version. */
   4.807 @@ -1733,7 +1638,8 @@
   4.808  			p++;
   4.809  
   4.810  		if (p == pend ||
   4.811 -		    strcmp(&pool[r->name], &upool[p->name]) != 0 ||
   4.812 +		    strcmp(&pool[r->name & RAZOR_ENTRY_MASK],
   4.813 +			   &upool[p->name & RAZOR_ENTRY_MASK]) != 0 ||
   4.814  		    versioncmp(&pool[r->version], &upool[p->version]) > 0) {
   4.815  			/* Do we need to track unsatisfiable requires
   4.816  			 * as we go, or should we just do a
     5.1 --- a/razor.h	Sun Oct 28 22:50:57 2007 -0400
     5.2 +++ b/razor.h	Wed Oct 31 22:41:27 2007 -0400
     5.3 @@ -5,19 +5,24 @@
     5.4  
     5.5  struct razor_set;
     5.6  
     5.7 +enum razor_property_type {
     5.8 +	RAZOR_PROPERTY_REQUIRES,
     5.9 +	RAZOR_PROPERTY_PROVIDES,
    5.10 +	RAZOR_PROPERTY_CONFLICTS,
    5.11 +	RAZOR_PROPERTY_OBSOLETES
    5.12 +};
    5.13 +
    5.14  struct razor_set *razor_set_open(const char *filename);
    5.15  void razor_set_destroy(struct razor_set *set);
    5.16  int razor_set_write(struct razor_set *set, const char *filename);
    5.17  
    5.18  void razor_set_list(struct razor_set *set, const char *pattern);
    5.19 -void razor_set_list_requires(struct razor_set *set, const char *name);
    5.20 -void razor_set_list_provides(struct razor_set *set, const char *name);
    5.21 -void razor_set_list_requires_packages(struct razor_set *set,
    5.22 +void razor_set_list_properties(struct razor_set *set, const char *name,
    5.23 +			       enum razor_property_type type);
    5.24 +void razor_set_list_property_packages(struct razor_set *set,
    5.25  				      const char *name,
    5.26 -				      const char *version);
    5.27 -void razor_set_list_provides_packages(struct razor_set *set,
    5.28 -				      const char *name,
    5.29 -				      const char *version);
    5.30 +				      const char *version,
    5.31 +				      enum razor_property_type type);
    5.32  void razor_set_list_files(struct razor_set *set, const char *prefix);
    5.33  void razor_set_list_file_packages(struct razor_set *set, const char *filename);
    5.34  void razor_set_list_package_files(struct razor_set *set, const char *name);
    5.35 @@ -44,10 +49,9 @@
    5.36  struct razor_importer *razor_importer_new(void);
    5.37  void razor_importer_begin_package(struct razor_importer *importer,
    5.38  				const char *name, const char *version);
    5.39 -void razor_importer_add_requires(struct razor_importer *importer,
    5.40 -				 const char *name, const char *version);
    5.41 -void razor_importer_add_provides(struct razor_importer *importer,
    5.42 -				 const char *name, const char *version);
    5.43 +void razor_importer_add_property(struct razor_importer *importer,
    5.44 +				 const char *name, const char *version,
    5.45 +				 enum razor_property_type type);
    5.46  void razor_importer_add_file(struct razor_importer *importer,
    5.47  			     const char *name);
    5.48  void razor_importer_finish_package(struct razor_importer *importer);