librazor/razor.c
changeset 252 3e696ec612a5
parent 247 63444a10fb8e
child 253 338a577cdfd2
child 258 29d5002bd17f
     1.1 --- a/librazor/razor.c	Fri Jun 20 14:18:52 2008 -0400
     1.2 +++ b/librazor/razor.c	Fri Jun 20 21:33:29 2008 -0400
     1.3 @@ -35,89 +35,8 @@
     1.4  
     1.5  #include "razor.h"
     1.6  #include "razor-internal.h"
     1.7 -#include "types.h"
     1.8  
     1.9 -struct razor_set_section {
    1.10 -	uint32_t type;
    1.11 -	uint32_t offset;
    1.12 -	uint32_t size;
    1.13 -};
    1.14 -
    1.15 -struct razor_set_header {
    1.16 -	uint32_t magic;
    1.17 -	uint32_t version;
    1.18 -	struct razor_set_section sections[0];
    1.19 -};
    1.20 -
    1.21 -#define RAZOR_MAGIC 0x7a7a7a7a
    1.22 -#define RAZOR_VERSION 1
    1.23 -
    1.24 -#define RAZOR_STRING_POOL	0
    1.25 -#define RAZOR_PACKAGES		1
    1.26 -#define RAZOR_PROPERTIES	2
    1.27 -#define RAZOR_FILES		3
    1.28 -#define RAZOR_PACKAGE_POOL	4
    1.29 -#define RAZOR_PROPERTY_POOL	5
    1.30 -#define RAZOR_FILE_POOL		6
    1.31 -
    1.32 -struct razor_package {
    1.33 -	uint name  : 24;
    1.34 -	uint flags : 8;
    1.35 -	uint32_t version;
    1.36 -	uint32_t arch;
    1.37 -	struct list_head properties;
    1.38 -	struct list_head files;
    1.39 -};
    1.40 -
    1.41 -struct razor_property {
    1.42 -	uint32_t name;
    1.43 -	uint32_t flags;
    1.44 -	uint32_t version;
    1.45 -	struct list_head packages;
    1.46 -};
    1.47 -
    1.48 -struct razor_entry {
    1.49 -	uint name  : 24;
    1.50 -	uint flags : 8;
    1.51 -	uint32_t start;
    1.52 -	struct list_head packages;
    1.53 -};
    1.54 -
    1.55 -#define RAZOR_ENTRY_LAST	0x80
    1.56 -
    1.57 -struct razor_set {
    1.58 -	struct array string_pool;
    1.59 - 	struct array packages;
    1.60 - 	struct array properties;
    1.61 - 	struct array files;
    1.62 -	struct array package_pool;
    1.63 - 	struct array property_pool;
    1.64 - 	struct array file_pool;
    1.65 -	struct razor_set_header *header;
    1.66 -};
    1.67 -
    1.68 -struct import_entry {
    1.69 -	uint32_t package;
    1.70 -	char *name;
    1.71 -};
    1.72 -
    1.73 -struct import_directory {
    1.74 -	uint32_t name, count;
    1.75 -	struct array files;
    1.76 -	struct array packages;
    1.77 -	struct import_directory *last;
    1.78 -};
    1.79 -
    1.80 -struct razor_importer {
    1.81 -	struct razor_set *set;
    1.82 -	struct hashtable table;
    1.83 -	struct razor_package *package;
    1.84 -	struct array properties;
    1.85 -	struct array files;
    1.86 -	struct array file_requires;
    1.87 -};
    1.88 -
    1.89 -static void *
    1.90 +void *
    1.91  zalloc(size_t size)
    1.92  {
    1.93  	void *p;
    1.94 @@ -296,95 +215,8 @@
    1.95  		snprintf(evr_buf, size, "-%s", release);
    1.96  }
    1.97  
    1.98 -void
    1.99 -razor_importer_begin_package(struct razor_importer *importer,
   1.100 -			     const char *name,
   1.101 -			     const char *version,
   1.102 -			     const char *arch)
   1.103 -{
   1.104 -	struct razor_package *p;
   1.105 -
   1.106 -	p = array_add(&importer->set->packages, sizeof *p);
   1.107 -	p->name = hashtable_tokenize(&importer->table, name);
   1.108 -	p->flags = 0;
   1.109 -	p->version = hashtable_tokenize(&importer->table, version);
   1.110 -	p->arch = hashtable_tokenize(&importer->table, arch);
   1.111 -
   1.112 -	importer->package = p;
   1.113 -	array_init(&importer->properties);
   1.114 -}
   1.115 -
   1.116 -
   1.117 -void
   1.118 -razor_importer_finish_package(struct razor_importer *importer)
   1.119 -{
   1.120 -	list_set_array(&importer->package->properties,
   1.121 -		       &importer->set->property_pool,
   1.122 -		       &importer->properties,
   1.123 -		       1);
   1.124 -
   1.125 -	array_release(&importer->properties);
   1.126 -}
   1.127 -
   1.128 -void
   1.129 -razor_importer_add_property(struct razor_importer *importer,
   1.130 -			    const char *name,
   1.131 -			    uint32_t flags,
   1.132 -			    const char *version)
   1.133 -{
   1.134 -	struct razor_property *p;
   1.135 -	uint32_t *r;
   1.136 -
   1.137 -	p = array_add(&importer->set->properties, sizeof *p);
   1.138 -	p->name = hashtable_tokenize(&importer->table, name);
   1.139 -	p->flags = flags;
   1.140 -	p->version = hashtable_tokenize(&importer->table, version);
   1.141 -	list_set_ptr(&p->packages, importer->package -
   1.142 -		     (struct razor_package *) importer->set->packages.data);
   1.143 -
   1.144 -	r = array_add(&importer->properties, sizeof *r);
   1.145 -	*r = p - (struct razor_property *) importer->set->properties.data;
   1.146 -
   1.147 -	if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
   1.148 -	    *name == '/') {
   1.149 -		r = array_add(&importer->file_requires, sizeof *r);
   1.150 -		*r = p->name;
   1.151 -	}
   1.152 -}
   1.153 -
   1.154 -void
   1.155 -razor_importer_add_file(struct razor_importer *importer, const char *name)
   1.156 -{
   1.157 -	struct import_entry *e;
   1.158 -
   1.159 -	e = array_add(&importer->files, sizeof *e);
   1.160 -
   1.161 -	e->package = importer->package -
   1.162 -		(struct razor_package *) importer->set->packages.data;
   1.163 -	e->name = strdup(name);
   1.164 -}
   1.165 -
   1.166 -struct razor_importer *
   1.167 -razor_importer_new(void)
   1.168 -{
   1.169 -	struct razor_importer *importer;
   1.170 -
   1.171 -	importer = zalloc(sizeof *importer);
   1.172 -	importer->set = razor_set_create();
   1.173 -	hashtable_init(&importer->table, &importer->set->string_pool);
   1.174 -
   1.175 -	return importer;
   1.176 -}
   1.177 -
   1.178 -/* Destroy an importer without creating the set. */
   1.179 -void
   1.180 -razor_importer_destroy(struct razor_importer *importer)
   1.181 -{
   1.182 -	/* FIXME: write this */
   1.183 -}
   1.184 -
   1.185 -static int
   1.186 -versioncmp(const char *s1, const char *s2)
   1.187 +int
   1.188 +razor_versioncmp(const char *s1, const char *s2)
   1.189  {
   1.190  	const char *p1, *p2;
   1.191  	long n1, n2;
   1.192 @@ -414,489 +246,12 @@
   1.193  		p1++;
   1.194  		p2++;
   1.195  		if (isdigit(*p1) && isdigit(*p2))
   1.196 -			return versioncmp(p1, p2);
   1.197 +			return razor_versioncmp(p1, p2);
   1.198  	}
   1.199  
   1.200  	return *p1 - *p2;
   1.201  }
   1.202  
   1.203 -static int
   1.204 -compare_packages(const void *p1, const void *p2, void *data)
   1.205 -{
   1.206 -	const struct razor_package *pkg1 = p1, *pkg2 = p2;
   1.207 -	struct razor_set *set = data;
   1.208 -	char *pool = set->string_pool.data;
   1.209 -
   1.210 -	/* FIXME: what if the flags are different? */
   1.211 -	if (pkg1->name == pkg2->name)
   1.212 -		return versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
   1.213 -	else
   1.214 -		return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
   1.215 -}
   1.216 -
   1.217 -static int
   1.218 -compare_properties(const void *p1, const void *p2, void *data)
   1.219 -{
   1.220 -	const struct razor_property *prop1 = p1, *prop2 = p2;
   1.221 -	struct razor_set *set = data;
   1.222 -	char *pool = set->string_pool.data;
   1.223 -
   1.224 -	if (prop1->name != prop2->name)
   1.225 -		return strcmp(&pool[prop1->name], &pool[prop2->name]);
   1.226 -	else if (prop1->flags != prop2->flags)
   1.227 -		return prop1->flags - prop2->flags;
   1.228 -	else
   1.229 -		return versioncmp(&pool[prop1->version], &pool[prop2->version]);
   1.230 -}
   1.231 -
   1.232 -static uint32_t *
   1.233 -uniqueify_properties(struct razor_set *set)
   1.234 -{
   1.235 -	struct razor_property *rp, *up, *rp_end;
   1.236 -	struct array *pkgs, *p;
   1.237 -	struct list_head *r;
   1.238 -	uint32_t *map, *rmap;
   1.239 -	int i, count, unique;
   1.240 -
   1.241 -	count = set->properties.size / sizeof(struct razor_property);
   1.242 -	map = razor_qsort_with_data(set->properties.data,
   1.243 -				    count,
   1.244 -				    sizeof(struct razor_property),
   1.245 -				    compare_properties,
   1.246 -				    set);
   1.247 -
   1.248 -	rp_end = set->properties.data + set->properties.size;
   1.249 -	rmap = malloc(count * sizeof *map);
   1.250 -	pkgs = zalloc(count * sizeof *pkgs);
   1.251 -	for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
   1.252 -		if (rp->name != up->name ||
   1.253 -		    rp->flags != up->flags ||
   1.254 -		    rp->version != up->version) {
   1.255 -			up++;
   1.256 -			up->name = rp->name;
   1.257 -			up->flags = rp->flags;
   1.258 -			up->version = rp->version;
   1.259 -		}
   1.260 -
   1.261 -		unique = up - (struct razor_property *) set->properties.data;
   1.262 -		rmap[map[i]] = unique;
   1.263 -		r = array_add(&pkgs[unique], sizeof *r);
   1.264 -		*r = rp->packages;
   1.265 -	}
   1.266 -	free(map);
   1.267 -
   1.268 -	if (up != rp)
   1.269 -		up++;
   1.270 -	set->properties.size = (void *) up - set->properties.data;
   1.271 -	rp_end = up;
   1.272 -	for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
   1.273 -		list_set_array(&rp->packages, &set->package_pool, p, 0);
   1.274 -		array_release(p);
   1.275 -	}
   1.276 -
   1.277 -	free(pkgs);
   1.278 -
   1.279 -	return rmap;
   1.280 -}
   1.281 -
   1.282 -static int
   1.283 -compare_filenames(const void *p1, const void *p2, void *data)
   1.284 -{
   1.285 -	const struct import_entry *e1 = p1;
   1.286 -	const struct import_entry *e2 = p2;
   1.287 -	const char *n1 = e1->name;
   1.288 -	const char *n2 = e2->name;
   1.289 -
   1.290 -	/* Need to make sure that the contents of a directory
   1.291 -	 * are sorted immediately after it. So "foo/bar" has to
   1.292 -	 * sort before "foo.conf"
   1.293 -	 *
   1.294 -	 * FIXME: this is about 60% slower than strcmp
   1.295 -	 */
   1.296 -	while (*n1 && *n2) {
   1.297 -		if (*n1 < *n2)
   1.298 -			return *n2 == '/' ? 1 : -1;
   1.299 -		else if (*n1 > *n2)
   1.300 -			return *n1 == '/' ? -1 : 1;
   1.301 -		n1++;
   1.302 -		n2++;
   1.303 -	}
   1.304 -	if (*n1)
   1.305 -		return 1;
   1.306 -	else if (*n2)
   1.307 -		return -1;
   1.308 -	else
   1.309 -		return 0;
   1.310 -}
   1.311 -
   1.312 -static void
   1.313 -count_entries(struct import_directory *d)
   1.314 -{
   1.315 -	struct import_directory *p, *end;
   1.316 -
   1.317 -	p = d->files.data;
   1.318 -	end = d->files.data + d->files.size;
   1.319 -	d->count = 0;
   1.320 -	while (p < end) {
   1.321 -		count_entries(p);
   1.322 -		d->count += p->count + 1;
   1.323 -		p++;
   1.324 -	}
   1.325 -}
   1.326 -
   1.327 -static void
   1.328 -serialize_files(struct razor_set *set,
   1.329 -		struct import_directory *d, struct array *array)
   1.330 -{
   1.331 -	struct import_directory *p, *end;
   1.332 -	struct razor_entry *e = NULL;
   1.333 -	uint32_t s;
   1.334 -
   1.335 -	p = d->files.data;
   1.336 -	end = d->files.data + d->files.size;
   1.337 -	s = array->size / sizeof *e + d->files.size / sizeof *p;
   1.338 -	while (p < end) {
   1.339 -		e = array_add(array, sizeof *e);
   1.340 -		e->name = p->name;
   1.341 -		e->flags = 0;
   1.342 -		e->start = p->count > 0 ? s : 0;
   1.343 -		s += p->count;
   1.344 -
   1.345 -		list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
   1.346 -		array_release(&p->packages);
   1.347 -		p++;
   1.348 -	}
   1.349 -	if (e != NULL)
   1.350 -		e->flags |= RAZOR_ENTRY_LAST;
   1.351 -
   1.352 -	p = d->files.data;
   1.353 -	end = d->files.data + d->files.size;
   1.354 -	while (p < end) {
   1.355 -		serialize_files(set, p, array);
   1.356 -		p++;
   1.357 -	}
   1.358 -}
   1.359 -
   1.360 -static void
   1.361 -remap_property_package_links(struct array *properties, uint32_t *rmap)
   1.362 -{
   1.363 -	struct razor_property *p, *end;
   1.364 -
   1.365 -	end = properties->data + properties->size;
   1.366 -	for (p = properties->data; p < end; p++)
   1.367 -		list_remap_head(&p->packages, rmap);
   1.368 -}
   1.369 -
   1.370 -static void
   1.371 -build_file_tree(struct razor_importer *importer)
   1.372 -{
   1.373 -	int count, i, length;
   1.374 -	struct import_entry *filenames;
   1.375 -	char *f, *end;
   1.376 -	uint32_t name, *r;
   1.377 -	char dirname[256];
   1.378 -	struct import_directory *d, root;
   1.379 -	struct razor_entry *e;
   1.380 -
   1.381 -	count = importer->files.size / sizeof (struct import_entry);
   1.382 -	razor_qsort_with_data(importer->files.data,
   1.383 -			      count,
   1.384 -			      sizeof (struct import_entry),
   1.385 -			      compare_filenames,
   1.386 -			      NULL);
   1.387 -
   1.388 -	root.name = hashtable_tokenize(&importer->table, "");
   1.389 -	array_init(&root.files);
   1.390 -	array_init(&root.packages);
   1.391 -	root.last = NULL;
   1.392 -
   1.393 -	filenames = importer->files.data;
   1.394 -	for (i = 0; i < count; i++) {
   1.395 -		f = filenames[i].name;
   1.396 -		if (*f != '/')
   1.397 -			continue;
   1.398 -		f++;
   1.399 -
   1.400 -		d = &root;
   1.401 -		while (*f) {
   1.402 -			end = strchr(f, '/');
   1.403 -			if (end == NULL)
   1.404 -				end = f + strlen(f);
   1.405 -			length = end - f;
   1.406 -			memcpy(dirname, f, length);
   1.407 -			dirname[length] ='\0';
   1.408 -			name = hashtable_tokenize(&importer->table, dirname);
   1.409 -			if (d->last == NULL || d->last->name != name) {
   1.410 -				d->last = array_add(&d->files, sizeof *d);
   1.411 -				d->last->name = name;
   1.412 -				d->last->last = NULL;
   1.413 -				array_init(&d->last->files);
   1.414 -				array_init(&d->last->packages);
   1.415 -			}
   1.416 -			d = d->last;
   1.417 -			f = end + 1;
   1.418 -			if (*end == '\0')
   1.419 -				break;
   1.420 -		}
   1.421 -
   1.422 -		r = array_add(&d->packages, sizeof *r);
   1.423 -		*r = filenames[i].package;
   1.424 -		free(filenames[i].name);
   1.425 -	}
   1.426 -
   1.427 -	count_entries(&root);
   1.428 -	e = importer->set->files.data;
   1.429 -	e->name = root.name;
   1.430 -	e->flags = RAZOR_ENTRY_LAST;
   1.431 -	e->start = importer->files.size ? 1 : 0;
   1.432 -	list_set_empty(&e->packages);
   1.433 -
   1.434 -	serialize_files(importer->set, &root, &importer->set->files);
   1.435 -
   1.436 -	array_release(&importer->files);
   1.437 -}
   1.438 -
   1.439 -static struct razor_entry *
   1.440 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern);
   1.441 -
   1.442 -static void
   1.443 -list_to_array(struct list *list, struct array *array)
   1.444 -{
   1.445 -	uint32_t *item;
   1.446 -
   1.447 -	while (list) {
   1.448 -		 item = array_add(array, sizeof *item);
   1.449 -		 *item = list->data;
   1.450 -		 list = list_next(list);
   1.451 -	}
   1.452 -}
   1.453 -
   1.454 -static int
   1.455 -compare_file_requires(const void *p1, const void *p2, void *data)
   1.456 -{
   1.457 -	uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
   1.458 -	const char *pool = data;
   1.459 -
   1.460 -	return strcmp(&pool[*f1], &pool[*f2]);
   1.461 -}
   1.462 -
   1.463 -static void
   1.464 -find_file_provides(struct razor_importer *importer)
   1.465 -{
   1.466 -	struct razor_property *prop;
   1.467 -	struct razor_entry *top, *entry;
   1.468 -	struct razor_package *packages;
   1.469 -	struct array pkgprops;
   1.470 -	struct list *pkg;
   1.471 -	uint32_t *req, *req_start, *req_end;
   1.472 -	uint32_t *map, *newprop;
   1.473 -	char *pool;
   1.474 -
   1.475 -	pool = importer->set->string_pool.data;
   1.476 -	packages = importer->set->packages.data;
   1.477 -	top = importer->set->files.data;
   1.478 -
   1.479 -	req = req_start = importer->file_requires.data;
   1.480 -	req_end = importer->file_requires.data + importer->file_requires.size;
   1.481 -	map = razor_qsort_with_data(req, req_end - req, sizeof *req,
   1.482 -				    compare_file_requires, pool);
   1.483 -	free(map);
   1.484 -
   1.485 -	for (req = req_start; req < req_end; req++) {
   1.486 -		if (req > req_start && req[0] == req[-1])
   1.487 -			continue;
   1.488 -		entry = find_entry(importer->set, top, &pool[*req]);
   1.489 -		if (!entry)
   1.490 -			continue;
   1.491 -
   1.492 -		for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
   1.493 -			prop = array_add(&importer->set->properties, sizeof *prop);
   1.494 -			prop->name = *req;
   1.495 -			prop->flags =
   1.496 -				RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
   1.497 -			prop->version = hashtable_tokenize(&importer->table, "");
   1.498 -			list_set_ptr(&prop->packages, pkg->data);
   1.499 -
   1.500 -			/* Update property list of pkg */
   1.501 -			array_init(&pkgprops);
   1.502 -			list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
   1.503 -			newprop = array_add(&pkgprops, sizeof *newprop);
   1.504 -			*newprop = prop - (struct razor_property *)importer->set->properties.data;
   1.505 -			list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
   1.506 -			array_release(&pkgprops);
   1.507 -		}
   1.508 -	}
   1.509 -
   1.510 -	array_release(&importer->file_requires);
   1.511 -}
   1.512 -
   1.513 -static void
   1.514 -build_package_file_lists(struct razor_set *set, uint32_t *rmap)
   1.515 -{
   1.516 -	struct razor_package *p, *packages;
   1.517 -	struct array *pkgs;
   1.518 -	struct razor_entry *e, *end;
   1.519 -	struct list *r;
   1.520 -	uint32_t *q;
   1.521 -	int i, count;
   1.522 -
   1.523 -	count = set->packages.size / sizeof *p;
   1.524 -	pkgs = zalloc(count * sizeof *pkgs);
   1.525 -
   1.526 -	end = set->files.data + set->files.size;
   1.527 -	for (e = set->files.data; e < end; e++) {
   1.528 -		list_remap_head(&e->packages, rmap);
   1.529 -		r = list_first(&e->packages, &set->package_pool);
   1.530 -		while (r) {
   1.531 -			q = array_add(&pkgs[r->data], sizeof *q);
   1.532 -			*q = e - (struct razor_entry *) set->files.data;
   1.533 -			r = list_next(r);
   1.534 -		}
   1.535 -	}
   1.536 -
   1.537 -	packages = set->packages.data;
   1.538 -	for (i = 0; i < count; i++) {
   1.539 -		list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
   1.540 -		array_release(&pkgs[i]);
   1.541 -	}
   1.542 -	free(pkgs);
   1.543 -}
   1.544 -
   1.545 -struct razor_set *
   1.546 -razor_importer_finish(struct razor_importer *importer)
   1.547 -{
   1.548 -	struct razor_set *set;
   1.549 -	uint32_t *map, *rmap;
   1.550 -	int i, count;
   1.551 -
   1.552 -	build_file_tree(importer);
   1.553 -	find_file_provides(importer);
   1.554 -
   1.555 -	map = uniqueify_properties(importer->set);
   1.556 -	list_remap_pool(&importer->set->property_pool, map);
   1.557 -	free(map);
   1.558 -
   1.559 -	count = importer->set->packages.size / sizeof(struct razor_package);
   1.560 -	map = razor_qsort_with_data(importer->set->packages.data,
   1.561 -				    count,
   1.562 -				    sizeof(struct razor_package),
   1.563 -				    compare_packages,
   1.564 -				    importer->set);
   1.565 -
   1.566 -	rmap = malloc(count * sizeof *rmap);
   1.567 -	for (i = 0; i < count; i++)
   1.568 -		rmap[map[i]] = i;
   1.569 -	free(map);
   1.570 -
   1.571 -	list_remap_pool(&importer->set->package_pool, rmap);
   1.572 -	build_package_file_lists(importer->set, rmap);
   1.573 -	remap_property_package_links(&importer->set->properties, rmap);
   1.574 -	free(rmap);
   1.575 -
   1.576 -	set = importer->set;
   1.577 -	hashtable_release(&importer->table);
   1.578 -	free(importer);
   1.579 -
   1.580 -	return set;
   1.581 -}
   1.582 -
   1.583 -struct razor_package_iterator {
   1.584 -	struct razor_set *set;
   1.585 -	struct razor_package *package, *end;
   1.586 -	struct list *index;
   1.587 -	int free_index;
   1.588 -};
   1.589 -
   1.590 -static struct razor_package_iterator *
   1.591 -razor_package_iterator_create_with_index(struct razor_set *set,
   1.592 -					 struct list *index)
   1.593 -{
   1.594 -	struct razor_package_iterator *pi;
   1.595 -
   1.596 -	pi = zalloc(sizeof *pi);
   1.597 -	pi->set = set;
   1.598 -	pi->index = index;
   1.599 -
   1.600 -	return pi;
   1.601 -}
   1.602 -
   1.603 -struct razor_package_iterator *
   1.604 -razor_package_iterator_create(struct razor_set *set)
   1.605 -{
   1.606 -	struct razor_package_iterator *pi;
   1.607 -
   1.608 -	pi = zalloc(sizeof *pi);
   1.609 -	pi->set = set;
   1.610 -	pi->end = set->packages.data + set->packages.size;
   1.611 -	pi->package = set->packages.data;
   1.612 -
   1.613 -	return pi;
   1.614 -}
   1.615 -
   1.616 -static void
   1.617 -razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
   1.618 -					 struct razor_set *set,
   1.619 -					 struct razor_property *property)
   1.620 -{
   1.621 -	memset(pi, 0, sizeof *pi);
   1.622 -	pi->set = set;
   1.623 -	pi->index = list_first(&property->packages, &set->package_pool);
   1.624 -}
   1.625 -
   1.626 -struct razor_package_iterator *
   1.627 -razor_package_iterator_create_for_property(struct razor_set *set,
   1.628 -					   struct razor_property *property)
   1.629 -{
   1.630 -	struct list *index;
   1.631 -
   1.632 -	index = list_first(&property->packages, &set->package_pool);
   1.633 -	return razor_package_iterator_create_with_index(set, index);
   1.634 -}
   1.635 -
   1.636 -int
   1.637 -razor_package_iterator_next(struct razor_package_iterator *pi,
   1.638 -			    struct razor_package **package,
   1.639 -			    const char **name,
   1.640 -			    const char **version,
   1.641 -			    const char **arch)
   1.642 -{
   1.643 -	char *pool;
   1.644 -	int valid;
   1.645 -	struct razor_package *p, *packages;
   1.646 -
   1.647 -	if (pi->package) {
   1.648 -		p = pi->package++;
   1.649 -		valid = p < pi->end;
   1.650 -	} else if (pi->index) {
   1.651 -		packages = pi->set->packages.data;
   1.652 -		p = &packages[pi->index->data];
   1.653 -		pi->index = list_next(pi->index);
   1.654 -		valid = 1;
   1.655 -	} else
   1.656 -		valid = 0;
   1.657 -
   1.658 -	if (valid) {
   1.659 -		pool = pi->set->string_pool.data;
   1.660 -		*package = p;
   1.661 -		*name = &pool[p->name];
   1.662 -		*version = &pool[p->version];
   1.663 -		*arch = &pool[p->arch];
   1.664 -	} else {
   1.665 -		*package = NULL;
   1.666 -	}
   1.667 -
   1.668 -	return valid;
   1.669 -}
   1.670 -
   1.671 -void
   1.672 -razor_package_iterator_destroy(struct razor_package_iterator *pi)
   1.673 -{
   1.674 -	if (pi->free_index)
   1.675 -		free(pi->index);
   1.676 -
   1.677 -	free(pi);
   1.678 -}
   1.679 -
   1.680  struct razor_package *
   1.681  razor_set_get_package(struct razor_set *set, const char *package)
   1.682  {
   1.683 @@ -914,75 +269,9 @@
   1.684  	return p;
   1.685  }
   1.686  
   1.687 -struct razor_property_iterator {
   1.688 -	struct razor_set *set;
   1.689 -	struct razor_property *property, *end;
   1.690 -	struct list *index;
   1.691 -};
   1.692 -
   1.693 -struct razor_property_iterator *
   1.694 -razor_property_iterator_create(struct razor_set *set,
   1.695 -			       struct razor_package *package)
   1.696 -{
   1.697 -	struct razor_property_iterator *pi;
   1.698 -
   1.699 -	pi = zalloc(sizeof *pi);
   1.700 -	pi->set = set;
   1.701 -
   1.702 -	if (package) {
   1.703 -		pi->index = list_first(&package->properties,
   1.704 -				       &set->property_pool);
   1.705 -	} else {
   1.706 -		pi->property = set->properties.data;
   1.707 -		pi->end = set->properties.data + set->properties.size;
   1.708 -	}
   1.709 -
   1.710 -	return pi;
   1.711 -}
   1.712 -
   1.713 -int
   1.714 -razor_property_iterator_next(struct razor_property_iterator *pi,
   1.715 -			     struct razor_property **property,
   1.716 -			     const char **name,
   1.717 -			     uint32_t *flags,
   1.718 -			     const char **version)
   1.719 -{
   1.720 -	char *pool;
   1.721 -	int valid;
   1.722 -	struct razor_property *p, *properties;
   1.723 -
   1.724 -	if (pi->property) {
   1.725 -		p = pi->property++;
   1.726 -		valid = p < pi->end;
   1.727 -	} else if (pi->index) {
   1.728 -		properties = pi->set->properties.data;
   1.729 -		p = &properties[pi->index->data];
   1.730 -		pi->index = list_next(pi->index);
   1.731 -		valid = 1;
   1.732 -	} else
   1.733 -		valid = 0;
   1.734 -
   1.735 -	if (valid) {
   1.736 -		pool = pi->set->string_pool.data;
   1.737 -		*property = p;
   1.738 -		*name = &pool[p->name];
   1.739 -		*flags = p->flags;
   1.740 -		*version = &pool[p->version];
   1.741 -	} else {
   1.742 -		*property = NULL;
   1.743 -	}
   1.744 -
   1.745 -	return valid;
   1.746 -}
   1.747 -
   1.748 -void
   1.749 -razor_property_iterator_destroy(struct razor_property_iterator *pi)
   1.750 -{
   1.751 -	free(pi);
   1.752 -}
   1.753 -
   1.754 -static struct razor_entry *
   1.755 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
   1.756 +struct razor_entry *
   1.757 +razor_set_find_entry(struct razor_set *set,
   1.758 +		     struct razor_entry *dir, const char *pattern)
   1.759  {
   1.760  	struct razor_entry *e;
   1.761  	const char *n, *pool = set->string_pool.data;
   1.762 @@ -996,7 +285,7 @@
   1.763  		len = strlen(n);
   1.764  		if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
   1.765  		    pattern[len + 1] == '/') {
   1.766 -			return find_entry(set, e, pattern + len + 1);
   1.767 +			return razor_set_find_entry(set, e, pattern + len + 1);
   1.768  		}
   1.769  	} while (!((e++)->flags & RAZOR_ENTRY_LAST));
   1.770  
   1.771 @@ -1039,7 +328,7 @@
   1.772  	}
   1.773  
   1.774  	strcpy(buffer, pattern);
   1.775 -	e = find_entry(set, set->files.data, buffer);
   1.776 +	e = razor_set_find_entry(set, set->files.data, buffer);
   1.777  	if (e && e->start > 0) {
   1.778  		base = NULL;
   1.779  	} else {
   1.780 @@ -1051,26 +340,11 @@
   1.781  			base = NULL;
   1.782  		}
   1.783  	}
   1.784 -	e = find_entry(set, set->files.data, buffer);
   1.785 +	e = razor_set_find_entry(set, set->files.data, buffer);
   1.786  	if (e->start != 0)
   1.787  		list_dir(set, e, buffer, base);
   1.788  }
   1.789  
   1.790 -struct razor_package_iterator *
   1.791 -razor_package_iterator_create_for_file(struct razor_set *set,
   1.792 -				       const char *filename)
   1.793 -{
   1.794 -	struct razor_entry *entry;
   1.795 -	struct list *index;
   1.796 -
   1.797 -	entry = find_entry(set, set->files.data, filename);
   1.798 -	if (entry == NULL)
   1.799 -		return NULL;
   1.800 -
   1.801 -	index = list_first(&entry->packages, &set->package_pool);
   1.802 -	return razor_package_iterator_create_with_index(set, index);
   1.803 -}
   1.804 -
   1.805  static struct list *
   1.806  list_package_files(struct razor_set *set, struct list *r,
   1.807  		   struct razor_entry *dir, uint32_t end,
   1.808 @@ -1142,509 +416,6 @@
   1.809  	list_package_files(set, r, set->files.data, end, buffer);
   1.810  }
   1.811  
   1.812 -#define UPSTREAM_SOURCE 0x80
   1.813 -
   1.814 -struct source {
   1.815 -	struct razor_set *set;
   1.816 -	uint32_t *property_map;
   1.817 -	uint32_t *file_map;
   1.818 -};
   1.819 -
   1.820 -struct razor_merger {
   1.821 -	struct razor_set *set;
   1.822 -	struct hashtable table;
   1.823 -	struct source source1;
   1.824 -	struct source source2;
   1.825 -};
   1.826 -
   1.827 -static struct razor_merger *
   1.828 -razor_merger_create(struct razor_set *set1, struct razor_set *set2)
   1.829 -{
   1.830 -	struct razor_merger *merger;
   1.831 -	int count;
   1.832 -	size_t size;
   1.833 -
   1.834 -	merger = zalloc(sizeof *merger);
   1.835 -	merger->set = razor_set_create();
   1.836 -	hashtable_init(&merger->table, &merger->set->string_pool);
   1.837 -
   1.838 -	merger->source1.set = set1;
   1.839 -	count = set1->properties.size / sizeof (struct razor_property);
   1.840 -	size = count * sizeof merger->source1.property_map[0];
   1.841 -	merger->source1.property_map = zalloc(size);
   1.842 -	count = set1->files.size / sizeof (struct razor_entry);
   1.843 -	size = count * sizeof merger->source1.file_map[0];
   1.844 -	merger->source1.file_map = zalloc(size);
   1.845 -
   1.846 -	merger->source2.set = set2;
   1.847 -	count = set2->properties.size / sizeof (struct razor_property);
   1.848 -	size = count * sizeof merger->source2.property_map[0];
   1.849 -	merger->source2.property_map = zalloc(size);
   1.850 -	count = set2->files.size / sizeof (struct razor_entry);
   1.851 -	size = count * sizeof merger->source2.file_map[0];
   1.852 -	merger->source2.file_map = zalloc(size);
   1.853 -
   1.854 -	return merger;
   1.855 -}
   1.856 -
   1.857 -static void
   1.858 -razor_merger_add_package(struct razor_merger *merger,
   1.859 -			 struct razor_package *package)
   1.860 -{
   1.861 -	char *pool;
   1.862 -	struct list *r;
   1.863 -	struct razor_package *p;
   1.864 -	struct razor_set *set1;
   1.865 -	struct source *source;
   1.866 -	uint32_t flags;
   1.867 -
   1.868 -	set1 = merger->source1.set;
   1.869 -	if (set1->packages.data <= (void *) package &&
   1.870 -	    (void *) package < set1->packages.data + set1->packages.size) {
   1.871 -		source = &merger->source1;
   1.872 -		flags = 0;
   1.873 -	} else {
   1.874 -		source = &merger->source2;
   1.875 -		flags = UPSTREAM_SOURCE;
   1.876 -	}
   1.877 -
   1.878 -	pool = source->set->string_pool.data;
   1.879 -	p = array_add(&merger->set->packages, sizeof *p);
   1.880 -	p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
   1.881 -	p->flags = flags;
   1.882 -	p->version = hashtable_tokenize(&merger->table,
   1.883 -					&pool[package->version]);
   1.884 -	p->arch = hashtable_tokenize(&merger->table,
   1.885 -				     &pool[package->arch]);
   1.886 -
   1.887 -	p->properties = package->properties;
   1.888 -	r = list_first(&package->properties, &source->set->property_pool);
   1.889 -	while (r) {
   1.890 -		source->property_map[r->data] = 1;
   1.891 -		r = list_next(r);
   1.892 -	}
   1.893 -
   1.894 -	p->files = package->files;
   1.895 -	r = list_first(&package->files, &source->set->file_pool);
   1.896 -	while (r) {
   1.897 -		source->file_map[r->data] = 1;
   1.898 -		r = list_next(r);
   1.899 -	}
   1.900 -}
   1.901 -
   1.902 -static uint32_t
   1.903 -add_property(struct razor_merger *merger,
   1.904 -	     const char *name, uint32_t flags, const char *version)
   1.905 -{
   1.906 -	struct razor_property *p;
   1.907 -
   1.908 -	p = array_add(&merger->set->properties, sizeof *p);
   1.909 -	p->name = hashtable_tokenize(&merger->table, name);
   1.910 -	p->flags = flags;
   1.911 -	p->version = hashtable_tokenize(&merger->table, version);
   1.912 -
   1.913 -	return p - (struct razor_property *) merger->set->properties.data;
   1.914 -}
   1.915 -
   1.916 -static void
   1.917 -merge_properties(struct razor_merger *merger)
   1.918 -{
   1.919 -	struct razor_property *p1, *p2;
   1.920 -	struct razor_set *set1, *set2;
   1.921 -	uint32_t *map1, *map2;
   1.922 -	int i, j, cmp, count1, count2;
   1.923 -	char *pool1, *pool2;
   1.924 -
   1.925 -	set1 = merger->source1.set;
   1.926 -	set2 = merger->source2.set;
   1.927 -	map1 = merger->source1.property_map;
   1.928 -	map2 = merger->source2.property_map;
   1.929 -
   1.930 -	i = 0;
   1.931 -	j = 0;
   1.932 -	pool1 = set1->string_pool.data;
   1.933 -	pool2 = set2->string_pool.data;
   1.934 -
   1.935 -	count1 = set1->properties.size / sizeof *p1;
   1.936 -	count2 = set2->properties.size / sizeof *p2;
   1.937 -	while (i < count1 || j < count2) {
   1.938 -		if (i < count1 && map1[i] == 0) {
   1.939 -			i++;
   1.940 -			continue;
   1.941 -		}
   1.942 -		if (j < count2 && map2[j] == 0) {
   1.943 -			j++;
   1.944 -			continue;
   1.945 -		}
   1.946 -		p1 = (struct razor_property *) set1->properties.data + i;
   1.947 -		p2 = (struct razor_property *) set2->properties.data + j;
   1.948 -		if (i < count1 && j < count2)
   1.949 -			cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
   1.950 -		else if (i < count1)
   1.951 -			cmp = -1;
   1.952 -		else
   1.953 -			cmp = 1;
   1.954 -		if (cmp == 0)
   1.955 -			cmp = p1->flags - p2->flags;
   1.956 -		if (cmp == 0)
   1.957 -			cmp = versioncmp(&pool1[p1->version],
   1.958 -					 &pool2[p2->version]);
   1.959 -		if (cmp < 0) {
   1.960 -			map1[i++] = add_property(merger,
   1.961 -						 &pool1[p1->name],
   1.962 -						 p1->flags,
   1.963 -						 &pool1[p1->version]);
   1.964 -		} else if (cmp > 0) {
   1.965 -			map2[j++] = add_property(merger,
   1.966 -						 &pool2[p2->name],
   1.967 -						 p2->flags,
   1.968 -						 &pool2[p2->version]);
   1.969 -		} else  {
   1.970 -			map1[i++] = map2[j++] =
   1.971 -				add_property(merger,
   1.972 -					     &pool1[p1->name],
   1.973 -					     p1->flags,
   1.974 -					     &pool1[p1->version]);
   1.975 -		}
   1.976 -	}
   1.977 -}
   1.978 -
   1.979 -static void
   1.980 -emit_properties(struct list_head *properties, struct array *source_pool,
   1.981 -		uint32_t *map, struct array *pool)
   1.982 -{
   1.983 -	uint32_t r;
   1.984 -	struct list *p, *q;
   1.985 -
   1.986 -	r = pool->size / sizeof *q;
   1.987 -	p = list_first(properties, source_pool);
   1.988 -	while (p) {
   1.989 -		q = array_add(pool, sizeof *q);
   1.990 -		q->data = map[p->data];
   1.991 -		q->flags = p->flags;
   1.992 -		p = list_next(p);
   1.993 -	}
   1.994 -
   1.995 -	list_set_ptr(properties, r);
   1.996 -}
   1.997 -
   1.998 -static uint32_t
   1.999 -add_file(struct razor_merger *merger, const char *name)
  1.1000 -{
  1.1001 -	struct razor_entry *e;
  1.1002 -
  1.1003 -	e = array_add(&merger->set->files, sizeof *e);
  1.1004 -	e->name = hashtable_tokenize(&merger->table, name);
  1.1005 -	e->flags = 0;
  1.1006 -	e->start = 0;
  1.1007 -
  1.1008 -	return e - (struct razor_entry *)merger->set->files.data;
  1.1009 -}
  1.1010 -
  1.1011 -/* FIXME. Blah */
  1.1012 -static int
  1.1013 -fix_file_map(uint32_t *map,
  1.1014 -	     struct razor_entry *files,
  1.1015 -	     struct razor_entry *top)
  1.1016 -{
  1.1017 -	uint32_t e;
  1.1018 -	int found_file = 0;
  1.1019 -
  1.1020 -	e = top->start;
  1.1021 -	do {
  1.1022 -		if (files[e].start)
  1.1023 -			fix_file_map(map, files, &files[e]);
  1.1024 -		if (map[e])
  1.1025 -			found_file = 1;
  1.1026 -	} while (!(files[e++].flags & RAZOR_ENTRY_LAST));
  1.1027 -
  1.1028 -	if (found_file)
  1.1029 -		map[top - files] = 1;
  1.1030 -	return found_file;
  1.1031 -}
  1.1032 -
  1.1033 -struct merge_directory {
  1.1034 -	uint32_t merged, dir1, dir2;
  1.1035 -};
  1.1036 -
  1.1037 -static void
  1.1038 -merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
  1.1039 -{
  1.1040 -	struct razor_entry *root1, *root2, *mroot, *e1, *e2;
  1.1041 -	struct razor_set *set1, *set2;
  1.1042 -	struct array merge_stack;
  1.1043 -	struct merge_directory *child_md, *end_md;
  1.1044 -	uint32_t *map1, *map2, start, last;
  1.1045 -	int cmp;
  1.1046 -	char *pool1, *pool2;
  1.1047 -
  1.1048 -	set1 = merger->source1.set;
  1.1049 -	set2 = merger->source2.set;
  1.1050 -	map1 = merger->source1.file_map;
  1.1051 -	map2 = merger->source2.file_map;
  1.1052 -	pool1 = set1->string_pool.data;
  1.1053 -	pool2 = set2->string_pool.data;
  1.1054 -	root1 = (struct razor_entry *) set1->files.data;
  1.1055 -	root2 = (struct razor_entry *) set2->files.data;
  1.1056 -
  1.1057 -	array_init(&merge_stack);
  1.1058 -
  1.1059 -	start = merger->set->files.size / sizeof (struct razor_entry);
  1.1060 -	last = 0;
  1.1061 -	e1 = md->dir1 ? root1 + md->dir1 : NULL;
  1.1062 -	e2 = md->dir2 ? root2 + md->dir2 : NULL;
  1.1063 -	while (e1 || e2) {
  1.1064 -		if (!e2 && !map1[e1 - root1]) {
  1.1065 -			if ((e1++)->flags & RAZOR_ENTRY_LAST)
  1.1066 -				e1 = NULL;
  1.1067 -			continue;
  1.1068 -		}
  1.1069 -		if (!e1 && !map2[e2 - root2]) {
  1.1070 -			if ((e2++)->flags & RAZOR_ENTRY_LAST)
  1.1071 -				e2 = NULL;
  1.1072 -			continue;
  1.1073 -		}
  1.1074 -		if (e1 && !map1[e1 - root1] &&
  1.1075 -		    e2 && !map1[e2 - root2]) {
  1.1076 -			if ((e1++)->flags & RAZOR_ENTRY_LAST)
  1.1077 -				e1 = NULL;
  1.1078 -			if ((e2++)->flags & RAZOR_ENTRY_LAST)
  1.1079 -				e2 = NULL;
  1.1080 -			continue;
  1.1081 -		}
  1.1082 -
  1.1083 -		if (!e1)
  1.1084 -			cmp = 1;
  1.1085 -		else if (!e2)
  1.1086 -			cmp = -1;
  1.1087 -		else {
  1.1088 -			cmp = strcmp (&pool1[e1->name],
  1.1089 -				      &pool2[e2->name]);
  1.1090 -		}
  1.1091 -
  1.1092 -		if (cmp < 0) {
  1.1093 -			if (map1[e1 - root1]) {
  1.1094 -				map1[e1 - root1] = last =
  1.1095 -					add_file(merger, &pool1[e1->name]);
  1.1096 -				if (e1->start) {
  1.1097 -					child_md = array_add(&merge_stack, sizeof (struct merge_directory));
  1.1098 -					child_md->merged = last;
  1.1099 -					child_md->dir1 = e1->start;
  1.1100 -					child_md->dir2 = 0;
  1.1101 -				}
  1.1102 -			}
  1.1103 -			if ((e1++)->flags & RAZOR_ENTRY_LAST)
  1.1104 -				e1 = NULL;
  1.1105 -		} else if (cmp > 0) {
  1.1106 -			if (map2[e2 - root2]) {
  1.1107 -				map2[e2 - root2] = last =
  1.1108 -					add_file(merger, &pool2[e2->name]);
  1.1109 -				if (e2->start) {
  1.1110 -					child_md = array_add(&merge_stack, sizeof (struct merge_directory));
  1.1111 -					child_md->merged = last;
  1.1112 -					child_md->dir1 = 0;
  1.1113 -					child_md->dir2 = e2->start;
  1.1114 -				}
  1.1115 -			}
  1.1116 -			if ((e2++)->flags & RAZOR_ENTRY_LAST)
  1.1117 -				e2 = NULL;
  1.1118 -		} else {
  1.1119 -			map1[e1 - root1] = map2[e2- root2] = last =
  1.1120 -				add_file(merger, &pool1[e1->name]);
  1.1121 -			if (e1->start || e2->start) {
  1.1122 -				child_md = array_add(&merge_stack, sizeof (struct merge_directory));
  1.1123 -				child_md->merged = last;
  1.1124 -				child_md->dir1 = e1->start;
  1.1125 -				child_md->dir2 = e2->start;
  1.1126 -			}
  1.1127 -			if ((e1++)->flags & RAZOR_ENTRY_LAST)
  1.1128 -				e1 = NULL;
  1.1129 -			if ((e2++)->flags & RAZOR_ENTRY_LAST)
  1.1130 -				e2 = NULL;
  1.1131 -		}
  1.1132 -	}
  1.1133 -
  1.1134 -	mroot = (struct razor_entry *)merger->set->files.data;
  1.1135 -	if (last) {
  1.1136 -		mroot[last].flags = RAZOR_ENTRY_LAST;
  1.1137 -		mroot[md->merged].start = start;
  1.1138 -	} else
  1.1139 -		mroot[md->merged].start = 0;
  1.1140 -
  1.1141 -	end_md = merge_stack.data + merge_stack.size;
  1.1142 -	for (child_md = merge_stack.data; child_md < end_md; child_md++)
  1.1143 -		merge_one_directory(merger, child_md);
  1.1144 -	array_release(&merge_stack);
  1.1145 -}
  1.1146 -
  1.1147 -static void
  1.1148 -merge_files(struct razor_merger *merger)
  1.1149 -{
  1.1150 -	struct razor_entry *root;
  1.1151 -	struct merge_directory md;
  1.1152 -	uint32_t *map1, *map2;
  1.1153 -
  1.1154 -	map1 = merger->source1.file_map;
  1.1155 -	map2 = merger->source2.file_map;
  1.1156 -
  1.1157 -	md.merged = 0;
  1.1158 -
  1.1159 -	if (merger->source1.set->files.size) {
  1.1160 -		root = (struct razor_entry *) merger->source1.set->files.data;
  1.1161 -		if (root->start)
  1.1162 -			fix_file_map(map1, root, root);
  1.1163 -		md.dir1 = root->start;
  1.1164 -	} else
  1.1165 -		md.dir1 = 0;
  1.1166 -
  1.1167 -	if (merger->source2.set->files.size) {
  1.1168 -		root = (struct razor_entry *) merger->source2.set->files.data;
  1.1169 -		if (root->start)
  1.1170 -			fix_file_map(map2, root, root);
  1.1171 -		md.dir2 = root->start;
  1.1172 -	} else
  1.1173 -		md.dir2 = 0;
  1.1174 -
  1.1175 -	merge_one_directory(merger, &md);
  1.1176 -}
  1.1177 -
  1.1178 -static void
  1.1179 -emit_files(struct list_head *files, struct array *source_pool,
  1.1180 -	   uint32_t *map, struct array *pool)
  1.1181 -{
  1.1182 -	uint32_t r;
  1.1183 -	struct list *p, *q;
  1.1184 -
  1.1185 -	r = pool->size / sizeof *q;
  1.1186 -	p = list_first(files, source_pool);
  1.1187 -	while (p) {
  1.1188 -		q = array_add(pool, sizeof *q);
  1.1189 -		q->data = map[p->data];
  1.1190 -		q->flags = p->flags;
  1.1191 -		p = list_next(p);
  1.1192 -	}
  1.1193 -
  1.1194 -	list_set_ptr(files, r);
  1.1195 -}
  1.1196 -
  1.1197 -/* Rebuild property->packages maps.  We can't just remap these, as a
  1.1198 - * property may have lost or gained a number of packages.  Allocate an
  1.1199 - * array per property and loop through the packages and add them to
  1.1200 - * the arrays for their properties. */
  1.1201 -static void
  1.1202 -rebuild_property_package_lists(struct razor_set *set)
  1.1203 -{
  1.1204 -	struct array *pkgs, *a;
  1.1205 -	struct razor_package *pkg, *pkg_end;
  1.1206 -	struct razor_property *prop, *prop_end;
  1.1207 -	struct list *r;
  1.1208 -	uint32_t *q;
  1.1209 -	int count;
  1.1210 -
  1.1211 -	count = set->properties.size / sizeof (struct razor_property);
  1.1212 -	pkgs = zalloc(count * sizeof *pkgs);
  1.1213 -	pkg_end = set->packages.data + set->packages.size;
  1.1214 -
  1.1215 -	for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
  1.1216 -		r = list_first(&pkg->properties, &set->property_pool);
  1.1217 -		while (r) {
  1.1218 -			q = array_add(&pkgs[r->data], sizeof *q);
  1.1219 -			*q = pkg - (struct razor_package *) set->packages.data;
  1.1220 -			r = list_next(r);
  1.1221 -		}
  1.1222 -	}
  1.1223 -
  1.1224 -	prop_end = set->properties.data + set->properties.size;
  1.1225 -	a = pkgs;
  1.1226 -	for (prop = set->properties.data; prop < prop_end; prop++, a++) {
  1.1227 -		list_set_array(&prop->packages, &set->package_pool, a, 0);
  1.1228 -		array_release(a);
  1.1229 -	}
  1.1230 -	free(pkgs);
  1.1231 -}
  1.1232 -
  1.1233 -static void
  1.1234 -rebuild_file_package_lists(struct razor_set *set)
  1.1235 -{
  1.1236 -	struct array *pkgs, *a;
  1.1237 -	struct razor_package *pkg, *pkg_end;
  1.1238 -	struct razor_entry *entry, *entry_end;
  1.1239 -	struct list *r;
  1.1240 -	uint32_t *q;
  1.1241 -	int count;
  1.1242 -
  1.1243 -	count = set->files.size / sizeof (struct razor_entry);
  1.1244 -	pkgs = zalloc(count * sizeof *pkgs);
  1.1245 -	pkg_end = set->packages.data + set->packages.size;
  1.1246 -
  1.1247 -	for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
  1.1248 -		r = list_first(&pkg->files, &set->file_pool);
  1.1249 -		while (r) {
  1.1250 -			q = array_add(&pkgs[r->data], sizeof *q);
  1.1251 -			*q = pkg - (struct razor_package *) set->packages.data;
  1.1252 -			r = list_next(r);
  1.1253 -		}
  1.1254 -	}
  1.1255 -
  1.1256 -	entry_end = set->files.data + set->files.size;
  1.1257 -	a = pkgs;
  1.1258 -	for (entry = set->files.data; entry < entry_end; entry++, a++) {
  1.1259 -		list_set_array(&entry->packages, &set->package_pool, a, 0);
  1.1260 -		array_release(a);
  1.1261 -	}
  1.1262 -	free(pkgs);
  1.1263 -}
  1.1264 -
  1.1265 -static struct razor_set *
  1.1266 -razor_merger_finish(struct razor_merger *merger)
  1.1267 -{
  1.1268 -	struct razor_set *result;
  1.1269 -	struct razor_package *p, *pend;
  1.1270 -
  1.1271 -	/* As we built the package list, we filled out a bitvector of
  1.1272 -	 * the properties that are referenced by the packages in the
  1.1273 -	 * new set.  Now we do a parallel loop through the properties
  1.1274 -	 * and emit those marked in the bit vector to the new set.  In
  1.1275 -	 * the process, we update the bit vector to actually map from
  1.1276 -	 * indices in the old property list to indices in the new
  1.1277 -	 * property list for both sets. */
  1.1278 -
  1.1279 -	merge_properties(merger);
  1.1280 -	merge_files(merger);
  1.1281 -
  1.1282 -	/* Now we loop through the packages again and emit the
  1.1283 -	 * property lists, remapped to point to the new properties. */
  1.1284 -
  1.1285 -	pend = merger->set->packages.data + merger->set->packages.size;
  1.1286 -	for (p = merger->set->packages.data; p < pend; p++) {
  1.1287 -		struct source *src;
  1.1288 -
  1.1289 -		if (p->flags & UPSTREAM_SOURCE)
  1.1290 -			src = &merger->source2;
  1.1291 -		else
  1.1292 -			src = &merger->source1;
  1.1293 -
  1.1294 -		emit_properties(&p->properties,
  1.1295 -				&src->set->property_pool,
  1.1296 -				src->property_map,
  1.1297 -				&merger->set->property_pool);
  1.1298 -		emit_files(&p->files,
  1.1299 -			   &src->set->file_pool,
  1.1300 -			   src->file_map,
  1.1301 -			   &merger->set->file_pool);
  1.1302 -		p->flags &= ~UPSTREAM_SOURCE;
  1.1303 -	}
  1.1304 -
  1.1305 -	rebuild_property_package_lists(merger->set);
  1.1306 -	rebuild_file_package_lists(merger->set);
  1.1307 -
  1.1308 -	result = merger->set;
  1.1309 -	hashtable_release(&merger->table);
  1.1310 -	free(merger);
  1.1311 -
  1.1312 -	return result;
  1.1313 -}
  1.1314 -
  1.1315  /* The diff order matters.  We should sort the packages so that a
  1.1316   * REMOVE of a package comes before the INSTALL, and so that all
  1.1317   * requires for a package have been installed before the package.
  1.1318 @@ -1669,7 +440,7 @@
  1.1319  		if (p1 && p2) {
  1.1320  			res = strcmp(name1, name2);
  1.1321  			if (res == 0)
  1.1322 -				res = versioncmp(version1, version2);
  1.1323 +				res = razor_versioncmp(version1, version2);
  1.1324  		} else {
  1.1325  			res = 0;
  1.1326  		}
  1.1327 @@ -1690,953 +461,3 @@
  1.1328  	razor_package_iterator_destroy(pi1);
  1.1329  	razor_package_iterator_destroy(pi2);
  1.1330  }
  1.1331 -
  1.1332 -static int
  1.1333 -provider_satisfies_requirement(struct razor_property *provider,
  1.1334 -			       const char *provider_strings,
  1.1335 -			       uint32_t flags,
  1.1336 -			       const char *required)
  1.1337 -{
  1.1338 -	int cmp, len;
  1.1339 -	const char *provided = &provider_strings[provider->version];
  1.1340 -
  1.1341 -	if (!*required)
  1.1342 -		return 1;
  1.1343 -	if (!*provided) {
  1.1344 -		if (flags & RAZOR_PROPERTY_LESS)
  1.1345 -			return 0;
  1.1346 -		else
  1.1347 -			return 1;
  1.1348 -	}
  1.1349 -
  1.1350 -	cmp = versioncmp(provided, required);
  1.1351 -
  1.1352 -	switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
  1.1353 -	case RAZOR_PROPERTY_LESS:
  1.1354 -		return cmp < 0;
  1.1355 -
  1.1356 -	case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
  1.1357 -		if (cmp <= 0)
  1.1358 -			return 1;
  1.1359 -		/* fall through: FIXME, make sure this is correct */
  1.1360 -
  1.1361 -	case RAZOR_PROPERTY_EQUAL:
  1.1362 -		if (cmp == 0)
  1.1363 -			return 1;
  1.1364 -
  1.1365 -		/* "foo == 1.1" is satisfied by "foo 1.1-2" */
  1.1366 -		len = strlen(required);
  1.1367 -		if (!strncmp(required, provided, len) && provided[len] == '-')
  1.1368 -			return 1;
  1.1369 -		return 0;
  1.1370 -
  1.1371 -	case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
  1.1372 -		return cmp >= 0;
  1.1373 -
  1.1374 -	case RAZOR_PROPERTY_GREATER:
  1.1375 -		return cmp > 0;
  1.1376 -	}
  1.1377 -
  1.1378 -	/* shouldn't happen */
  1.1379 -	return 0;
  1.1380 -}
  1.1381 -
  1.1382 -#define TRANS_PACKAGE_PRESENT		1
  1.1383 -#define TRANS_PACKAGE_UPDATE		2
  1.1384 -#define TRANS_PROPERTY_SATISFIED	0x80000000
  1.1385 -
  1.1386 -struct transaction_set {
  1.1387 -	struct razor_set *set;
  1.1388 -	uint32_t *packages;
  1.1389 -	uint32_t *properties;
  1.1390 -};
  1.1391 -
  1.1392 -struct razor_transaction {
  1.1393 -	int package_count, errors;
  1.1394 -	struct transaction_set system, upstream;
  1.1395 -	int changes;
  1.1396 -};
  1.1397 -
  1.1398 -static void
  1.1399 -transaction_set_init(struct transaction_set *ts, struct razor_set *set)
  1.1400 -{
  1.1401 -	int count;
  1.1402 -
  1.1403 -	ts->set = set;
  1.1404 -	count = set->packages.size / sizeof (struct razor_package);
  1.1405 -	ts->packages = zalloc(count * sizeof *ts->packages);
  1.1406 -	count = set->properties.size / sizeof (struct razor_property);
  1.1407 -	ts->properties = zalloc(count * sizeof *ts->properties);
  1.1408 -}
  1.1409 -
  1.1410 -static void
  1.1411 -transaction_set_release(struct transaction_set *ts)
  1.1412 -{
  1.1413 -	free(ts->packages);
  1.1414 -	free(ts->properties);
  1.1415 -}
  1.1416 -
  1.1417 -static void
  1.1418 -transaction_set_install_package(struct transaction_set *ts,
  1.1419 -				struct razor_package *package)
  1.1420 -{
  1.1421 -	struct razor_package *pkgs;
  1.1422 -	struct list *prop;
  1.1423 -	int i;
  1.1424 -
  1.1425 -	pkgs = ts->set->packages.data;
  1.1426 -	i = package - pkgs;
  1.1427 -	if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
  1.1428 -		return;
  1.1429 -
  1.1430 -	ts->packages[i] = TRANS_PACKAGE_PRESENT;
  1.1431 -
  1.1432 -	prop = list_first(&package->properties, &ts->set->property_pool);
  1.1433 -	while (prop) {
  1.1434 -		ts->properties[prop->data]++;
  1.1435 -		prop = list_next(prop);
  1.1436 -	}
  1.1437 -}
  1.1438 -
  1.1439 -static void
  1.1440 -transaction_set_remove_package(struct transaction_set *ts,
  1.1441 -			       struct razor_package *package)
  1.1442 -{
  1.1443 -	struct razor_package *pkgs;
  1.1444 -	struct list *prop;
  1.1445 -	int i;
  1.1446 -
  1.1447 -	pkgs = ts->set->packages.data;
  1.1448 -	i = package - pkgs;
  1.1449 -	if (ts->packages[i] == 0)
  1.1450 -		return;
  1.1451 -
  1.1452 -	ts->packages[i] = 0;
  1.1453 -
  1.1454 -	prop = list_first(&package->properties, &ts->set->property_pool);
  1.1455 -	while (prop) {
  1.1456 -		ts->properties[prop->data]--;
  1.1457 -		prop = list_next(prop);
  1.1458 -	}
  1.1459 -}
  1.1460 -
  1.1461 -struct razor_transaction *
  1.1462 -razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
  1.1463 -{
  1.1464 -	struct razor_transaction *trans;
  1.1465 -	struct razor_package *p, *spkgs, *pend;
  1.1466 -
  1.1467 -	trans = zalloc(sizeof *trans);
  1.1468 -	transaction_set_init(&trans->system, system);
  1.1469 -	transaction_set_init(&trans->upstream, upstream);
  1.1470 -
  1.1471 -	spkgs = trans->system.set->packages.data;
  1.1472 -	pend = trans->system.set->packages.data +
  1.1473 -		trans->system.set->packages.size;
  1.1474 -	for (p = spkgs; p < pend; p++)
  1.1475 -		transaction_set_install_package(&trans->system, p);
  1.1476 -
  1.1477 -	return trans;
  1.1478 -}
  1.1479 -
  1.1480 -void
  1.1481 -razor_transaction_install_package(struct razor_transaction *trans,
  1.1482 -				  struct razor_package *package)
  1.1483 -{
  1.1484 -	transaction_set_install_package(&trans->upstream, package);
  1.1485 -	trans->changes++;
  1.1486 -}
  1.1487 -
  1.1488 -void
  1.1489 -razor_transaction_remove_package(struct razor_transaction *trans,
  1.1490 -				 struct razor_package *package)
  1.1491 -{
  1.1492 -	transaction_set_remove_package(&trans->system, package);
  1.1493 -	trans->changes++;
  1.1494 -}
  1.1495 -
  1.1496 -void
  1.1497 -razor_transaction_update_package(struct razor_transaction *trans,
  1.1498 -				  struct razor_package *package)
  1.1499 -{
  1.1500 -	struct razor_package *spkgs, *upkgs, *end;
  1.1501 -
  1.1502 -	spkgs = trans->system.set->packages.data;
  1.1503 -	upkgs = trans->upstream.set->packages.data;
  1.1504 -	end = trans->system.set->packages.data +
  1.1505 -		trans->system.set->packages.size;
  1.1506 -	if (spkgs <= package && package < end)
  1.1507 -		trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
  1.1508 -	else
  1.1509 -		trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
  1.1510 -}
  1.1511 -
  1.1512 -struct prop_iter {
  1.1513 -	struct razor_property *p, *start, *end;
  1.1514 -	const char *pool;
  1.1515 -	uint32_t *present;
  1.1516 -};
  1.1517 -
  1.1518 -static void
  1.1519 -prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
  1.1520 -{
  1.1521 -	pi->p = ts->set->properties.data;
  1.1522 -	pi->start = ts->set->properties.data;
  1.1523 -	pi->end = ts->set->properties.data + ts->set->properties.size;
  1.1524 -	pi->pool = ts->set->string_pool.data;
  1.1525 -	pi->present = ts->properties;
  1.1526 -}
  1.1527 -
  1.1528 -static int
  1.1529 -prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
  1.1530 -{
  1.1531 -	while (pi->p < pi->end) {
  1.1532 -		if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
  1.1533 -		    (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
  1.1534 -			*p = pi->p++;
  1.1535 -			return 1;
  1.1536 -		}
  1.1537 -		pi->p++;
  1.1538 -	}
  1.1539 -
  1.1540 -	return 0;
  1.1541 -}
  1.1542 -
  1.1543 -static struct razor_property *
  1.1544 -prop_iter_seek_to(struct prop_iter *pi,
  1.1545 -		  uint32_t flags, const char *match)
  1.1546 -{
  1.1547 -	uint32_t name;
  1.1548 -
  1.1549 -	while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
  1.1550 -		pi->p++;
  1.1551 -
  1.1552 -	if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
  1.1553 -		return NULL;
  1.1554 -
  1.1555 -	name = pi->p->name;
  1.1556 -	while (pi->p < pi->end &&
  1.1557 -	       pi->p->name == name &&
  1.1558 -	       (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
  1.1559 -		pi->p++;
  1.1560 -
  1.1561 -	if (pi->p == pi->end || pi->p->name != name)
  1.1562 -		return NULL;
  1.1563 -
  1.1564 -	return pi->p;
  1.1565 -}
  1.1566 -
  1.1567 -/* Remove packages from set that provide any of the matching (same
  1.1568 - * name and type) providers from ppi onwards that match the
  1.1569 - * requirement that rpi points to. */
  1.1570 -static void
  1.1571 -remove_matching_providers(struct razor_transaction *trans,
  1.1572 -			  struct prop_iter *ppi,
  1.1573 -			  uint32_t flags,
  1.1574 -			  const char *version)
  1.1575 -{
  1.1576 -	struct razor_property *p;
  1.1577 -	struct razor_package *pkg, *pkgs;
  1.1578 -	struct razor_package_iterator pkg_iter;
  1.1579 -	struct razor_set *set;
  1.1580 -	const char *n, *v, *a;
  1.1581 -	uint32_t type;
  1.1582 -
  1.1583 -	if (ppi->present == trans->system.properties)
  1.1584 -		set = trans->system.set;
  1.1585 -	else
  1.1586 -		set = trans->upstream.set;
  1.1587 -
  1.1588 -	pkgs = (struct razor_package *) set->packages.data;
  1.1589 -	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
  1.1590 -	for (p = ppi->p;
  1.1591 -	     p < ppi->end &&
  1.1592 -	     p->name == ppi->p->name &&
  1.1593 -	     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
  1.1594 -	     p++) {
  1.1595 -		if (!ppi->present[p - ppi->start])
  1.1596 -			continue;
  1.1597 -		if (!provider_satisfies_requirement(p, ppi->pool,
  1.1598 -						    flags, version))
  1.1599 -			continue;
  1.1600 -
  1.1601 -		razor_package_iterator_init_for_property(&pkg_iter, set, p);
  1.1602 -		while (razor_package_iterator_next(&pkg_iter,
  1.1603 -						   &pkg, &n, &v, &a)) {
  1.1604 -			fprintf(stderr, "removing %s-%s\n", n, v);
  1.1605 -			razor_transaction_remove_package(trans, pkg);
  1.1606 -		}
  1.1607 -	}
  1.1608 -}
  1.1609 -
  1.1610 -static void
  1.1611 -flag_matching_providers(struct razor_transaction *trans,
  1.1612 -			struct prop_iter *ppi,
  1.1613 -			struct razor_property *r,
  1.1614 -			struct prop_iter *rpi,
  1.1615 -			unsigned int flag)
  1.1616 -{
  1.1617 -	struct razor_property *p;
  1.1618 -	struct razor_package *pkg, *pkgs;
  1.1619 -	struct razor_package_iterator pkg_iter;
  1.1620 -	struct razor_set *set;
  1.1621 -	const char *name, *version, *arch;
  1.1622 -	uint32_t *flags, type;
  1.1623 -
  1.1624 -	if (ppi->present == trans->system.properties) {
  1.1625 -		set = trans->system.set;
  1.1626 -		flags = trans->system.packages;
  1.1627 -	} else {
  1.1628 -		set = trans->upstream.set;
  1.1629 -		flags = trans->upstream.packages;
  1.1630 -	}
  1.1631 -
  1.1632 -	pkgs = (struct razor_package *) set->packages.data;
  1.1633 -	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
  1.1634 -	for (p = ppi->p;
  1.1635 -	     p < ppi->end &&
  1.1636 -		     p->name == ppi->p->name &&
  1.1637 -		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
  1.1638 -	     p++) {
  1.1639 -		if (!ppi->present[p - ppi->start])
  1.1640 -			continue;
  1.1641 -		if (!provider_satisfies_requirement(p, ppi->pool,
  1.1642 -						    r->flags,
  1.1643 -						    &rpi->pool[r->version]))
  1.1644 -			continue;
  1.1645 -
  1.1646 -		razor_package_iterator_init_for_property(&pkg_iter, set, p);
  1.1647 -		while (razor_package_iterator_next(&pkg_iter, &pkg,
  1.1648 -						   &name, &version, &arch)) {
  1.1649 -
  1.1650 -			fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
  1.1651 -				name, version,
  1.1652 -				ppi->pool + p->name,
  1.1653 -				rpi->pool + r->name,
  1.1654 -				rpi->pool + r->version);
  1.1655 -			flags[pkg - pkgs] |= flag;
  1.1656 -		}
  1.1657 -	}
  1.1658 -}
  1.1659 -
  1.1660 -static struct razor_package *
  1.1661 -pick_matching_provider(struct razor_set *set,
  1.1662 -		       struct prop_iter *ppi,
  1.1663 -		       uint32_t flags,
  1.1664 -		       const char *version)
  1.1665 -{
  1.1666 -	struct razor_property *p;
  1.1667 -	struct razor_package *pkgs;
  1.1668 -	struct list *i;
  1.1669 -	uint32_t type;
  1.1670 -
  1.1671 -	/* This is where we decide which pkgs to pull in to satisfy a
  1.1672 -	 * requirement.  There may be several different providers
  1.1673 -	 * (different versions) and each version of a provider may
  1.1674 -	 * come from a number of packages.  We pick the first package
  1.1675 -	 * from the first provider that matches. */
  1.1676 -
  1.1677 -	pkgs = set->packages.data;
  1.1678 -	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
  1.1679 -	for (p = ppi->p;
  1.1680 -	     p < ppi->end &&
  1.1681 -		     p->name == ppi->p->name &&
  1.1682 -		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
  1.1683 -		     ppi->present[p - ppi->start] == 0;
  1.1684 -	     p++) {
  1.1685 -		if (!provider_satisfies_requirement(p, ppi->pool,
  1.1686 -						    flags, version))
  1.1687 -			continue;
  1.1688 -
  1.1689 -		i = list_first(&p->packages, &set->package_pool);
  1.1690 -
  1.1691 -		return &pkgs[i->data];
  1.1692 -	}
  1.1693 -
  1.1694 -	return NULL;
  1.1695 -}
  1.1696 -
  1.1697 -static void
  1.1698 -remove_obsoleted_packages(struct razor_transaction *trans)
  1.1699 -{
  1.1700 -	struct razor_property *up;
  1.1701 -	struct razor_package *spkgs;
  1.1702 -	struct prop_iter spi, upi;
  1.1703 -
  1.1704 -	spkgs = trans->system.set->packages.data;
  1.1705 -	prop_iter_init(&spi, &trans->system);
  1.1706 -	prop_iter_init(&upi, &trans->upstream);
  1.1707 -
  1.1708 -	while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
  1.1709 -		if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
  1.1710 -				       &upi.pool[up->name]))
  1.1711 -			continue;
  1.1712 -		remove_matching_providers(trans, &spi, up->flags,
  1.1713 -					  &upi.pool[up->version]);
  1.1714 -	}
  1.1715 -}
  1.1716 -
  1.1717 -static int
  1.1718 -any_provider_satisfies_requirement(struct prop_iter *ppi,
  1.1719 -				   uint32_t flags,
  1.1720 -				   const char *version)
  1.1721 -{
  1.1722 -	struct razor_property *p;
  1.1723 -	uint32_t type;
  1.1724 -
  1.1725 -	type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
  1.1726 -	for (p = ppi->p;
  1.1727 -	     p < ppi->end &&
  1.1728 -		     p->name == ppi->p->name &&
  1.1729 -		     (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
  1.1730 -	     p++) {
  1.1731 -		if (ppi->present[p - ppi->start] > 0 &&
  1.1732 -		    provider_satisfies_requirement(p, ppi->pool,
  1.1733 -						   flags, version))
  1.1734 -			return 1;
  1.1735 -	}
  1.1736 -
  1.1737 -	return 0;
  1.1738 -}
  1.1739 -
  1.1740 -static void
  1.1741 -clear_requires_flags(struct transaction_set *ts)
  1.1742 -{
  1.1743 -	struct razor_property *p;
  1.1744 -	const char *pool;
  1.1745 -	int i, count;
  1.1746 -
  1.1747 -	count = ts->set->properties.size / sizeof *p;
  1.1748 -	p = ts->set->properties.data;
  1.1749 -	pool = ts->set->string_pool.data;
  1.1750 -	for (i = 0; i < count; i++) {
  1.1751 -		ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
  1.1752 -		if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
  1.1753 -			ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
  1.1754 -	}
  1.1755 -}
  1.1756 -
  1.1757 -const char *
  1.1758 -razor_property_relation_to_string(struct razor_property *p)
  1.1759 -{
  1.1760 -	switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
  1.1761 -	case RAZOR_PROPERTY_LESS:
  1.1762 -		return "<";
  1.1763 -
  1.1764 -	case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
  1.1765 -		return "<=";
  1.1766 -
  1.1767 -	case RAZOR_PROPERTY_EQUAL:
  1.1768 -		return "=";
  1.1769 -
  1.1770 -	case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
  1.1771 -		return ">=";
  1.1772 -
  1.1773 -	case RAZOR_PROPERTY_GREATER:
  1.1774 -		return ">";
  1.1775 -
  1.1776 -	default:
  1.1777 -		return "?";
  1.1778 -	}
  1.1779 -}
  1.1780 -
  1.1781 -const char *
  1.1782 -razor_property_type_to_string(struct razor_property *p)
  1.1783 -{
  1.1784 -	switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
  1.1785 -	case RAZOR_PROPERTY_REQUIRES:
  1.1786 -		return "requires";
  1.1787 -	case RAZOR_PROPERTY_PROVIDES:
  1.1788 -		return "provides";
  1.1789 -	case RAZOR_PROPERTY_CONFLICTS:
  1.1790 -		return "conflicts";
  1.1791 -	case RAZOR_PROPERTY_OBSOLETES:
  1.1792 -		return "obsoletes";
  1.1793 -	default:
  1.1794 -		return NULL;
  1.1795 -	}
  1.1796 -}
  1.1797 -
  1.1798 -static void
  1.1799 -mark_satisfied_requires(struct razor_transaction *trans,
  1.1800 -			struct transaction_set *rts,
  1.1801 -			struct transaction_set *pts)
  1.1802 -{
  1.1803 -	struct prop_iter rpi, ppi;
  1.1804 -	struct razor_property *rp;
  1.1805 -
  1.1806 -	prop_iter_init(&rpi, rts);
  1.1807 -	prop_iter_init(&ppi, pts);
  1.1808 -
  1.1809 -	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
  1.1810 -		if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
  1.1811 -				       &rpi.pool[rp->name]))
  1.1812 -			continue;
  1.1813 -
  1.1814 -		if (any_provider_satisfies_requirement(&ppi, rp->flags,
  1.1815 -						       &rpi.pool[rp->version]))
  1.1816 -			rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
  1.1817 -	}
  1.1818 -}
  1.1819 -
  1.1820 -static void
  1.1821 -mark_all_satisfied_requires(struct razor_transaction *trans)
  1.1822 -{
  1.1823 -	clear_requires_flags(&trans->system);
  1.1824 -	clear_requires_flags(&trans->upstream);
  1.1825 -	mark_satisfied_requires(trans, &trans->system, &trans->system);
  1.1826 -	mark_satisfied_requires(trans, &trans->system, &trans->upstream);
  1.1827 -	mark_satisfied_requires(trans, &trans->upstream, &trans->system);
  1.1828 -	mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
  1.1829 -}
  1.1830 -
  1.1831 -static void
  1.1832 -update_unsatisfied_packages(struct razor_transaction *trans)
  1.1833 -{
  1.1834 -	struct razor_package *spkgs, *pkg;
  1.1835 -	struct razor_property *sp;
  1.1836 -	struct prop_iter spi;
  1.1837 -	struct razor_package_iterator pkg_iter;
  1.1838 -	const char *name, *version, *arch;
  1.1839 -
  1.1840 -	spkgs = trans->system.set->packages.data;
  1.1841 -	prop_iter_init(&spi, &trans->system);
  1.1842 -
  1.1843 -	while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
  1.1844 -		if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
  1.1845 -			continue;
  1.1846 -
  1.1847 -		razor_package_iterator_init_for_property(&pkg_iter,
  1.1848 -							 trans->system.set,
  1.1849 -							 sp);
  1.1850 -		while (razor_package_iterator_next(&pkg_iter, &pkg,
  1.1851 -						   &name, &version, &arch)) {
  1.1852 -			fprintf(stderr, "updating %s because %s %s %s "
  1.1853 -				"isn't satisfied\n",
  1.1854 -				name, spi.pool + sp->name,
  1.1855 -				razor_property_relation_to_string(sp),
  1.1856 -				spi.pool + sp->version);
  1.1857 -			trans->system.packages[pkg - spkgs] |=
  1.1858 -				TRANS_PACKAGE_UPDATE;
  1.1859 -		}
  1.1860 -	}
  1.1861 -}
  1.1862 -
  1.1863 -void
  1.1864 -razor_transaction_update_all(struct razor_transaction *trans)
  1.1865 -{
  1.1866 -	struct razor_package *p;
  1.1867 -	int i, count;
  1.1868 -
  1.1869 -	count = trans->system.set->packages.size / sizeof *p;
  1.1870 -	for (i = 0; i < count; i++)
  1.1871 -		trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
  1.1872 -}
  1.1873 -
  1.1874 -static void
  1.1875 -update_conflicted_packages(struct razor_transaction *trans)
  1.1876 -{
  1.1877 -	struct razor_package *pkg, *spkgs;
  1.1878 -	struct razor_property *up, *sp;
  1.1879 -	struct prop_iter spi, upi;
  1.1880 -	struct razor_package_iterator pkg_iter;
  1.1881 -	const char *name, *version, *arch;
  1.1882 -
  1.1883 -	spkgs = trans->system.set->packages.data;
  1.1884 -	prop_iter_init(&spi, &trans->system);
  1.1885 -	prop_iter_init(&upi, &trans->upstream);
  1.1886 -
  1.1887 -	while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
  1.1888 -		if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
  1.1889 -				       &spi.pool[sp->name]))
  1.1890 -			continue;
  1.1891 -
  1.1892 -		if (!any_provider_satisfies_requirement(&upi, sp->flags,
  1.1893 -							&spi.pool[sp->version]))
  1.1894 -			continue;
  1.1895 -
  1.1896 -		razor_package_iterator_init_for_property(&pkg_iter,
  1.1897 -							 trans->system.set,
  1.1898 -							 sp);
  1.1899 -		while (razor_package_iterator_next(&pkg_iter, &pkg,
  1.1900 -						   &name, &version, &arch)) {
  1.1901 -			fprintf(stderr, "updating %s %s because it conflicts with %s",
  1.1902 -				name, version, spi.pool + sp->name);
  1.1903 -			trans->system.packages[pkg - spkgs] |=
  1.1904 -				TRANS_PACKAGE_UPDATE;
  1.1905 -		}
  1.1906 -	}
  1.1907 -
  1.1908 -	prop_iter_init(&spi, &trans->system);
  1.1909 -	prop_iter_init(&upi, &trans->upstream);
  1.1910 -
  1.1911 -	while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
  1.1912 -		sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
  1.1913 -				       &upi.pool[upi.p->name]);
  1.1914 -
  1.1915 -		if (sp)
  1.1916 -			flag_matching_providers(trans, &spi, up, &upi,
  1.1917 -						TRANS_PACKAGE_UPDATE);
  1.1918 -	}
  1.1919 -}
  1.1920 -
  1.1921 -static void
  1.1922 -pull_in_requirements(struct razor_transaction *trans,
  1.1923 -		     struct prop_iter *rpi, struct prop_iter *ppi)
  1.1924 -{
  1.1925 -	struct razor_property *rp, *pp;
  1.1926 -	struct razor_package *pkg, *upkgs;
  1.1927 -
  1.1928 -	upkgs = trans->upstream.set->packages.data;
  1.1929 -	while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
  1.1930 -		if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
  1.1931 -			continue;
  1.1932 -
  1.1933 -		pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
  1.1934 -				       &rpi->pool[rp->name]);
  1.1935 -		if (pp == NULL)
  1.1936 -			continue;
  1.1937 -		pkg = pick_matching_provider(trans->upstream.set,
  1.1938 -					     ppi, rp->flags,
  1.1939 -					     &rpi->pool[rp->version]);
  1.1940 -		if (pkg == NULL)
  1.1941 -			continue;
  1.1942 -
  1.1943 -		rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
  1.1944 -
  1.1945 -		fprintf(stderr, "pulling in %s which provides %s %s %s "
  1.1946 -			"to satisfy %s %s %s\n",
  1.1947 -			ppi->pool + pkg->name,
  1.1948 -			ppi->pool + pp->name,
  1.1949 -			razor_property_relation_to_string(pp),
  1.1950 -			ppi->pool + pp->version,
  1.1951 -			&rpi->pool[rp->name],
  1.1952 -			razor_property_relation_to_string(rp),
  1.1953 -			&rpi->pool[rp->version]);
  1.1954 -
  1.1955 -		trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
  1.1956 -	}
  1.1957 -}
  1.1958 -
  1.1959 -static void
  1.1960 -pull_in_all_requirements(struct razor_transaction *trans)
  1.1961 -{
  1.1962 -	struct prop_iter rpi, ppi;
  1.1963 -
  1.1964 -	prop_iter_init(&rpi, &trans->system);
  1.1965 -	prop_iter_init(&ppi, &trans->upstream);
  1.1966 -	pull_in_requirements(trans, &rpi, &ppi);
  1.1967 -
  1.1968 -	prop_iter_init(&rpi, &trans->upstream);
  1.1969 -	prop_iter_init(&ppi, &trans->upstream);
  1.1970 -	pull_in_requirements(trans, &rpi, &ppi);
  1.1971 -}
  1.1972 -
  1.1973 -static void
  1.1974 -flush_scheduled_system_updates(struct razor_transaction *trans)
  1.1975 -{
  1.1976 - 	struct razor_package_iterator *pi;
  1.1977 - 	struct razor_package *p, *pkg, *spkgs;
  1.1978 -	struct prop_iter ppi;
  1.1979 -	const char *name, *version, *arch;
  1.1980 -
  1.1981 -	spkgs = trans->system.set->packages.data;
  1.1982 -	pi = razor_package_iterator_create(trans->system.set);
  1.1983 -	prop_iter_init(&ppi, &trans->upstream);
  1.1984 -
  1.1985 -	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
  1.1986 -		if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
  1.1987 -			continue;
  1.1988 -
  1.1989 -		if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
  1.1990 -			continue;
  1.1991 -
  1.1992 -		pkg = pick_matching_provider(trans->upstream.set, &ppi,
  1.1993 -					     RAZOR_PROPERTY_GREATER, version);
  1.1994 -		if (pkg == NULL)
  1.1995 -			continue;
  1.1996 -
  1.1997 -		fprintf(stderr, "updating %s-%s to %s-%s\n",
  1.1998 -			name, version,
  1.1999 -			&ppi.pool[pkg->name], &ppi.pool[pkg->version]);
  1.2000 -
  1.2001 -		razor_transaction_remove_package(trans, p);
  1.2002 -		razor_transaction_install_package(trans, pkg);
  1.2003 -	}
  1.2004 -
  1.2005 -	razor_package_iterator_destroy(pi);
  1.2006 -}
  1.2007 -
  1.2008 -static void
  1.2009 -flush_scheduled_upstream_updates(struct razor_transaction *trans)
  1.2010 -{
  1.2011 - 	struct razor_package_iterator *pi;
  1.2012 - 	struct razor_package *p, *upkgs;
  1.2013 -	struct prop_iter spi;
  1.2014 -	const char *name, *version, *arch;
  1.2015 -
  1.2016 -	upkgs = trans->upstream.set->packages.data;
  1.2017 -	pi = razor_package_iterator_create(trans->upstream.set);
  1.2018 -	prop_iter_init(&spi, &trans->system);
  1.2019 -
  1.2020 -	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
  1.2021 -		if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
  1.2022 -			continue;
  1.2023 -
  1.2024 -		if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
  1.2025 -			remove_matching_providers(trans,
  1.2026 -						  &spi,
  1.2027 -						  RAZOR_PROPERTY_LESS,
  1.2028 -						  version);
  1.2029 -		razor_transaction_install_package(trans, p);
  1.2030 -		fprintf(stderr, "installing %s-%s\n", name, version);
  1.2031 -	}
  1.2032 -}
  1.2033 -
  1.2034 -int
  1.2035 -razor_transaction_resolve(struct razor_transaction *trans)
  1.2036 -{
  1.2037 -	int last = 0;
  1.2038 -
  1.2039 -	flush_scheduled_system_updates(trans);
  1.2040 -	flush_scheduled_upstream_updates(trans);
  1.2041 -
  1.2042 -	while (last < trans->changes) {
  1.2043 -		last = trans->changes;
  1.2044 -		remove_obsoleted_packages(trans);
  1.2045 -		mark_all_satisfied_requires(trans);
  1.2046 -		update_unsatisfied_packages(trans);
  1.2047 -		update_conflicted_packages(trans);
  1.2048 -		pull_in_all_requirements(trans);
  1.2049 -		flush_scheduled_system_updates(trans);
  1.2050 -		flush_scheduled_upstream_updates(trans);
  1.2051 -	}
  1.2052 -
  1.2053 -	return trans->changes;
  1.2054 -}
  1.2055 -
  1.2056 -static void
  1.2057 -describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
  1.2058 -{
  1.2059 -	struct razor_package_iterator pi;
  1.2060 -	struct razor_package *pkg;
  1.2061 -	const char *name, *version, *arch, *pool;
  1.2062 -
  1.2063 -	pool = set->string_pool.data;
  1.2064 -	if (pool[rp->version] == '\0') {
  1.2065 -		razor_package_iterator_init_for_property(&pi, set, rp);
  1.2066 -		while (razor_package_iterator_next(&pi, &pkg,
  1.2067 -						   &name, &version, &arch))
  1.2068 -			fprintf(stderr, "%s is needed by %s-%s.%s\n",
  1.2069 -				&pool[rp->name],
  1.2070 -				name, version, arch);
  1.2071 -	} else {
  1.2072 -		razor_package_iterator_init_for_property(&pi, set, rp);
  1.2073 -		while (razor_package_iterator_next(&pi, &pkg,
  1.2074 -						   &name, &version, &arch))
  1.2075 -			fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
  1.2076 -				&pool[rp->name],
  1.2077 -				razor_property_relation_to_string(rp),
  1.2078 -				&pool[rp->version],
  1.2079 -				name, version, arch);
  1.2080 -	}
  1.2081 -}
  1.2082 -
  1.2083 -int
  1.2084 -razor_transaction_describe(struct razor_transaction *trans)
  1.2085 -{
  1.2086 -	struct prop_iter rpi;
  1.2087 -	struct razor_property *rp;
  1.2088 -	int unsatisfied;
  1.2089 -
  1.2090 -	flush_scheduled_system_updates(trans);
  1.2091 -	flush_scheduled_upstream_updates(trans);
  1.2092 -	mark_all_satisfied_requires(trans);
  1.2093 -
  1.2094 -	unsatisfied = 0;
  1.2095 -	prop_iter_init(&rpi, &trans->system);
  1.2096 -	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
  1.2097 -		if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
  1.2098 -			describe_unsatisfied(trans->system.set, rp);
  1.2099 -		        unsatisfied++;
  1.2100 -		}
  1.2101 -	}
  1.2102 -
  1.2103 -	prop_iter_init(&rpi, &trans->upstream);
  1.2104 -	while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
  1.2105 -		if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
  1.2106 -			describe_unsatisfied(trans->upstream.set, rp);
  1.2107 -			unsatisfied++;
  1.2108 -		}
  1.2109 -	}
  1.2110 -
  1.2111 -	return unsatisfied;
  1.2112 -}
  1.2113 -
  1.2114 -int
  1.2115 -razor_transaction_unsatisfied_property(struct razor_transaction *trans,
  1.2116 -				       const char *name,
  1.2117 -				       uint32_t flags,
  1.2118 -				       const char *version)
  1.2119 -{
  1.2120 -	struct prop_iter pi;
  1.2121 -	struct razor_property *p;
  1.2122 -
  1.2123 -	prop_iter_init(&pi, &trans->system);
  1.2124 -	while (prop_iter_next(&pi, flags, &p)) {
  1.2125 -		if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
  1.2126 -		    p->flags == flags &&
  1.2127 -		    strcmp(&pi.pool[p->name], name) == 0 &&
  1.2128 -		    strcmp(&pi.pool[p->version], version) == 0)
  1.2129 -
  1.2130 -			return 1;
  1.2131 -	}
  1.2132 -
  1.2133 -	prop_iter_init(&pi, &trans->upstream);
  1.2134 -	while (prop_iter_next(&pi, flags, &p)) {
  1.2135 -		if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
  1.2136 -		    p->flags == flags &&
  1.2137 -		    strcmp(&pi.pool[p->name], name) == 0 &&
  1.2138 -		    strcmp(&pi.pool[p->version], version) == 0)
  1.2139 -
  1.2140 -			return 1;
  1.2141 -	}
  1.2142 -
  1.2143 -	return 0;
  1.2144 -}
  1.2145 -
  1.2146 -struct razor_set *
  1.2147 -razor_transaction_finish(struct razor_transaction *trans)
  1.2148 -{
  1.2149 -	struct razor_merger *merger;
  1.2150 -	struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
  1.2151 -	char *upool, *spool;
  1.2152 -	int cmp;
  1.2153 -
  1.2154 -	s = trans->system.set->packages.data;
  1.2155 -	spkgs = trans->system.set->packages.data;
  1.2156 -	send = trans->system.set->packages.data +
  1.2157 -		trans->system.set->packages.size;
  1.2158 -	spool = trans->system.set->string_pool.data;
  1.2159 -
  1.2160 -	u = trans->upstream.set->packages.data;
  1.2161 -	upkgs = trans->upstream.set->packages.data;
  1.2162 -	uend = trans->upstream.set->packages.data +
  1.2163 -		trans->upstream.set->packages.size;
  1.2164 -	upool = trans->upstream.set->string_pool.data;
  1.2165 -
  1.2166 -	merger = razor_merger_create(trans->system.set, trans->upstream.set);
  1.2167 -	while (s < send || u < uend) {
  1.2168 -		if (s < send && u < uend)
  1.2169 -			cmp = strcmp(&spool[s->name], &upool[u->name]);
  1.2170 -		else if (s < send)
  1.2171 -			cmp = -1;
  1.2172 -		else
  1.2173 -			cmp = 1;
  1.2174 -
  1.2175 -		if (cmp < 0) {
  1.2176 -			if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
  1.2177 -				razor_merger_add_package(merger, s);
  1.2178 -			s++;
  1.2179 -		} else if (cmp == 0) {
  1.2180 -			if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
  1.2181 -				razor_merger_add_package(merger, s);
  1.2182 -			if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
  1.2183 -				razor_merger_add_package(merger, u);
  1.2184 -
  1.2185 -			s++;
  1.2186 -			u++;
  1.2187 -		} else {
  1.2188 -			if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
  1.2189 -				razor_merger_add_package(merger, u);
  1.2190 -			u++;
  1.2191 -		}
  1.2192 -	}
  1.2193 -
  1.2194 -	razor_transaction_destroy(trans);
  1.2195 -
  1.2196 -	return razor_merger_finish(merger);
  1.2197 -}
  1.2198 -
  1.2199 -void
  1.2200 -razor_transaction_destroy(struct razor_transaction *trans)
  1.2201 -{
  1.2202 -	transaction_set_release(&trans->system);
  1.2203 -	transaction_set_release(&trans->upstream);
  1.2204 -	free(trans);
  1.2205 -}
  1.2206 -
  1.2207 -struct razor_package_query {
  1.2208 -	struct razor_set *set;
  1.2209 -	char *vector;
  1.2210 -	int count;
  1.2211 -};
  1.2212 -
  1.2213 -struct razor_package_query *
  1.2214 -razor_package_query_create(struct razor_set *set)
  1.2215 -{
  1.2216 -	struct razor_package_query *pq;
  1.2217 -	int count;
  1.2218 -
  1.2219 -	pq = zalloc(sizeof *pq);
  1.2220 -	pq->set = set;
  1.2221 -	count = set->packages.size / sizeof(struct razor_package);
  1.2222 -	pq->vector = zalloc(count * sizeof(char));
  1.2223 -
  1.2224 -	return pq;
  1.2225 -}
  1.2226 -
  1.2227 -void
  1.2228 -razor_package_query_add_package(struct razor_package_query *pq,
  1.2229 -				struct razor_package *p)
  1.2230 -{
  1.2231 -	struct razor_package *packages;
  1.2232 -
  1.2233 -	packages = pq->set->packages.data;
  1.2234 -	pq->count += pq->vector[p - packages] ^ 1;
  1.2235 -	pq->vector[p - packages] = 1;
  1.2236 -}
  1.2237 -
  1.2238 -void
  1.2239 -razor_package_query_add_iterator(struct razor_package_query *pq,
  1.2240 -				 struct razor_package_iterator *pi)
  1.2241 -{
  1.2242 -	struct razor_package *packages, *p;
  1.2243 -	const char *name, *version, *arch;
  1.2244 -
  1.2245 -	packages = pq->set->packages.data;
  1.2246 -	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
  1.2247 -		pq->count += pq->vector[p - packages] ^ 1;
  1.2248 -		pq->vector[p - packages] = 1;
  1.2249 -	}
  1.2250 -}
  1.2251 -
  1.2252 -struct razor_package_iterator *
  1.2253 -razor_package_query_finish(struct razor_package_query *pq)
  1.2254 -{
  1.2255 -	struct razor_package_iterator *pi;
  1.2256 -	struct razor_set *set;
  1.2257 -	struct list *index;
  1.2258 -	int i, j, count;
  1.2259 -
  1.2260 -	set = pq->set;
  1.2261 -	count = set->packages.size / sizeof(struct razor_package);
  1.2262 -	index = zalloc(pq->count * sizeof *index);
  1.2263 -
  1.2264 -	for (i = 0, j = 0; i < count; i++) {
  1.2265 -		if (!pq->vector[i])
  1.2266 -			continue;
  1.2267 -
  1.2268 -		index[j].data = i;
  1.2269 -		if (j == pq->count - 1)
  1.2270 -			index[j].flags = 0x80;
  1.2271 -		j++;
  1.2272 -	}
  1.2273 -
  1.2274 -	free(pq);
  1.2275 -
  1.2276 -	pi = razor_package_iterator_create_with_index(set, index);
  1.2277 -	pi->free_index = 1;
  1.2278 -
  1.2279 -	return pi;
  1.2280 -}