razor.c
changeset 141 9b56280ea8ea
parent 140 017f92f7039a
child 142 4819c228434c
     1.1 --- a/razor.c	Mon Mar 03 14:55:16 2008 -0500
     1.2 +++ b/razor.c	Mon Mar 03 16:05:33 2008 -0500
     1.3 @@ -1651,16 +1651,34 @@
     1.4  	return result;
     1.5  }
     1.6  
     1.7 -static int
     1.8 -find_packages(struct razor_set *set, int count, const char **package_names,
     1.9 -	      struct array *package_array, struct bitarray *pkgbits,
    1.10 +
    1.11 +struct razor_transaction_resolver {
    1.12 +	struct razor_set *system, *upstream;
    1.13 +	struct bitarray syspkgs, uppkgs;
    1.14 +	struct array packages;
    1.15 +	int errors;
    1.16 +};
    1.17 +
    1.18 +static void
    1.19 +find_packages(struct razor_transaction_resolver *trans,
    1.20 +	      int count, const char **package_names,
    1.21  	      enum razor_transaction_package_state state)
    1.22  {
    1.23 +	struct razor_set *set;
    1.24 +	struct bitarray *pkgbits;
    1.25  	struct razor_package_iterator *pi;
    1.26  	struct razor_package *p, *packages;
    1.27  	const char *name, *version;
    1.28  	struct razor_transaction_package *tp;
    1.29 -	int i, *found, errors = 0;
    1.30 +	int i, *found;
    1.31 +
    1.32 +	if (state == RAZOR_PACKAGE_INSTALL) {
    1.33 +		set = trans->upstream;
    1.34 +		pkgbits = &trans->uppkgs;
    1.35 +	} else {
    1.36 +		set = trans->system;
    1.37 +		pkgbits = &trans->syspkgs;
    1.38 +	}
    1.39  
    1.40  	packages = (struct razor_package *) set->packages.data;
    1.41  	pi = razor_package_iterator_create(set);
    1.42 @@ -1670,7 +1688,7 @@
    1.43  		for (i = 0; i < count; i++) {
    1.44  			if (strcmp(name, package_names[i]) == 0) {
    1.45  				found[i] = 1;
    1.46 -				tp = array_add(package_array, sizeof *tp);
    1.47 +				tp = array_add(&trans->packages, sizeof *tp);
    1.48  				memset(tp, 0, sizeof *tp);
    1.49  				tp->package = p;
    1.50  				tp->name = name;
    1.51 @@ -1685,45 +1703,42 @@
    1.52  
    1.53  	for (i = 0; i < count; i++) {
    1.54  		if (!found[i]) {
    1.55 -			tp = array_add(package_array, sizeof *tp);
    1.56 +			tp = array_add(&trans->packages, sizeof *tp);
    1.57  			memset(tp, 0, sizeof *tp);
    1.58  			tp->name = strdup(package_names[i]);
    1.59  			tp->state = state | RAZOR_PACKAGE_UNAVAILABLE;
    1.60 -			errors++;
    1.61 +			trans->errors++;
    1.62  		}
    1.63  	}
    1.64  
    1.65  	razor_package_iterator_destroy(pi);
    1.66  	free(found);
    1.67 -
    1.68 -	return errors;
    1.69  }
    1.70  
    1.71  static void
    1.72 -find_all_packages(struct razor_set *set, struct razor_set *upstream,
    1.73 -		  struct array *package_array, struct bitarray *pkgbits)
    1.74 +find_all_packages(struct razor_transaction_resolver *trans)
    1.75  {
    1.76  	struct razor_transaction_package *tp;
    1.77  	struct razor_package *p, *packages, *u, *pend, *uend;
    1.78  	char *pool, *upool;
    1.79  
    1.80 -	packages = set->packages.data;
    1.81 -	pend = set->packages.data + set->packages.size;
    1.82 -	pool = set->string_pool.data;
    1.83 -	u = upstream->packages.data;
    1.84 -	uend = upstream->packages.data + upstream->packages.size;
    1.85 -	upool = upstream->string_pool.data;
    1.86 +	packages = trans->system->packages.data;
    1.87 +	pend = trans->system->packages.data + trans->system->packages.size;
    1.88 +	pool = trans->system->string_pool.data;
    1.89 +	u = trans->upstream->packages.data;
    1.90 +	uend = trans->upstream->packages.data + trans->upstream->packages.size;
    1.91 +	upool = trans->upstream->string_pool.data;
    1.92  
    1.93  	for (p = packages; p < pend; p++) {
    1.94  		while (u < uend && strcmp(&pool[p->name], &upool[u->name]) > 0)
    1.95  			u++;
    1.96  		if (strcmp(&pool[p->name], &upool[u->name]) == 0) {
    1.97 -			tp = array_add(package_array, sizeof *tp);
    1.98 +			tp = array_add(&trans->packages, sizeof *tp);
    1.99  			memset(tp, 0, sizeof *tp);
   1.100  			tp->name = &upool[u->name];
   1.101  			tp->version = &upool[u->version];
   1.102  			tp->state = RAZOR_PACKAGE_INSTALL;
   1.103 -			bitarray_set(pkgbits, p - packages, 1);
   1.104 +			bitarray_set(&trans->uppkgs, p - packages, 1);
   1.105  		}
   1.106  	}
   1.107  }
   1.108 @@ -1789,8 +1804,8 @@
   1.109  }
   1.110  
   1.111  static int
   1.112 -find_system_file(struct razor_transaction *trans,
   1.113 -		 struct bitarray *syspkgs, int installed, int up)
   1.114 +find_system_file(struct razor_transaction_resolver *trans,
   1.115 +		 int installed, int up)
   1.116  {
   1.117  	struct razor_entry *entry;
   1.118  	struct razor_property *uprops = trans->upstream->properties.data;
   1.119 @@ -1808,14 +1823,14 @@
   1.120  	for (p = list_first(&entry->packages, &trans->system->package_pool);
   1.121  	     p;
   1.122  	     p = list_next(p)) {
   1.123 -		if (bitarray_get(syspkgs, p->data) == installed)
   1.124 +		if (bitarray_get(&trans->syspkgs, p->data) == installed)
   1.125  			return 1;
   1.126  	}
   1.127  	return 0;
   1.128  }
   1.129  
   1.130  static struct razor_package *
   1.131 -find_system_provider(struct razor_transaction *trans, struct bitarray *syspkgs,
   1.132 +find_system_provider(struct razor_transaction_resolver *trans,
   1.133  		     int installed, int match_name,
   1.134  		     struct razor_property *req, int *sp)
   1.135  {
   1.136 @@ -1844,7 +1859,7 @@
   1.137  			struct list *pkg;
   1.138  
   1.139  			for (pkg = list_first(&sprops[*sp].packages, &trans->system->package_pool); pkg; pkg = list_next(pkg)) {
   1.140 -				if (bitarray_get(syspkgs, pkg->data) != installed)
   1.141 +				if (bitarray_get(&trans->syspkgs, pkg->data) != installed)
   1.142  					continue;
   1.143  				if (!match_name ||
   1.144  				    strcmp(&spool[spkgs[pkg->data].name],
   1.145 @@ -1859,8 +1874,7 @@
   1.146  }
   1.147  
   1.148  static struct razor_package *
   1.149 -find_upstream_provider(struct razor_transaction *trans,
   1.150 -		       struct bitarray *uppkgs,
   1.151 +find_upstream_provider(struct razor_transaction_resolver *trans,
   1.152  		       int installed, int match_name,
   1.153  		       struct razor_property *req, int up)
   1.154  {
   1.155 @@ -1894,7 +1908,7 @@
   1.156  			struct list *pkg;
   1.157  
   1.158  			for (pkg = list_first(&uprops[up].packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
   1.159 -				if (bitarray_get(uppkgs, pkg->data) != installed)
   1.160 +				if (bitarray_get(&trans->uppkgs, pkg->data) != installed)
   1.161  					continue;
   1.162  				if (!match_name ||
   1.163  				    strcmp(&upool[upkgs[pkg->data].name],
   1.164 @@ -1908,9 +1922,8 @@
   1.165  }
   1.166  
   1.167  static struct razor_package *
   1.168 -find_upgrade(struct razor_transaction *trans,
   1.169 -	     struct bitarray *uppkgs, struct razor_property *obsolete,
   1.170 -	     int up)
   1.171 +find_upgrade(struct razor_transaction_resolver *trans,
   1.172 +	     struct razor_property *obsolete, int up)
   1.173  {
   1.174  	struct razor_property *uprops = trans->upstream->properties.data;
   1.175  	const char *upool = trans->upstream->string_pool.data;
   1.176 @@ -1939,13 +1952,12 @@
   1.177  	if (up < 0)
   1.178  		return NULL;
   1.179  
   1.180 -	return find_upstream_provider(trans, uppkgs, 0, 1, &req, up);
   1.181 +	return find_upstream_provider(trans, 0, 1, &req, up);
   1.182  }
   1.183  
   1.184  static struct razor_package *
   1.185 -find_upstream_file(struct razor_transaction *trans,
   1.186 -		   struct bitarray *uppkgs, int installed,
   1.187 -		   int up)
   1.188 +find_upstream_file(struct razor_transaction_resolver *trans,
   1.189 +		   int installed, int up)
   1.190  {
   1.191  	struct razor_package *upkgs = trans->upstream->packages.data;
   1.192  	struct razor_property *uprops = trans->upstream->properties.data;
   1.193 @@ -1962,17 +1974,14 @@
   1.194  		return NULL;
   1.195  
   1.196  	for (pkg = list_first(&entry->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
   1.197 -		if (bitarray_get(uppkgs, pkg->data) == installed)
   1.198 +		if (bitarray_get(&trans->uppkgs, pkg->data) == installed)
   1.199  			return &upkgs[pkg->data];
   1.200  	}
   1.201  	return NULL;
   1.202  }
   1.203  
   1.204  static void
   1.205 -add_transaction_package(struct razor_transaction *trans,
   1.206 -			struct bitarray *syspkgs,
   1.207 -			struct bitarray *uppkgs,
   1.208 -			struct array *package_array,
   1.209 +add_transaction_package(struct razor_transaction_resolver *trans,
   1.210  			struct razor_package *package,
   1.211  			struct razor_set *package_set,
   1.212  			enum razor_transaction_package_state state,
   1.213 @@ -1984,7 +1993,7 @@
   1.214  	struct razor_package *pkgs;
   1.215  	struct list *pkg;
   1.216  
   1.217 -	tp = array_add(package_array, sizeof *tp);
   1.218 +	tp = array_add(&trans->packages, sizeof *tp);
   1.219  	memset(tp, 0, sizeof *tp);
   1.220  
   1.221  	if (package) {
   1.222 @@ -1997,7 +2006,7 @@
   1.223  		tp->state = state | RAZOR_PACKAGE_UNSATISFIABLE;
   1.224  
   1.225  	for (pkg = list_first(&req_prop->packages, &req_set->package_pool); pkg; pkg = list_next(pkg)) {
   1.226 -		if (bitarray_get(uppkgs, pkg->data))
   1.227 +		if (bitarray_get(&trans->uppkgs, pkg->data))
   1.228  			break;
   1.229  	}
   1.230  	if (pkg) {
   1.231 @@ -2012,33 +2021,29 @@
   1.232  
   1.233  	pkgs = package_set->packages.data;
   1.234  	if (tp->state == RAZOR_PACKAGE_INSTALL)
   1.235 -		bitarray_set(uppkgs, package - pkgs, 1);
   1.236 +		bitarray_set(&trans->uppkgs, package - pkgs, 1);
   1.237  	else if (tp->state == RAZOR_PACKAGE_REMOVE)
   1.238 -		bitarray_set(uppkgs, package - pkgs, 0);
   1.239 +		bitarray_set(&trans->syspkgs, package - pkgs, 0);
   1.240  	else
   1.241  		trans->errors++;
   1.242  }
   1.243  
   1.244  /* FIXME */
   1.245  static int
   1.246 -prop_belongs_to_uppkgs(struct razor_set *set,
   1.247 -		       struct razor_property *prop,
   1.248 -		       struct bitarray *uppkgs)
   1.249 +prop_is_being_installed(struct razor_transaction_resolver *trans,
   1.250 +			struct razor_property *prop)
   1.251  {
   1.252  	struct list *pkg;
   1.253  
   1.254 -	for (pkg = list_first(&prop->packages, &set->package_pool); pkg; pkg = list_next(pkg)) {
   1.255 -		if (bitarray_get(uppkgs, pkg->data))
   1.256 +	for (pkg = list_first(&prop->packages, &trans->upstream->package_pool); pkg; pkg = list_next(pkg)) {
   1.257 +		if (bitarray_get(&trans->uppkgs, pkg->data))
   1.258  			return 1;
   1.259  	}
   1.260  	return 0;
   1.261  }
   1.262  
   1.263  static void
   1.264 -razor_transaction_satisfy_installs(struct razor_transaction *trans,
   1.265 -				   struct bitarray *syspkgs,
   1.266 -				   struct bitarray *uppkgs,
   1.267 -				   struct array *package_array)
   1.268 +razor_transaction_satisfy_installs(struct razor_transaction_resolver *trans)
   1.269  {
   1.270  	struct razor_package *spkgs, *upkgs, *pkg;
   1.271  	struct razor_property *sprops, *uprops;
   1.272 @@ -2059,7 +2064,7 @@
   1.273  		 */
   1.274  		while (up < ucount &&
   1.275  		       (uprops[up].type == RAZOR_PROPERTY_PROVIDES ||
   1.276 -			!prop_belongs_to_uppkgs(trans->upstream, &uprops[up], uppkgs)))
   1.277 +			!prop_is_being_installed(trans, &uprops[up])))
   1.278  			up++;
   1.279  		if (up == ucount)
   1.280  			break;
   1.281 @@ -2069,10 +2074,10 @@
   1.282  			if (!strncmp(&upool[uprops[up].name], "rpmlib(", 7))
   1.283  				break;
   1.284  
   1.285 -			if (find_system_provider(trans, syspkgs, 1, 0, &uprops[up], &sp) ||
   1.286 -			    find_upstream_provider(trans, uppkgs, 1, 0, &uprops[up], up) ||
   1.287 -			    find_system_file(trans, syspkgs, 1, up) ||
   1.288 -			    find_upstream_file(trans, uppkgs, 1, up)) {
   1.289 +			if (find_system_provider(trans, 1, 0, &uprops[up], &sp) ||
   1.290 +			    find_upstream_provider(trans, 1, 0, &uprops[up], up) ||
   1.291 +			    find_system_file(trans, 1, up) ||
   1.292 +			    find_upstream_file(trans, 1, up)) {
   1.293  				/* Requires something that is either installed
   1.294  				 * or to-be-installed.
   1.295  				 */
   1.296 @@ -2080,61 +2085,54 @@
   1.297  			}
   1.298  
   1.299  			/* See if we can install a new upstream provider */
   1.300 -			pkg = find_upstream_provider(trans, uppkgs, 0, 0, &uprops[up], up);
   1.301 +			pkg = find_upstream_provider(trans, 0, 0, &uprops[up], up);
   1.302  			if (!pkg)
   1.303 -				pkg = find_upstream_file(trans, uppkgs, 0, up);
   1.304 -			add_transaction_package(trans, syspkgs, uppkgs,
   1.305 -						package_array,
   1.306 -						pkg, trans->upstream,
   1.307 +				pkg = find_upstream_file(trans, 0, up);
   1.308 +			add_transaction_package(trans, pkg, trans->upstream,
   1.309  						RAZOR_PACKAGE_INSTALL,
   1.310  						&uprops[up], trans->upstream);
   1.311  			break;
   1.312  
   1.313  		case RAZOR_PROPERTY_CONFLICTS:
   1.314 -			if ((pkg = find_system_provider(trans, syspkgs, 1, 1, &uprops[up], &sp))) {
   1.315 +			if ((pkg = find_system_provider(trans, 1, 1, &uprops[up], &sp))) {
   1.316  				struct razor_package *upgrade;
   1.317  
   1.318  				/* Conflicts with something already installed.
   1.319  				 * Try to upgrade out.
   1.320  				 */
   1.321 -				upgrade = find_upgrade(trans, uppkgs, &uprops[up], up);
   1.322 +				upgrade = find_upgrade(trans, &uprops[up], up);
   1.323  				if (upgrade) {
   1.324 -					bitarray_set(syspkgs, pkg - spkgs, 0);
   1.325 -					add_transaction_package(trans, syspkgs, uppkgs,
   1.326 -								package_array,
   1.327 -								upgrade, trans->upstream,
   1.328 +					bitarray_set(&trans->syspkgs, pkg - spkgs, 0);
   1.329 +					add_transaction_package(trans, upgrade,
   1.330 +								trans->upstream,
   1.331  								RAZOR_PACKAGE_INSTALL,
   1.332  								&uprops[up], trans->upstream);
   1.333  				} else {
   1.334 -					add_transaction_package(trans, syspkgs, uppkgs,
   1.335 -								package_array,
   1.336 -								pkg, trans->system, 
   1.337 +					add_transaction_package(trans, pkg,
   1.338 +								trans->system, 
   1.339  								RAZOR_PACKAGE_INSTALL_CONFLICT,
   1.340  								&uprops[up], trans->upstream);
   1.341  				}
   1.342 -			} else if ((pkg = find_upstream_provider(trans, uppkgs, 1, 1, &uprops[up], up))) {
   1.343 +			} else if ((pkg = find_upstream_provider(trans, 1, 1, &uprops[up], up))) {
   1.344  				/* Conflicts with something already to-be-installed */
   1.345 -				add_transaction_package(trans, syspkgs, uppkgs,
   1.346 -							package_array,
   1.347 -							pkg, trans->upstream, 
   1.348 +				add_transaction_package(trans, pkg,
   1.349 +							trans->upstream, 
   1.350  							RAZOR_PACKAGE_INSTALL_CONFLICT,
   1.351  							&uprops[up], trans->upstream);
   1.352  			}
   1.353  			break;
   1.354  
   1.355  		case RAZOR_PROPERTY_OBSOLETES:
   1.356 -			if ((pkg = find_system_provider(trans, syspkgs, 1, 1, &uprops[up], &sp))) {
   1.357 +			if ((pkg = find_system_provider(trans, 1, 1, &uprops[up], &sp))) {
   1.358  				/* Obsoletes something installed */
   1.359 -				add_transaction_package(trans, syspkgs, uppkgs,
   1.360 -							package_array,
   1.361 -							pkg, trans->system, 
   1.362 +				add_transaction_package(trans, pkg,
   1.363 +							trans->system, 
   1.364  							RAZOR_PACKAGE_REMOVE,
   1.365  							&uprops[up], trans->upstream);
   1.366 -			} else if ((pkg = find_upstream_provider(trans, uppkgs, 1, 1, &uprops[up], up))) {
   1.367 +			} else if ((pkg = find_upstream_provider(trans, 1, 1, &uprops[up], up))) {
   1.368  				/* Obsoletes something that was to-be-installed */
   1.369 -				add_transaction_package(trans, syspkgs, uppkgs,
   1.370 -							package_array,
   1.371 -							pkg, trans->upstream, 
   1.372 +				add_transaction_package(trans, pkg,
   1.373 +							trans->upstream, 
   1.374  							RAZOR_PACKAGE_REMOVE_CONFLICT,
   1.375  							&uprops[up], trans->upstream);
   1.376  			}
   1.377 @@ -2190,8 +2188,7 @@
   1.378  }
   1.379  
   1.380  static void
   1.381 -lose_required_package(struct razor_transaction *trans, struct bitarray *syspkgs,
   1.382 -		      struct array *package_array,
   1.383 +lose_required_package(struct razor_transaction_resolver *trans,
   1.384  		      struct razor_property *req,
   1.385  		      struct list_head *lost_package_list)
   1.386  {
   1.387 @@ -2205,13 +2202,13 @@
   1.388  	lost_package = &pkgs[list_first(lost_package_list, &trans->system->package_pool)->data];
   1.389  
   1.390  	for (p = list_first(&req->packages, &trans->system->package_pool); p; p = list_next(p)) {
   1.391 -		packages = package_array->data;
   1.392 -		already = find_transaction_package(package_array, &pkgs[p->data]);
   1.393 +		packages = trans->packages.data;
   1.394 +		already = find_transaction_package(&trans->packages, &pkgs[p->data]);
   1.395  		if (already != -1 &&
   1.396  		    (packages[already].state & RAZOR_PACKAGE_REMOVE))
   1.397  			continue;
   1.398  
   1.399 -		tp = array_add(package_array, sizeof *tp);
   1.400 +		tp = array_add(&trans->packages, sizeof *tp);
   1.401  		memset(tp, 0, sizeof *tp);
   1.402  		tp->package = &pkgs[p->data];
   1.403  		tp->name = &pool[tp->package->name];
   1.404 @@ -2226,14 +2223,13 @@
   1.405  			trans->errors++;
   1.406  		} else {
   1.407  			tp->state = RAZOR_PACKAGE_REMOVE;
   1.408 -			bitarray_set(syspkgs, p->data, 0);
   1.409 +			bitarray_set(&trans->syspkgs, p->data, 0);
   1.410  		}
   1.411  	}
   1.412  }
   1.413  
   1.414  static void
   1.415 -lose_requirement(struct razor_transaction *trans, struct bitarray *syspkgs,
   1.416 -		 struct array *package_array,
   1.417 +lose_requirement(struct razor_transaction_resolver *trans,
   1.418  		 struct razor_property *req,
   1.419  		 struct razor_property *lost_provider,
   1.420  		 struct razor_property *first_provider)
   1.421 @@ -2254,14 +2250,11 @@
   1.422  			return;
   1.423  	}
   1.424  
   1.425 -	lose_required_package(trans, syspkgs, package_array, req,
   1.426 -			      &lost_provider->packages);
   1.427 +	lose_required_package(trans, req, &lost_provider->packages);
   1.428  }
   1.429  
   1.430  static void
   1.431 -razor_transaction_satisfy_removes(struct razor_transaction *trans,
   1.432 -				  struct bitarray *syspkgs,
   1.433 -				  struct array *package_array,
   1.434 +razor_transaction_satisfy_removes(struct razor_transaction_resolver *trans,
   1.435  				  int start, int end)
   1.436  {
   1.437  	struct razor_transaction_package *packages;
   1.438 @@ -2282,7 +2275,7 @@
   1.439  	array_init(&lost_files);
   1.440  	array_init(&lost_provides);
   1.441  	for (r = start; r < end; r++) {
   1.442 -		packages = package_array->data;
   1.443 +		packages = trans->packages.data;
   1.444  		if (packages[r].state != RAZOR_PACKAGE_REMOVE)
   1.445  			continue;
   1.446  
   1.447 @@ -2301,8 +2294,8 @@
   1.448  		first_provider = req + 1;
   1.449  
   1.450  		while (req > props && req->name == props[*lost].name) {
   1.451 -			lose_requirement(trans, syspkgs, package_array, req,
   1.452 -					 &props[*lost], first_provider);
   1.453 +			lose_requirement(trans, req, &props[*lost],
   1.454 +					 first_provider);
   1.455  			req--;
   1.456  		}
   1.457  	}
   1.458 @@ -2332,8 +2325,7 @@
   1.459  		if (lostf == lostf_end)
   1.460  			continue;
   1.461  
   1.462 -		lose_required_package(trans, syspkgs, package_array, req,
   1.463 -				      &(entry)->packages);
   1.464 +		lose_required_package(trans, req, &entry->packages);
   1.465  	}
   1.466  	array_release(&lost_files);
   1.467  }
   1.468 @@ -2389,54 +2381,48 @@
   1.469  			 int update_count, const char **update_packages,
   1.470  			 int remove_count, const char **remove_packages)
   1.471  {
   1.472 -	struct razor_transaction *trans;
   1.473 -	struct array package_array;
   1.474 -	struct razor_package *spkgs, *upkgs;
   1.475 -	struct bitarray syspkgs, uppkgs;
   1.476 +	struct razor_transaction_resolver trans;
   1.477 +	struct razor_transaction *ret_trans;
   1.478  	int start, end;
   1.479  
   1.480 -	trans = zalloc(sizeof *trans);
   1.481 -	trans->system = system;
   1.482 -	spkgs = trans->system->packages.data;
   1.483 -	trans->upstream = upstream ? upstream : razor_set_create();
   1.484 -	upkgs = trans->upstream->packages.data;
   1.485 -	array_init(&package_array);
   1.486 -	bitarray_init(&syspkgs, trans->system->packages.size / sizeof (struct razor_package), 1);
   1.487 -	bitarray_init(&uppkgs, trans->upstream->packages.size / sizeof (struct razor_package), 0);
   1.488 +	trans.system = system;
   1.489 +	trans.upstream = upstream ? upstream : razor_set_create();
   1.490 +	array_init(&trans.packages);
   1.491 +	bitarray_init(&trans.syspkgs, trans.system->packages.size / sizeof (struct razor_package), 1);
   1.492 +	bitarray_init(&trans.uppkgs, trans.upstream->packages.size / sizeof (struct razor_package), 0);
   1.493 +	trans.errors = 0;
   1.494  
   1.495  	/* Find initial upstream packages to be installed */
   1.496  	if (update_count > 0) {
   1.497 -		trans->errors +=
   1.498 -			find_packages(upstream, update_count, update_packages,
   1.499 -				      &package_array, &uppkgs,
   1.500 -				      RAZOR_PACKAGE_INSTALL);
   1.501 +		find_packages(&trans, update_count, update_packages,
   1.502 +			      RAZOR_PACKAGE_INSTALL);
   1.503  	} else if (remove_count == 0)
   1.504 -		find_all_packages(system, upstream, &package_array, &uppkgs);
   1.505 +		find_all_packages(&trans);
   1.506  
   1.507  	/* Find initial installed packages to remove. */
   1.508  	if (remove_count > 0) {
   1.509 -		trans->errors +=
   1.510 -			find_packages(system, remove_count, remove_packages,
   1.511 -				      &package_array, &syspkgs,
   1.512 -				      RAZOR_PACKAGE_REMOVE);
   1.513 +		find_packages(&trans, remove_count, remove_packages,
   1.514 +			      RAZOR_PACKAGE_REMOVE);
   1.515  	}
   1.516  
   1.517  	start = 0;
   1.518 -	end = package_array.size / sizeof (struct razor_transaction_package);
   1.519 +	end = trans.packages.size / sizeof (struct razor_transaction_package);
   1.520  
   1.521 -	while (!trans->errors && start != end) {
   1.522 -		razor_transaction_satisfy_installs(trans, &syspkgs, &uppkgs,
   1.523 -						   &package_array);
   1.524 -		razor_transaction_satisfy_removes(trans, &syspkgs,
   1.525 -						  &package_array, start, end);
   1.526 +	while (!trans.errors && start != end) {
   1.527 +		razor_transaction_satisfy_installs(&trans);
   1.528 +		razor_transaction_satisfy_removes(&trans, start, end);
   1.529  
   1.530  		start = end;
   1.531 -		end = package_array.size / sizeof (struct razor_transaction_package);
   1.532 +		end = trans.packages.size / sizeof (struct razor_transaction_package);
   1.533  	}
   1.534  
   1.535 -	trans->packages = package_array.data;
   1.536 -	trans->package_count = end;
   1.537 -	return trans;
   1.538 +	ret_trans = zalloc(sizeof *ret_trans);
   1.539 +	ret_trans->system = trans.system;
   1.540 +	ret_trans->upstream = trans.upstream;
   1.541 +	ret_trans->packages = trans.packages.data;
   1.542 +	ret_trans->package_count = end;
   1.543 +	ret_trans->errors = trans.errors;
   1.544 +	return ret_trans;
   1.545  }
   1.546  
   1.547  const char * const razor_version_relations[] = {