1.1 --- a/razor.c Sun Nov 11 14:57:42 2007 -0500
1.2 +++ b/razor.c Tue Nov 13 01:30:09 2007 -0500
1.3 @@ -407,18 +407,24 @@
1.4 }
1.5
1.6 static unsigned long
1.7 -razor_importer_tokenize(struct razor_importer *importer, const char *string)
1.8 +hashtable_tokenize(struct hashtable *table, const char *string)
1.9 {
1.10 unsigned long token;
1.11
1.12 if (string == NULL)
1.13 string = "";
1.14
1.15 - token = hashtable_lookup(&importer->table, string);
1.16 + token = hashtable_lookup(table, string);
1.17 if (token != 0)
1.18 return token;
1.19
1.20 - return hashtable_insert(&importer->table, string);
1.21 + return hashtable_insert(table, string);
1.22 +}
1.23 +
1.24 +static unsigned long
1.25 +razor_importer_tokenize(struct razor_importer *importer, const char *string)
1.26 +{
1.27 + return hashtable_tokenize(&importer->table, string);
1.28 }
1.29
1.30 void
1.31 @@ -1357,21 +1363,39 @@
1.32 unsigned long *property_map;
1.33 };
1.34
1.35 -static void
1.36 -prepare_source(struct source *source, struct razor_set *set)
1.37 +struct razor_merger {
1.38 + struct razor_set *set;
1.39 + struct hashtable table;
1.40 + struct source source1;
1.41 + struct source source2;
1.42 +};
1.43 +
1.44 +static struct razor_merger *
1.45 +razor_merger_create(struct razor_set *set1, struct razor_set *set2)
1.46 {
1.47 + struct razor_merger *merger;
1.48 int count;
1.49 size_t size;
1.50
1.51 - source->set = set;
1.52 + merger = zalloc(sizeof *merger);
1.53 + merger->set = razor_set_create();
1.54 + hashtable_init(&merger->table, &merger->set->string_pool);
1.55
1.56 - count = set->properties.size / sizeof (struct razor_property);
1.57 - size = count * sizeof *source->property_map;
1.58 - source->property_map = zalloc(size);
1.59 + count = set1->properties.size / sizeof (struct razor_property);
1.60 + size = count * sizeof merger->source1.property_map[0];
1.61 + merger->source1.property_map = zalloc(size);
1.62 + merger->source1.set = set1;
1.63 +
1.64 + count = set2->properties.size / sizeof (struct razor_property);
1.65 + size = count * sizeof merger->source2.property_map[0];
1.66 + merger->source2.property_map = zalloc(size);
1.67 + merger->source2.set = set2;
1.68 +
1.69 + return merger;
1.70 }
1.71
1.72 static void
1.73 -add_package(struct razor_importer *importer,
1.74 +add_package(struct razor_merger *merger,
1.75 struct razor_package *package, struct source *source,
1.76 unsigned long flags)
1.77 {
1.78 @@ -1380,11 +1404,11 @@
1.79 struct razor_package *p;
1.80
1.81 pool = source->set->string_pool.data;
1.82 - p = array_add(&importer->set->packages, sizeof *p);
1.83 - p->name = razor_importer_tokenize(importer, &pool[package->name]);
1.84 + p = array_add(&merger->set->packages, sizeof *p);
1.85 + p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
1.86 p->name |= flags;
1.87 - p->version = razor_importer_tokenize(importer,
1.88 - &pool[package->version]);
1.89 + p->version = hashtable_tokenize(&merger->table,
1.90 + &pool[package->version]);
1.91 p->properties = package->properties;
1.92
1.93 if (package->properties & RAZOR_IMMEDIATE)
1.94 @@ -1401,18 +1425,18 @@
1.95
1.96
1.97 /* Build the new package list sorted by merging the two package lists.
1.98 - * Build new string pool as we go. (for now we just re-use that part of
1.99 - * the importer). */
1.100 + * Build new string pool as we go. */
1.101 static void
1.102 -merge_packages(struct razor_importer *importer,
1.103 - struct source *source1, struct source *source2,
1.104 - struct array *packages)
1.105 +merge_packages(struct razor_merger *merger, struct array *packages)
1.106 {
1.107 struct razor_package *upstream_packages, *p, *s, *send;
1.108 + struct source *source1, *source2;
1.109 char *spool, *upool;
1.110 unsigned long *u, *uend;
1.111 int cmp;
1.112
1.113 + source1 = &merger->source1;
1.114 + source2 = &merger->source2;
1.115 upstream_packages = source2->set->packages.data;
1.116
1.117 u = packages->data;
1.118 @@ -1429,43 +1453,46 @@
1.119 if (u < uend)
1.120 cmp = strcmp(&spool[s->name], &upool[p->name]);
1.121 if (u >= uend || cmp < 0) {
1.122 - add_package(importer, s, source1, 0);
1.123 + add_package(merger, s, source1, 0);
1.124 s++;
1.125 } else if (cmp == 0) {
1.126 - add_package(importer, p, source2, UPSTREAM_SOURCE);
1.127 + add_package(merger, p, source2, UPSTREAM_SOURCE);
1.128 s++;
1.129 u++;
1.130 } else {
1.131 - add_package(importer, p, source2, UPSTREAM_SOURCE);
1.132 + add_package(merger, p, source2, UPSTREAM_SOURCE);
1.133 u++;
1.134 }
1.135 }
1.136 }
1.137
1.138 static unsigned long
1.139 -add_property(struct razor_importer *importer,
1.140 +add_property(struct razor_merger *merger,
1.141 const char *name, const char *version, int type)
1.142 {
1.143 struct razor_property *p;
1.144
1.145 - p = array_add(&importer->set->properties, sizeof *p);
1.146 - p->name = razor_importer_tokenize(importer, name) | (type << 30);
1.147 - p->version = razor_importer_tokenize(importer, version);
1.148 + p = array_add(&merger->set->properties, sizeof *p);
1.149 + p->name = hashtable_tokenize(&merger->table, name) | (type << 30);
1.150 + p->version = hashtable_tokenize(&merger->table, version);
1.151
1.152 - return p - (struct razor_property *) importer->set->properties.data;
1.153 + return p - (struct razor_property *) merger->set->properties.data;
1.154 }
1.155
1.156 static void
1.157 -merge_properties(struct razor_importer *importer,
1.158 - struct razor_set *set1,
1.159 - unsigned long *map1,
1.160 - struct razor_set *set2,
1.161 - unsigned long *map2)
1.162 +merge_properties(struct razor_merger *merger)
1.163 {
1.164 struct razor_property *p1, *p2;
1.165 + struct razor_set *set1, *set2;
1.166 + unsigned long *map1, *map2;
1.167 int i, j, cmp, count1, count2;
1.168 char *pool1, *pool2;
1.169
1.170 + set1 = merger->source1.set;
1.171 + set2 = merger->source2.set;
1.172 + map1 = merger->source1.property_map;
1.173 + map2 = merger->source2.property_map;
1.174 +
1.175 i = 0;
1.176 j = 0;
1.177 pool1 = set1->string_pool.data;
1.178 @@ -1495,17 +1522,17 @@
1.179 cmp = versioncmp(&pool1[p1->version],
1.180 &pool2[p2->version]);
1.181 if (cmp < 0) {
1.182 - map1[i++] = add_property(importer,
1.183 + map1[i++] = add_property(merger,
1.184 &pool1[p1->name & RAZOR_ENTRY_MASK],
1.185 &pool1[p1->version],
1.186 (p1->name >> 30));
1.187 } else if (cmp > 0) {
1.188 - map2[j++] = add_property(importer,
1.189 + map2[j++] = add_property(merger,
1.190 &pool2[p2->name & RAZOR_ENTRY_MASK],
1.191 &pool2[p2->version],
1.192 (p2->name >> 30));
1.193 } else {
1.194 - map1[i++] = map2[j++] = add_property(importer,
1.195 + map1[i++] = map2[j++] = add_property(merger,
1.196 &pool1[p1->name & RAZOR_ENTRY_MASK],
1.197 &pool1[p1->version],
1.198 (p1->name >> 30));
1.199 @@ -1573,6 +1600,18 @@
1.200 free(pkgs);
1.201 }
1.202
1.203 +struct razor_set *
1.204 +razor_merger_finish(struct razor_merger *merger)
1.205 +{
1.206 + struct razor_set *result;
1.207 +
1.208 + result = merger->set;
1.209 + hashtable_release(&merger->table);
1.210 + free(merger);
1.211 +
1.212 + return result;
1.213 +}
1.214 +
1.215 /* Add packages from 'upstream' to 'set'. The packages to add are
1.216 * specified by the 'packages' array, which is a sorted list of
1.217 * package indexes. Returns a newly allocated package set. Does not
1.218 @@ -1587,17 +1626,12 @@
1.219 razor_set_add(struct razor_set *set, struct razor_set *upstream,
1.220 struct array *packages)
1.221 {
1.222 - struct razor_set *result;
1.223 - struct razor_importer *importer;
1.224 + struct razor_merger *merger;
1.225 struct razor_package *p, *pend;
1.226 - struct source source, upstream_source;
1.227
1.228 - importer = razor_importer_new();
1.229 + merger = razor_merger_create(set, upstream);
1.230
1.231 - prepare_source(&upstream_source, upstream);
1.232 - prepare_source(&source, set);
1.233 -
1.234 - merge_packages(importer, &source, &upstream_source, packages);
1.235 + merge_packages(merger, packages);
1.236
1.237 /* As we built the package list, we filled out a bitvector of
1.238 * the properties that are referenced by the packages in the
1.239 @@ -1607,36 +1641,30 @@
1.240 * indices in the old property list to indices in the new
1.241 * property list for both sets. */
1.242
1.243 - merge_properties(importer,
1.244 - set, source.property_map,
1.245 - upstream, upstream_source.property_map);
1.246 + merge_properties(merger);
1.247
1.248 /* Now we loop through the packages again and emit the
1.249 * property lists, remapped to point to the new properties. */
1.250
1.251 - pend = importer->set->packages.data + importer->set->packages.size;
1.252 - for (p = importer->set->packages.data; p < pend; p++) {
1.253 + pend = merger->set->packages.data + merger->set->packages.size;
1.254 + for (p = merger->set->packages.data; p < pend; p++) {
1.255 struct source *src;
1.256
1.257 if (p->name & UPSTREAM_SOURCE)
1.258 - src = &upstream_source;
1.259 + src = &merger->source2;
1.260 else
1.261 - src = &source;
1.262 + src = &merger->source1;
1.263
1.264 p->properties = emit_properties(&src->set->property_pool,
1.265 p->properties,
1.266 src->property_map,
1.267 - &importer->set->property_pool);
1.268 + &merger->set->property_pool);
1.269 p->name &= INDEX_MASK;
1.270 }
1.271
1.272 - rebuild_package_lists(importer->set);
1.273 + rebuild_package_lists(merger->set);
1.274
1.275 - result = importer->set;
1.276 - hashtable_release(&importer->table);
1.277 - free(importer);
1.278 -
1.279 - return result;
1.280 + return razor_merger_finish(merger);
1.281 }
1.282
1.283 void