1.1 --- a/razor.c Wed Feb 20 16:54:03 2008 -0500
1.2 +++ b/razor.c Thu Feb 21 12:09:13 2008 -0500
1.3 @@ -676,7 +676,7 @@
1.4 e = array_add(&importer->set->files, sizeof *e);
1.5 e->name = root.name;
1.6 e->flags = RAZOR_ENTRY_LAST;
1.7 - e->start = 1;
1.8 + e->start = importer->files.size ? 1 : 0;
1.9 list_set_empty(&e->packages);
1.10
1.11 serialize_files(importer->set, &root, &importer->set->files);
1.12 @@ -1093,12 +1093,10 @@
1.13 if (r->type != RAZOR_PROPERTY_REQUIRES)
1.14 continue;
1.15
1.16 - if (r->name != p->name) {
1.17 - p = r;
1.18 - while (p < end && p->name == r->name &&
1.19 - p->type == r->type)
1.20 - p++;
1.21 - }
1.22 + p = r;
1.23 + while (p < end && p->name == r->name &&
1.24 + p->type == r->type)
1.25 + p++;
1.26
1.27 /* If there is more than one version of a provides,
1.28 * seek to the end for the highest version. */
1.29 @@ -1396,6 +1394,7 @@
1.30 return e - (struct razor_entry *)merger->set->files.data;
1.31 }
1.32
1.33 +/* FIXME. Blah */
1.34 static int
1.35 fix_file_map(uint32_t *map,
1.36 struct razor_entry *files,
1.37 @@ -1534,22 +1533,31 @@
1.38 static void
1.39 merge_files(struct razor_merger *merger)
1.40 {
1.41 - struct razor_entry *root1, *root2;
1.42 + struct razor_entry *root;
1.43 struct merge_directory md;
1.44 uint32_t *map1, *map2;
1.45
1.46 map1 = merger->source1.file_map;
1.47 map2 = merger->source2.file_map;
1.48 - root1 = (struct razor_entry *) merger->source1.set->files.data;
1.49 - root2 = (struct razor_entry *) merger->source2.set->files.data;
1.50 -
1.51 - /* FIXME. Blah */
1.52 - fix_file_map(map1, root1, root1);
1.53 - fix_file_map(map2, root2, root2);
1.54
1.55 md.merged = add_file(merger, "");
1.56 - md.dir1 = root1->start;
1.57 - md.dir2 = root2->start;
1.58 +
1.59 + if (merger->source1.set->files.size) {
1.60 + root = (struct razor_entry *) merger->source1.set->files.data;
1.61 + if (root->start)
1.62 + fix_file_map(map1, root, root);
1.63 + md.dir1 = root->start;
1.64 + } else
1.65 + md.dir1 = 0;
1.66 +
1.67 + if (merger->source2.set->files.size) {
1.68 + root = (struct razor_entry *) merger->source2.set->files.data;
1.69 + if (root->start)
1.70 + fix_file_map(map2, root, root);
1.71 + md.dir2 = root->start;
1.72 + } else
1.73 + md.dir2 = 0;
1.74 +
1.75 merge_one_directory(merger, &md);
1.76 }
1.77
1.78 @@ -1644,35 +1652,8 @@
1.79 razor_merger_finish(struct razor_merger *merger)
1.80 {
1.81 struct razor_set *result;
1.82 -
1.83 - result = merger->set;
1.84 - hashtable_release(&merger->table);
1.85 - free(merger);
1.86 -
1.87 - return result;
1.88 -}
1.89 -
1.90 -/* Add packages from 'upstream' to 'set'. The packages to add are
1.91 - * specified by the 'packages' array, which is a sorted list of
1.92 - * package indexes. Returns a newly allocated package set. Does not
1.93 - * enforce validity of the resulting package set.
1.94 - *
1.95 - * This looks more complicated than it is. An easy way to merge two
1.96 - * package sets would be to just use a razor_importer, but that
1.97 - * requires resorting, and is thus O(n log n). We can do this in a
1.98 - * linear sweep, but it gets a little more complicated.
1.99 - */
1.100 -struct razor_set *
1.101 -razor_set_add(struct razor_set *set, struct razor_set *upstream,
1.102 - struct array *packages)
1.103 -{
1.104 - struct razor_merger *merger;
1.105 struct razor_package *p, *pend;
1.106
1.107 - merger = razor_merger_create(set, upstream);
1.108 -
1.109 - merge_packages(merger, packages);
1.110 -
1.111 /* As we built the package list, we filled out a bitvector of
1.112 * the properties that are referenced by the packages in the
1.113 * new set. Now we do a parallel loop through the properties
1.114 @@ -1710,6 +1691,33 @@
1.115 rebuild_property_package_lists(merger->set);
1.116 rebuild_file_package_lists(merger->set);
1.117
1.118 + result = merger->set;
1.119 + hashtable_release(&merger->table);
1.120 + free(merger);
1.121 +
1.122 + return result;
1.123 +}
1.124 +
1.125 +/* Add packages from 'upstream' to 'set'. The packages to add are
1.126 + * specified by the 'packages' array, which is a sorted list of
1.127 + * package indexes. Returns a newly allocated package set. Does not
1.128 + * enforce validity of the resulting package set.
1.129 + *
1.130 + * This looks more complicated than it is. An easy way to merge two
1.131 + * package sets would be to just use a razor_importer, but that
1.132 + * requires resorting, and is thus O(n log n). We can do this in a
1.133 + * linear sweep, but it gets a little more complicated.
1.134 + */
1.135 +struct razor_set *
1.136 +razor_set_add(struct razor_set *set, struct razor_set *upstream,
1.137 + struct array *packages)
1.138 +{
1.139 + struct razor_merger *merger;
1.140 +
1.141 + merger = razor_merger_create(set, upstream);
1.142 +
1.143 + merge_packages(merger, packages);
1.144 +
1.145 return razor_merger_finish(merger);
1.146 }
1.147
1.148 @@ -1839,6 +1847,108 @@
1.149 return set;
1.150 }
1.151
1.152 +static struct razor_set *
1.153 +razor_set_remove_internal(struct razor_set *set, struct array *list,
1.154 + struct array *unsatisfied)
1.155 +{
1.156 + struct razor_set *empty, *new;
1.157 + struct razor_merger *merger;
1.158 + struct razor_package *pkgs;
1.159 + int pkg_count, remove_count, p, r;
1.160 + struct array unsatisfied_before;
1.161 + uint32_t *u, *uend, *ub, *ubend;
1.162 + struct razor_property *props, *propsb;
1.163 + char *pool, *poolb;
1.164 +
1.165 + array_init(&unsatisfied_before);
1.166 + razor_set_validate(set, &unsatisfied_before);
1.167 +
1.168 + empty = razor_set_create();
1.169 + merger = razor_merger_create(set, empty);
1.170 +
1.171 + remove_count = list->size / sizeof (uint32_t);
1.172 + pkg_count = set->packages.size / sizeof (struct razor_package);
1.173 + pkgs = set->packages.data;
1.174 +
1.175 + for (p = 0; p < pkg_count; p++) {
1.176 + for (r = 0; r < remove_count; r++) {
1.177 + if (p == ((uint32_t *)list->data)[r])
1.178 + goto skip;
1.179 + }
1.180 +
1.181 + add_package(merger, &pkgs[p], &merger->source1, 0);
1.182 + skip:
1.183 + ;
1.184 + }
1.185 +
1.186 + new = razor_merger_finish(merger);
1.187 +
1.188 + razor_set_validate(new, unsatisfied);
1.189 +
1.190 + ubend = unsatisfied_before.data + unsatisfied_before.size;
1.191 + uend = unsatisfied->data + unsatisfied->size;
1.192 + props = new->properties.data;
1.193 + propsb = set->properties.data;
1.194 + pool = new->string_pool.data;
1.195 + poolb = set->string_pool.data;
1.196 +
1.197 + for (u = unsatisfied->data; u < uend; u++) {
1.198 + for (ub = unsatisfied_before.data; ub < ubend; ub++) {
1.199 + if (!strcmp (&pool[props[*u].name],
1.200 + &poolb[propsb[*ub].name]) &&
1.201 + props[*u].relation == propsb[*ub].relation &&
1.202 + !strcmp (&pool[props[*u].version],
1.203 + &poolb[propsb[*ub].version])) {
1.204 + *(u--) = *(--uend);
1.205 + break;
1.206 + }
1.207 + }
1.208 + }
1.209 +
1.210 + unsatisfied->size = (void *)uend - unsatisfied->data;
1.211 + return new;
1.212 +}
1.213 +
1.214 +struct razor_set *
1.215 +razor_set_remove(struct razor_set *set, int count, const char **packages)
1.216 +{
1.217 + struct razor_set *new;
1.218 + struct array list, unsatisfied;
1.219 + struct razor_property *props;
1.220 + uint32_t *u, *uend, *p;
1.221 + struct list *r;
1.222 +
1.223 + array_init(&list);
1.224 + find_packages(set, count, packages, &list);
1.225 +
1.226 + while (list.size > 0) {
1.227 + array_init(&unsatisfied);
1.228 + new = razor_set_remove_internal(set, &list, &unsatisfied);
1.229 + array_release(&list);
1.230 + razor_set_destroy(set);
1.231 + set = new;
1.232 +
1.233 + props = set->properties.data;
1.234 + array_init(&list);
1.235 + uend = unsatisfied.data + unsatisfied.size;
1.236 + for (u = unsatisfied.data; u < uend; u++) {
1.237 + if (props[*u].type == RAZOR_PROPERTY_REQUIRES) {
1.238 + r = list_first(&props[*u].packages, &set->package_pool);
1.239 + while (r) {
1.240 + p = array_add(&list, sizeof *p);
1.241 + *p = r->data;
1.242 + r = list_next(r);
1.243 + }
1.244 + }
1.245 + }
1.246 +
1.247 + array_release(&unsatisfied);
1.248 + }
1.249 +
1.250 + array_release(&list);
1.251 + return set;
1.252 +}
1.253 +
1.254 /* The diff order matters. We should sort the packages so that a
1.255 * REMOVE of a package comes before the INSTALL, and so that all
1.256 * requires for a package have been installed before the package.