Break up the monolithic razor.c.
1.1 --- a/librazor/Makefile.am Fri Jun 20 14:18:52 2008 -0400
1.2 +++ b/librazor/Makefile.am Fri Jun 20 15:10:34 2008 -0400
1.3 @@ -21,11 +21,14 @@
1.4 razor-internal.h \
1.5 razor.h \
1.6 razor.c \
1.7 - razor-root.c \
1.8 - types.h \
1.9 + root.c \
1.10 types.c \
1.11 util.c \
1.12 - rpm.c
1.13 + rpm.c \
1.14 + iterator.c \
1.15 + importer.c \
1.16 + merger.c \
1.17 + transaction.c
1.18
1.19 librazor_la_LIBADD = $(ZLIB_LIBS)
1.20
2.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
2.2 +++ b/librazor/importer.c Fri Jun 20 15:10:34 2008 -0400
2.3 @@ -0,0 +1,488 @@
2.4 +/*
2.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
2.6 + * Copyright (C) 2008 Red Hat, Inc
2.7 + *
2.8 + * This program is free software; you can redistribute it and/or modify
2.9 + * it under the terms of the GNU General Public License as published by
2.10 + * the Free Software Foundation; either version 2 of the License, or
2.11 + * (at your option) any later version.
2.12 + *
2.13 + * This program is distributed in the hope that it will be useful,
2.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
2.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
2.16 + * GNU General Public License for more details.
2.17 + *
2.18 + * You should have received a copy of the GNU General Public License along
2.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
2.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
2.21 + */
2.22 +
2.23 +#define _GNU_SOURCE
2.24 +
2.25 +#include <string.h>
2.26 +#include "razor-internal.h"
2.27 +#include "razor.h"
2.28 +
2.29 +void
2.30 +razor_importer_begin_package(struct razor_importer *importer,
2.31 + const char *name,
2.32 + const char *version,
2.33 + const char *arch)
2.34 +{
2.35 + struct razor_package *p;
2.36 +
2.37 + p = array_add(&importer->set->packages, sizeof *p);
2.38 + p->name = hashtable_tokenize(&importer->table, name);
2.39 + p->flags = 0;
2.40 + p->version = hashtable_tokenize(&importer->table, version);
2.41 + p->arch = hashtable_tokenize(&importer->table, arch);
2.42 +
2.43 + importer->package = p;
2.44 + array_init(&importer->properties);
2.45 +}
2.46 +
2.47 +
2.48 +void
2.49 +razor_importer_finish_package(struct razor_importer *importer)
2.50 +{
2.51 + list_set_array(&importer->package->properties,
2.52 + &importer->set->property_pool,
2.53 + &importer->properties,
2.54 + 1);
2.55 +
2.56 + array_release(&importer->properties);
2.57 +}
2.58 +
2.59 +void
2.60 +razor_importer_add_property(struct razor_importer *importer,
2.61 + const char *name,
2.62 + uint32_t flags,
2.63 + const char *version)
2.64 +{
2.65 + struct razor_property *p;
2.66 + uint32_t *r;
2.67 +
2.68 + p = array_add(&importer->set->properties, sizeof *p);
2.69 + p->name = hashtable_tokenize(&importer->table, name);
2.70 + p->flags = flags;
2.71 + p->version = hashtable_tokenize(&importer->table, version);
2.72 + list_set_ptr(&p->packages, importer->package -
2.73 + (struct razor_package *) importer->set->packages.data);
2.74 +
2.75 + r = array_add(&importer->properties, sizeof *r);
2.76 + *r = p - (struct razor_property *) importer->set->properties.data;
2.77 +
2.78 + if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
2.79 + *name == '/') {
2.80 + r = array_add(&importer->file_requires, sizeof *r);
2.81 + *r = p->name;
2.82 + }
2.83 +}
2.84 +
2.85 +void
2.86 +razor_importer_add_file(struct razor_importer *importer, const char *name)
2.87 +{
2.88 + struct import_entry *e;
2.89 +
2.90 + e = array_add(&importer->files, sizeof *e);
2.91 +
2.92 + e->package = importer->package -
2.93 + (struct razor_package *) importer->set->packages.data;
2.94 + e->name = strdup(name);
2.95 +}
2.96 +
2.97 +struct razor_importer *
2.98 +razor_importer_new(void)
2.99 +{
2.100 + struct razor_importer *importer;
2.101 +
2.102 + importer = zalloc(sizeof *importer);
2.103 + importer->set = razor_set_create();
2.104 + hashtable_init(&importer->table, &importer->set->string_pool);
2.105 +
2.106 + return importer;
2.107 +}
2.108 +
2.109 +/* Destroy an importer without creating the set. */
2.110 +void
2.111 +razor_importer_destroy(struct razor_importer *importer)
2.112 +{
2.113 + /* FIXME: write this */
2.114 +}
2.115 +
2.116 +static int
2.117 +compare_packages(const void *p1, const void *p2, void *data)
2.118 +{
2.119 + const struct razor_package *pkg1 = p1, *pkg2 = p2;
2.120 + struct razor_set *set = data;
2.121 + char *pool = set->string_pool.data;
2.122 +
2.123 + /* FIXME: what if the flags are different? */
2.124 + if (pkg1->name == pkg2->name)
2.125 + return razor_versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
2.126 + else
2.127 + return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
2.128 +}
2.129 +
2.130 +static int
2.131 +compare_properties(const void *p1, const void *p2, void *data)
2.132 +{
2.133 + const struct razor_property *prop1 = p1, *prop2 = p2;
2.134 + struct razor_set *set = data;
2.135 + char *pool = set->string_pool.data;
2.136 +
2.137 + if (prop1->name != prop2->name)
2.138 + return strcmp(&pool[prop1->name], &pool[prop2->name]);
2.139 + else if (prop1->flags != prop2->flags)
2.140 + return prop1->flags - prop2->flags;
2.141 + else
2.142 + return razor_versioncmp(&pool[prop1->version], &pool[prop2->version]);
2.143 +}
2.144 +
2.145 +static uint32_t *
2.146 +uniqueify_properties(struct razor_set *set)
2.147 +{
2.148 + struct razor_property *rp, *up, *rp_end;
2.149 + struct array *pkgs, *p;
2.150 + struct list_head *r;
2.151 + uint32_t *map, *rmap;
2.152 + int i, count, unique;
2.153 +
2.154 + count = set->properties.size / sizeof(struct razor_property);
2.155 + map = razor_qsort_with_data(set->properties.data,
2.156 + count,
2.157 + sizeof(struct razor_property),
2.158 + compare_properties,
2.159 + set);
2.160 +
2.161 + rp_end = set->properties.data + set->properties.size;
2.162 + rmap = malloc(count * sizeof *map);
2.163 + pkgs = zalloc(count * sizeof *pkgs);
2.164 + for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
2.165 + if (rp->name != up->name ||
2.166 + rp->flags != up->flags ||
2.167 + rp->version != up->version) {
2.168 + up++;
2.169 + up->name = rp->name;
2.170 + up->flags = rp->flags;
2.171 + up->version = rp->version;
2.172 + }
2.173 +
2.174 + unique = up - (struct razor_property *) set->properties.data;
2.175 + rmap[map[i]] = unique;
2.176 + r = array_add(&pkgs[unique], sizeof *r);
2.177 + *r = rp->packages;
2.178 + }
2.179 + free(map);
2.180 +
2.181 + if (up != rp)
2.182 + up++;
2.183 + set->properties.size = (void *) up - set->properties.data;
2.184 + rp_end = up;
2.185 + for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
2.186 + list_set_array(&rp->packages, &set->package_pool, p, 0);
2.187 + array_release(p);
2.188 + }
2.189 +
2.190 + free(pkgs);
2.191 +
2.192 + return rmap;
2.193 +}
2.194 +
2.195 +static int
2.196 +compare_filenames(const void *p1, const void *p2, void *data)
2.197 +{
2.198 + const struct import_entry *e1 = p1;
2.199 + const struct import_entry *e2 = p2;
2.200 + const char *n1 = e1->name;
2.201 + const char *n2 = e2->name;
2.202 +
2.203 + /* Need to make sure that the contents of a directory
2.204 + * are sorted immediately after it. So "foo/bar" has to
2.205 + * sort before "foo.conf"
2.206 + *
2.207 + * FIXME: this is about 60% slower than strcmp
2.208 + */
2.209 + while (*n1 && *n2) {
2.210 + if (*n1 < *n2)
2.211 + return *n2 == '/' ? 1 : -1;
2.212 + else if (*n1 > *n2)
2.213 + return *n1 == '/' ? -1 : 1;
2.214 + n1++;
2.215 + n2++;
2.216 + }
2.217 + if (*n1)
2.218 + return 1;
2.219 + else if (*n2)
2.220 + return -1;
2.221 + else
2.222 + return 0;
2.223 +}
2.224 +
2.225 +static void
2.226 +count_entries(struct import_directory *d)
2.227 +{
2.228 + struct import_directory *p, *end;
2.229 +
2.230 + p = d->files.data;
2.231 + end = d->files.data + d->files.size;
2.232 + d->count = 0;
2.233 + while (p < end) {
2.234 + count_entries(p);
2.235 + d->count += p->count + 1;
2.236 + p++;
2.237 + }
2.238 +}
2.239 +
2.240 +static void
2.241 +serialize_files(struct razor_set *set,
2.242 + struct import_directory *d, struct array *array)
2.243 +{
2.244 + struct import_directory *p, *end;
2.245 + struct razor_entry *e = NULL;
2.246 + uint32_t s;
2.247 +
2.248 + p = d->files.data;
2.249 + end = d->files.data + d->files.size;
2.250 + s = array->size / sizeof *e + d->files.size / sizeof *p;
2.251 + while (p < end) {
2.252 + e = array_add(array, sizeof *e);
2.253 + e->name = p->name;
2.254 + e->flags = 0;
2.255 + e->start = p->count > 0 ? s : 0;
2.256 + s += p->count;
2.257 +
2.258 + list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
2.259 + array_release(&p->packages);
2.260 + p++;
2.261 + }
2.262 + if (e != NULL)
2.263 + e->flags |= RAZOR_ENTRY_LAST;
2.264 +
2.265 + p = d->files.data;
2.266 + end = d->files.data + d->files.size;
2.267 + while (p < end) {
2.268 + serialize_files(set, p, array);
2.269 + p++;
2.270 + }
2.271 +}
2.272 +
2.273 +static void
2.274 +remap_property_package_links(struct array *properties, uint32_t *rmap)
2.275 +{
2.276 + struct razor_property *p, *end;
2.277 +
2.278 + end = properties->data + properties->size;
2.279 + for (p = properties->data; p < end; p++)
2.280 + list_remap_head(&p->packages, rmap);
2.281 +}
2.282 +
2.283 +static void
2.284 +build_file_tree(struct razor_importer *importer)
2.285 +{
2.286 + int count, i, length;
2.287 + struct import_entry *filenames;
2.288 + char *f, *end;
2.289 + uint32_t name, *r;
2.290 + char dirname[256];
2.291 + struct import_directory *d, root;
2.292 + struct razor_entry *e;
2.293 +
2.294 + count = importer->files.size / sizeof (struct import_entry);
2.295 + razor_qsort_with_data(importer->files.data,
2.296 + count,
2.297 + sizeof (struct import_entry),
2.298 + compare_filenames,
2.299 + NULL);
2.300 +
2.301 + root.name = hashtable_tokenize(&importer->table, "");
2.302 + array_init(&root.files);
2.303 + array_init(&root.packages);
2.304 + root.last = NULL;
2.305 +
2.306 + filenames = importer->files.data;
2.307 + for (i = 0; i < count; i++) {
2.308 + f = filenames[i].name;
2.309 + if (*f != '/')
2.310 + continue;
2.311 + f++;
2.312 +
2.313 + d = &root;
2.314 + while (*f) {
2.315 + end = strchr(f, '/');
2.316 + if (end == NULL)
2.317 + end = f + strlen(f);
2.318 + length = end - f;
2.319 + memcpy(dirname, f, length);
2.320 + dirname[length] ='\0';
2.321 + name = hashtable_tokenize(&importer->table, dirname);
2.322 + if (d->last == NULL || d->last->name != name) {
2.323 + d->last = array_add(&d->files, sizeof *d);
2.324 + d->last->name = name;
2.325 + d->last->last = NULL;
2.326 + array_init(&d->last->files);
2.327 + array_init(&d->last->packages);
2.328 + }
2.329 + d = d->last;
2.330 + f = end + 1;
2.331 + if (*end == '\0')
2.332 + break;
2.333 + }
2.334 +
2.335 + r = array_add(&d->packages, sizeof *r);
2.336 + *r = filenames[i].package;
2.337 + free(filenames[i].name);
2.338 + }
2.339 +
2.340 + count_entries(&root);
2.341 + e = importer->set->files.data;
2.342 + e->name = root.name;
2.343 + e->flags = RAZOR_ENTRY_LAST;
2.344 + e->start = importer->files.size ? 1 : 0;
2.345 + list_set_empty(&e->packages);
2.346 +
2.347 + serialize_files(importer->set, &root, &importer->set->files);
2.348 +
2.349 + array_release(&importer->files);
2.350 +}
2.351 +
2.352 +static void
2.353 +list_to_array(struct list *list, struct array *array)
2.354 +{
2.355 + uint32_t *item;
2.356 +
2.357 + while (list) {
2.358 + item = array_add(array, sizeof *item);
2.359 + *item = list->data;
2.360 + list = list_next(list);
2.361 + }
2.362 +}
2.363 +
2.364 +static int
2.365 +compare_file_requires(const void *p1, const void *p2, void *data)
2.366 +{
2.367 + uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
2.368 + const char *pool = data;
2.369 +
2.370 + return strcmp(&pool[*f1], &pool[*f2]);
2.371 +}
2.372 +
2.373 +static void
2.374 +find_file_provides(struct razor_importer *importer)
2.375 +{
2.376 + struct razor_property *prop;
2.377 + struct razor_entry *top, *entry;
2.378 + struct razor_package *packages;
2.379 + struct array pkgprops;
2.380 + struct list *pkg;
2.381 + uint32_t *req, *req_start, *req_end;
2.382 + uint32_t *map, *newprop;
2.383 + char *pool;
2.384 +
2.385 + pool = importer->set->string_pool.data;
2.386 + packages = importer->set->packages.data;
2.387 + top = importer->set->files.data;
2.388 +
2.389 + req = req_start = importer->file_requires.data;
2.390 + req_end = importer->file_requires.data + importer->file_requires.size;
2.391 + map = razor_qsort_with_data(req, req_end - req, sizeof *req,
2.392 + compare_file_requires, pool);
2.393 + free(map);
2.394 +
2.395 + for (req = req_start; req < req_end; req++) {
2.396 + if (req > req_start && req[0] == req[-1])
2.397 + continue;
2.398 + entry = razor_set_find_entry(importer->set, top, &pool[*req]);
2.399 + if (!entry)
2.400 + continue;
2.401 +
2.402 + for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
2.403 + prop = array_add(&importer->set->properties, sizeof *prop);
2.404 + prop->name = *req;
2.405 + prop->flags =
2.406 + RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
2.407 + prop->version = hashtable_tokenize(&importer->table, "");
2.408 + list_set_ptr(&prop->packages, pkg->data);
2.409 +
2.410 + /* Update property list of pkg */
2.411 + array_init(&pkgprops);
2.412 + list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
2.413 + newprop = array_add(&pkgprops, sizeof *newprop);
2.414 + *newprop = prop - (struct razor_property *)importer->set->properties.data;
2.415 + list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
2.416 + array_release(&pkgprops);
2.417 + }
2.418 + }
2.419 +
2.420 + array_release(&importer->file_requires);
2.421 +}
2.422 +
2.423 +static void
2.424 +build_package_file_lists(struct razor_set *set, uint32_t *rmap)
2.425 +{
2.426 + struct razor_package *p, *packages;
2.427 + struct array *pkgs;
2.428 + struct razor_entry *e, *end;
2.429 + struct list *r;
2.430 + uint32_t *q;
2.431 + int i, count;
2.432 +
2.433 + count = set->packages.size / sizeof *p;
2.434 + pkgs = zalloc(count * sizeof *pkgs);
2.435 +
2.436 + end = set->files.data + set->files.size;
2.437 + for (e = set->files.data; e < end; e++) {
2.438 + list_remap_head(&e->packages, rmap);
2.439 + r = list_first(&e->packages, &set->package_pool);
2.440 + while (r) {
2.441 + q = array_add(&pkgs[r->data], sizeof *q);
2.442 + *q = e - (struct razor_entry *) set->files.data;
2.443 + r = list_next(r);
2.444 + }
2.445 + }
2.446 +
2.447 + packages = set->packages.data;
2.448 + for (i = 0; i < count; i++) {
2.449 + list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
2.450 + array_release(&pkgs[i]);
2.451 + }
2.452 + free(pkgs);
2.453 +}
2.454 +
2.455 +struct razor_set *
2.456 +razor_importer_finish(struct razor_importer *importer)
2.457 +{
2.458 + struct razor_set *set;
2.459 + uint32_t *map, *rmap;
2.460 + int i, count;
2.461 +
2.462 + build_file_tree(importer);
2.463 + find_file_provides(importer);
2.464 +
2.465 + map = uniqueify_properties(importer->set);
2.466 + list_remap_pool(&importer->set->property_pool, map);
2.467 + free(map);
2.468 +
2.469 + count = importer->set->packages.size / sizeof(struct razor_package);
2.470 + map = razor_qsort_with_data(importer->set->packages.data,
2.471 + count,
2.472 + sizeof(struct razor_package),
2.473 + compare_packages,
2.474 + importer->set);
2.475 +
2.476 + rmap = malloc(count * sizeof *rmap);
2.477 + for (i = 0; i < count; i++)
2.478 + rmap[map[i]] = i;
2.479 + free(map);
2.480 +
2.481 + list_remap_pool(&importer->set->package_pool, rmap);
2.482 + build_package_file_lists(importer->set, rmap);
2.483 + remap_property_package_links(&importer->set->properties, rmap);
2.484 + free(rmap);
2.485 +
2.486 + set = importer->set;
2.487 + hashtable_release(&importer->table);
2.488 + free(importer);
2.489 +
2.490 + return set;
2.491 +}
3.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
3.2 +++ b/librazor/iterator.c Fri Jun 20 15:10:34 2008 -0400
3.3 @@ -0,0 +1,265 @@
3.4 +/*
3.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
3.6 + * Copyright (C) 2008 Red Hat, Inc
3.7 + *
3.8 + * This program is free software; you can redistribute it and/or modify
3.9 + * it under the terms of the GNU General Public License as published by
3.10 + * the Free Software Foundation; either version 2 of the License, or
3.11 + * (at your option) any later version.
3.12 + *
3.13 + * This program is distributed in the hope that it will be useful,
3.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
3.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3.16 + * GNU General Public License for more details.
3.17 + *
3.18 + * You should have received a copy of the GNU General Public License along
3.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
3.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
3.21 + */
3.22 +
3.23 +#define _GNU_SOURCE
3.24 +
3.25 +#include <string.h>
3.26 +#include "razor-internal.h"
3.27 +#include "razor.h"
3.28 +
3.29 +static struct razor_package_iterator *
3.30 +razor_package_iterator_create_with_index(struct razor_set *set,
3.31 + struct list *index)
3.32 +{
3.33 + struct razor_package_iterator *pi;
3.34 +
3.35 + pi = zalloc(sizeof *pi);
3.36 + pi->set = set;
3.37 + pi->index = index;
3.38 +
3.39 + return pi;
3.40 +}
3.41 +
3.42 +struct razor_package_iterator *
3.43 +razor_package_iterator_create(struct razor_set *set)
3.44 +{
3.45 + struct razor_package_iterator *pi;
3.46 +
3.47 + pi = zalloc(sizeof *pi);
3.48 + pi->set = set;
3.49 + pi->end = set->packages.data + set->packages.size;
3.50 + pi->package = set->packages.data;
3.51 +
3.52 + return pi;
3.53 +}
3.54 +
3.55 +void
3.56 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
3.57 + struct razor_set *set,
3.58 + struct razor_property *property)
3.59 +{
3.60 + memset(pi, 0, sizeof *pi);
3.61 + pi->set = set;
3.62 + pi->index = list_first(&property->packages, &set->package_pool);
3.63 +}
3.64 +
3.65 +struct razor_package_iterator *
3.66 +razor_package_iterator_create_for_property(struct razor_set *set,
3.67 + struct razor_property *property)
3.68 +{
3.69 + struct list *index;
3.70 +
3.71 + index = list_first(&property->packages, &set->package_pool);
3.72 + return razor_package_iterator_create_with_index(set, index);
3.73 +}
3.74 +
3.75 +struct razor_package_iterator *
3.76 +razor_package_iterator_create_for_file(struct razor_set *set,
3.77 + const char *filename)
3.78 +{
3.79 + struct razor_entry *entry;
3.80 + struct list *index;
3.81 +
3.82 + entry = razor_set_find_entry(set, set->files.data, filename);
3.83 + if (entry == NULL)
3.84 + return NULL;
3.85 +
3.86 + index = list_first(&entry->packages, &set->package_pool);
3.87 + return razor_package_iterator_create_with_index(set, index);
3.88 +}
3.89 +
3.90 +int
3.91 +razor_package_iterator_next(struct razor_package_iterator *pi,
3.92 + struct razor_package **package,
3.93 + const char **name,
3.94 + const char **version,
3.95 + const char **arch)
3.96 +{
3.97 + char *pool;
3.98 + int valid;
3.99 + struct razor_package *p, *packages;
3.100 +
3.101 + if (pi->package) {
3.102 + p = pi->package++;
3.103 + valid = p < pi->end;
3.104 + } else if (pi->index) {
3.105 + packages = pi->set->packages.data;
3.106 + p = &packages[pi->index->data];
3.107 + pi->index = list_next(pi->index);
3.108 + valid = 1;
3.109 + } else
3.110 + valid = 0;
3.111 +
3.112 + if (valid) {
3.113 + pool = pi->set->string_pool.data;
3.114 + *package = p;
3.115 + *name = &pool[p->name];
3.116 + *version = &pool[p->version];
3.117 + *arch = &pool[p->arch];
3.118 + } else {
3.119 + *package = NULL;
3.120 + }
3.121 +
3.122 + return valid;
3.123 +}
3.124 +
3.125 +void
3.126 +razor_package_iterator_destroy(struct razor_package_iterator *pi)
3.127 +{
3.128 + if (pi->free_index)
3.129 + free(pi->index);
3.130 +
3.131 + free(pi);
3.132 +}
3.133 +
3.134 +struct razor_property_iterator *
3.135 +razor_property_iterator_create(struct razor_set *set,
3.136 + struct razor_package *package)
3.137 +{
3.138 + struct razor_property_iterator *pi;
3.139 +
3.140 + pi = zalloc(sizeof *pi);
3.141 + pi->set = set;
3.142 +
3.143 + if (package) {
3.144 + pi->index = list_first(&package->properties,
3.145 + &set->property_pool);
3.146 + } else {
3.147 + pi->property = set->properties.data;
3.148 + pi->end = set->properties.data + set->properties.size;
3.149 + }
3.150 +
3.151 + return pi;
3.152 +}
3.153 +
3.154 +int
3.155 +razor_property_iterator_next(struct razor_property_iterator *pi,
3.156 + struct razor_property **property,
3.157 + const char **name,
3.158 + uint32_t *flags,
3.159 + const char **version)
3.160 +{
3.161 + char *pool;
3.162 + int valid;
3.163 + struct razor_property *p, *properties;
3.164 +
3.165 + if (pi->property) {
3.166 + p = pi->property++;
3.167 + valid = p < pi->end;
3.168 + } else if (pi->index) {
3.169 + properties = pi->set->properties.data;
3.170 + p = &properties[pi->index->data];
3.171 + pi->index = list_next(pi->index);
3.172 + valid = 1;
3.173 + } else
3.174 + valid = 0;
3.175 +
3.176 + if (valid) {
3.177 + pool = pi->set->string_pool.data;
3.178 + *property = p;
3.179 + *name = &pool[p->name];
3.180 + *flags = p->flags;
3.181 + *version = &pool[p->version];
3.182 + } else {
3.183 + *property = NULL;
3.184 + }
3.185 +
3.186 + return valid;
3.187 +}
3.188 +
3.189 +void
3.190 +razor_property_iterator_destroy(struct razor_property_iterator *pi)
3.191 +{
3.192 + free(pi);
3.193 +}
3.194 +
3.195 +struct razor_package_query {
3.196 + struct razor_set *set;
3.197 + char *vector;
3.198 + int count;
3.199 +};
3.200 +
3.201 +struct razor_package_query *
3.202 +razor_package_query_create(struct razor_set *set)
3.203 +{
3.204 + struct razor_package_query *pq;
3.205 + int count;
3.206 +
3.207 + pq = zalloc(sizeof *pq);
3.208 + pq->set = set;
3.209 + count = set->packages.size / sizeof(struct razor_package);
3.210 + pq->vector = zalloc(count * sizeof(char));
3.211 +
3.212 + return pq;
3.213 +}
3.214 +
3.215 +void
3.216 +razor_package_query_add_package(struct razor_package_query *pq,
3.217 + struct razor_package *p)
3.218 +{
3.219 + struct razor_package *packages;
3.220 +
3.221 + packages = pq->set->packages.data;
3.222 + pq->count += pq->vector[p - packages] ^ 1;
3.223 + pq->vector[p - packages] = 1;
3.224 +}
3.225 +
3.226 +void
3.227 +razor_package_query_add_iterator(struct razor_package_query *pq,
3.228 + struct razor_package_iterator *pi)
3.229 +{
3.230 + struct razor_package *packages, *p;
3.231 + const char *name, *version, *arch;
3.232 +
3.233 + packages = pq->set->packages.data;
3.234 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
3.235 + pq->count += pq->vector[p - packages] ^ 1;
3.236 + pq->vector[p - packages] = 1;
3.237 + }
3.238 +}
3.239 +
3.240 +struct razor_package_iterator *
3.241 +razor_package_query_finish(struct razor_package_query *pq)
3.242 +{
3.243 + struct razor_package_iterator *pi;
3.244 + struct razor_set *set;
3.245 + struct list *index;
3.246 + int i, j, count;
3.247 +
3.248 + set = pq->set;
3.249 + count = set->packages.size / sizeof(struct razor_package);
3.250 + index = zalloc(pq->count * sizeof *index);
3.251 +
3.252 + for (i = 0, j = 0; i < count; i++) {
3.253 + if (!pq->vector[i])
3.254 + continue;
3.255 +
3.256 + index[j].data = i;
3.257 + if (j == pq->count - 1)
3.258 + index[j].flags = 0x80;
3.259 + j++;
3.260 + }
3.261 +
3.262 + free(pq);
3.263 +
3.264 + pi = razor_package_iterator_create_with_index(set, index);
3.265 + pi->free_index = 1;
3.266 +
3.267 + return pi;
3.268 +}
4.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
4.2 +++ b/librazor/merger.c Fri Jun 20 15:10:34 2008 -0400
4.3 @@ -0,0 +1,525 @@
4.4 +/*
4.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
4.6 + * Copyright (C) 2008 Red Hat, Inc
4.7 + *
4.8 + * This program is free software; you can redistribute it and/or modify
4.9 + * it under the terms of the GNU General Public License as published by
4.10 + * the Free Software Foundation; either version 2 of the License, or
4.11 + * (at your option) any later version.
4.12 + *
4.13 + * This program is distributed in the hope that it will be useful,
4.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
4.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4.16 + * GNU General Public License for more details.
4.17 + *
4.18 + * You should have received a copy of the GNU General Public License along
4.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
4.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
4.21 + */
4.22 +
4.23 +#include <string.h>
4.24 +#include "razor-internal.h"
4.25 +#include "razor.h"
4.26 +
4.27 +#define UPSTREAM_SOURCE 0x80
4.28 +
4.29 +struct source {
4.30 + struct razor_set *set;
4.31 + uint32_t *property_map;
4.32 + uint32_t *file_map;
4.33 +};
4.34 +
4.35 +struct razor_merger {
4.36 + struct razor_set *set;
4.37 + struct hashtable table;
4.38 + struct source source1;
4.39 + struct source source2;
4.40 +};
4.41 +
4.42 +struct razor_merger *
4.43 +razor_merger_create(struct razor_set *set1, struct razor_set *set2)
4.44 +{
4.45 + struct razor_merger *merger;
4.46 + int count;
4.47 + size_t size;
4.48 +
4.49 + merger = zalloc(sizeof *merger);
4.50 + merger->set = razor_set_create();
4.51 + hashtable_init(&merger->table, &merger->set->string_pool);
4.52 +
4.53 + merger->source1.set = set1;
4.54 + count = set1->properties.size / sizeof (struct razor_property);
4.55 + size = count * sizeof merger->source1.property_map[0];
4.56 + merger->source1.property_map = zalloc(size);
4.57 + count = set1->files.size / sizeof (struct razor_entry);
4.58 + size = count * sizeof merger->source1.file_map[0];
4.59 + merger->source1.file_map = zalloc(size);
4.60 +
4.61 + merger->source2.set = set2;
4.62 + count = set2->properties.size / sizeof (struct razor_property);
4.63 + size = count * sizeof merger->source2.property_map[0];
4.64 + merger->source2.property_map = zalloc(size);
4.65 + count = set2->files.size / sizeof (struct razor_entry);
4.66 + size = count * sizeof merger->source2.file_map[0];
4.67 + merger->source2.file_map = zalloc(size);
4.68 +
4.69 + return merger;
4.70 +}
4.71 +
4.72 +void
4.73 +razor_merger_add_package(struct razor_merger *merger,
4.74 + struct razor_package *package)
4.75 +{
4.76 + char *pool;
4.77 + struct list *r;
4.78 + struct razor_package *p;
4.79 + struct razor_set *set1;
4.80 + struct source *source;
4.81 + uint32_t flags;
4.82 +
4.83 + set1 = merger->source1.set;
4.84 + if (set1->packages.data <= (void *) package &&
4.85 + (void *) package < set1->packages.data + set1->packages.size) {
4.86 + source = &merger->source1;
4.87 + flags = 0;
4.88 + } else {
4.89 + source = &merger->source2;
4.90 + flags = UPSTREAM_SOURCE;
4.91 + }
4.92 +
4.93 + pool = source->set->string_pool.data;
4.94 + p = array_add(&merger->set->packages, sizeof *p);
4.95 + p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
4.96 + p->flags = flags;
4.97 + p->version = hashtable_tokenize(&merger->table,
4.98 + &pool[package->version]);
4.99 + p->arch = hashtable_tokenize(&merger->table,
4.100 + &pool[package->arch]);
4.101 +
4.102 + p->properties = package->properties;
4.103 + r = list_first(&package->properties, &source->set->property_pool);
4.104 + while (r) {
4.105 + source->property_map[r->data] = 1;
4.106 + r = list_next(r);
4.107 + }
4.108 +
4.109 + p->files = package->files;
4.110 + r = list_first(&package->files, &source->set->file_pool);
4.111 + while (r) {
4.112 + source->file_map[r->data] = 1;
4.113 + r = list_next(r);
4.114 + }
4.115 +}
4.116 +
4.117 +static uint32_t
4.118 +add_property(struct razor_merger *merger,
4.119 + const char *name, uint32_t flags, const char *version)
4.120 +{
4.121 + struct razor_property *p;
4.122 +
4.123 + p = array_add(&merger->set->properties, sizeof *p);
4.124 + p->name = hashtable_tokenize(&merger->table, name);
4.125 + p->flags = flags;
4.126 + p->version = hashtable_tokenize(&merger->table, version);
4.127 +
4.128 + return p - (struct razor_property *) merger->set->properties.data;
4.129 +}
4.130 +
4.131 +static void
4.132 +merge_properties(struct razor_merger *merger)
4.133 +{
4.134 + struct razor_property *p1, *p2;
4.135 + struct razor_set *set1, *set2;
4.136 + uint32_t *map1, *map2;
4.137 + int i, j, cmp, count1, count2;
4.138 + char *pool1, *pool2;
4.139 +
4.140 + set1 = merger->source1.set;
4.141 + set2 = merger->source2.set;
4.142 + map1 = merger->source1.property_map;
4.143 + map2 = merger->source2.property_map;
4.144 +
4.145 + i = 0;
4.146 + j = 0;
4.147 + pool1 = set1->string_pool.data;
4.148 + pool2 = set2->string_pool.data;
4.149 +
4.150 + count1 = set1->properties.size / sizeof *p1;
4.151 + count2 = set2->properties.size / sizeof *p2;
4.152 + while (i < count1 || j < count2) {
4.153 + if (i < count1 && map1[i] == 0) {
4.154 + i++;
4.155 + continue;
4.156 + }
4.157 + if (j < count2 && map2[j] == 0) {
4.158 + j++;
4.159 + continue;
4.160 + }
4.161 + p1 = (struct razor_property *) set1->properties.data + i;
4.162 + p2 = (struct razor_property *) set2->properties.data + j;
4.163 + if (i < count1 && j < count2)
4.164 + cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
4.165 + else if (i < count1)
4.166 + cmp = -1;
4.167 + else
4.168 + cmp = 1;
4.169 + if (cmp == 0)
4.170 + cmp = p1->flags - p2->flags;
4.171 + if (cmp == 0)
4.172 + cmp = razor_versioncmp(&pool1[p1->version],
4.173 + &pool2[p2->version]);
4.174 + if (cmp < 0) {
4.175 + map1[i++] = add_property(merger,
4.176 + &pool1[p1->name],
4.177 + p1->flags,
4.178 + &pool1[p1->version]);
4.179 + } else if (cmp > 0) {
4.180 + map2[j++] = add_property(merger,
4.181 + &pool2[p2->name],
4.182 + p2->flags,
4.183 + &pool2[p2->version]);
4.184 + } else {
4.185 + map1[i++] = map2[j++] =
4.186 + add_property(merger,
4.187 + &pool1[p1->name],
4.188 + p1->flags,
4.189 + &pool1[p1->version]);
4.190 + }
4.191 + }
4.192 +}
4.193 +
4.194 +static void
4.195 +emit_properties(struct list_head *properties, struct array *source_pool,
4.196 + uint32_t *map, struct array *pool)
4.197 +{
4.198 + uint32_t r;
4.199 + struct list *p, *q;
4.200 +
4.201 + r = pool->size / sizeof *q;
4.202 + p = list_first(properties, source_pool);
4.203 + while (p) {
4.204 + q = array_add(pool, sizeof *q);
4.205 + q->data = map[p->data];
4.206 + q->flags = p->flags;
4.207 + p = list_next(p);
4.208 + }
4.209 +
4.210 + list_set_ptr(properties, r);
4.211 +}
4.212 +
4.213 +static uint32_t
4.214 +add_file(struct razor_merger *merger, const char *name)
4.215 +{
4.216 + struct razor_entry *e;
4.217 +
4.218 + e = array_add(&merger->set->files, sizeof *e);
4.219 + e->name = hashtable_tokenize(&merger->table, name);
4.220 + e->flags = 0;
4.221 + e->start = 0;
4.222 +
4.223 + return e - (struct razor_entry *)merger->set->files.data;
4.224 +}
4.225 +
4.226 +/* FIXME. Blah */
4.227 +static int
4.228 +fix_file_map(uint32_t *map,
4.229 + struct razor_entry *files,
4.230 + struct razor_entry *top)
4.231 +{
4.232 + uint32_t e;
4.233 + int found_file = 0;
4.234 +
4.235 + e = top->start;
4.236 + do {
4.237 + if (files[e].start)
4.238 + fix_file_map(map, files, &files[e]);
4.239 + if (map[e])
4.240 + found_file = 1;
4.241 + } while (!(files[e++].flags & RAZOR_ENTRY_LAST));
4.242 +
4.243 + if (found_file)
4.244 + map[top - files] = 1;
4.245 + return found_file;
4.246 +}
4.247 +
4.248 +struct merge_directory {
4.249 + uint32_t merged, dir1, dir2;
4.250 +};
4.251 +
4.252 +static void
4.253 +merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
4.254 +{
4.255 + struct razor_entry *root1, *root2, *mroot, *e1, *e2;
4.256 + struct razor_set *set1, *set2;
4.257 + struct array merge_stack;
4.258 + struct merge_directory *child_md, *end_md;
4.259 + uint32_t *map1, *map2, start, last;
4.260 + int cmp;
4.261 + char *pool1, *pool2;
4.262 +
4.263 + set1 = merger->source1.set;
4.264 + set2 = merger->source2.set;
4.265 + map1 = merger->source1.file_map;
4.266 + map2 = merger->source2.file_map;
4.267 + pool1 = set1->string_pool.data;
4.268 + pool2 = set2->string_pool.data;
4.269 + root1 = (struct razor_entry *) set1->files.data;
4.270 + root2 = (struct razor_entry *) set2->files.data;
4.271 +
4.272 + array_init(&merge_stack);
4.273 +
4.274 + start = merger->set->files.size / sizeof (struct razor_entry);
4.275 + last = 0;
4.276 + e1 = md->dir1 ? root1 + md->dir1 : NULL;
4.277 + e2 = md->dir2 ? root2 + md->dir2 : NULL;
4.278 + while (e1 || e2) {
4.279 + if (!e2 && !map1[e1 - root1]) {
4.280 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
4.281 + e1 = NULL;
4.282 + continue;
4.283 + }
4.284 + if (!e1 && !map2[e2 - root2]) {
4.285 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
4.286 + e2 = NULL;
4.287 + continue;
4.288 + }
4.289 + if (e1 && !map1[e1 - root1] &&
4.290 + e2 && !map1[e2 - root2]) {
4.291 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
4.292 + e1 = NULL;
4.293 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
4.294 + e2 = NULL;
4.295 + continue;
4.296 + }
4.297 +
4.298 + if (!e1)
4.299 + cmp = 1;
4.300 + else if (!e2)
4.301 + cmp = -1;
4.302 + else {
4.303 + cmp = strcmp (&pool1[e1->name],
4.304 + &pool2[e2->name]);
4.305 + }
4.306 +
4.307 + if (cmp < 0) {
4.308 + if (map1[e1 - root1]) {
4.309 + map1[e1 - root1] = last =
4.310 + add_file(merger, &pool1[e1->name]);
4.311 + if (e1->start) {
4.312 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
4.313 + child_md->merged = last;
4.314 + child_md->dir1 = e1->start;
4.315 + child_md->dir2 = 0;
4.316 + }
4.317 + }
4.318 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
4.319 + e1 = NULL;
4.320 + } else if (cmp > 0) {
4.321 + if (map2[e2 - root2]) {
4.322 + map2[e2 - root2] = last =
4.323 + add_file(merger, &pool2[e2->name]);
4.324 + if (e2->start) {
4.325 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
4.326 + child_md->merged = last;
4.327 + child_md->dir1 = 0;
4.328 + child_md->dir2 = e2->start;
4.329 + }
4.330 + }
4.331 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
4.332 + e2 = NULL;
4.333 + } else {
4.334 + map1[e1 - root1] = map2[e2- root2] = last =
4.335 + add_file(merger, &pool1[e1->name]);
4.336 + if (e1->start || e2->start) {
4.337 + child_md = array_add(&merge_stack, sizeof (struct merge_directory));
4.338 + child_md->merged = last;
4.339 + child_md->dir1 = e1->start;
4.340 + child_md->dir2 = e2->start;
4.341 + }
4.342 + if ((e1++)->flags & RAZOR_ENTRY_LAST)
4.343 + e1 = NULL;
4.344 + if ((e2++)->flags & RAZOR_ENTRY_LAST)
4.345 + e2 = NULL;
4.346 + }
4.347 + }
4.348 +
4.349 + mroot = (struct razor_entry *)merger->set->files.data;
4.350 + if (last) {
4.351 + mroot[last].flags = RAZOR_ENTRY_LAST;
4.352 + mroot[md->merged].start = start;
4.353 + } else
4.354 + mroot[md->merged].start = 0;
4.355 +
4.356 + end_md = merge_stack.data + merge_stack.size;
4.357 + for (child_md = merge_stack.data; child_md < end_md; child_md++)
4.358 + merge_one_directory(merger, child_md);
4.359 + array_release(&merge_stack);
4.360 +}
4.361 +
4.362 +static void
4.363 +merge_files(struct razor_merger *merger)
4.364 +{
4.365 + struct razor_entry *root;
4.366 + struct merge_directory md;
4.367 + uint32_t *map1, *map2;
4.368 +
4.369 + map1 = merger->source1.file_map;
4.370 + map2 = merger->source2.file_map;
4.371 +
4.372 + md.merged = 0;
4.373 +
4.374 + if (merger->source1.set->files.size) {
4.375 + root = (struct razor_entry *) merger->source1.set->files.data;
4.376 + if (root->start)
4.377 + fix_file_map(map1, root, root);
4.378 + md.dir1 = root->start;
4.379 + } else
4.380 + md.dir1 = 0;
4.381 +
4.382 + if (merger->source2.set->files.size) {
4.383 + root = (struct razor_entry *) merger->source2.set->files.data;
4.384 + if (root->start)
4.385 + fix_file_map(map2, root, root);
4.386 + md.dir2 = root->start;
4.387 + } else
4.388 + md.dir2 = 0;
4.389 +
4.390 + merge_one_directory(merger, &md);
4.391 +}
4.392 +
4.393 +static void
4.394 +emit_files(struct list_head *files, struct array *source_pool,
4.395 + uint32_t *map, struct array *pool)
4.396 +{
4.397 + uint32_t r;
4.398 + struct list *p, *q;
4.399 +
4.400 + r = pool->size / sizeof *q;
4.401 + p = list_first(files, source_pool);
4.402 + while (p) {
4.403 + q = array_add(pool, sizeof *q);
4.404 + q->data = map[p->data];
4.405 + q->flags = p->flags;
4.406 + p = list_next(p);
4.407 + }
4.408 +
4.409 + list_set_ptr(files, r);
4.410 +}
4.411 +
4.412 +/* Rebuild property->packages maps. We can't just remap these, as a
4.413 + * property may have lost or gained a number of packages. Allocate an
4.414 + * array per property and loop through the packages and add them to
4.415 + * the arrays for their properties. */
4.416 +static void
4.417 +rebuild_property_package_lists(struct razor_set *set)
4.418 +{
4.419 + struct array *pkgs, *a;
4.420 + struct razor_package *pkg, *pkg_end;
4.421 + struct razor_property *prop, *prop_end;
4.422 + struct list *r;
4.423 + uint32_t *q;
4.424 + int count;
4.425 +
4.426 + count = set->properties.size / sizeof (struct razor_property);
4.427 + pkgs = zalloc(count * sizeof *pkgs);
4.428 + pkg_end = set->packages.data + set->packages.size;
4.429 +
4.430 + for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
4.431 + r = list_first(&pkg->properties, &set->property_pool);
4.432 + while (r) {
4.433 + q = array_add(&pkgs[r->data], sizeof *q);
4.434 + *q = pkg - (struct razor_package *) set->packages.data;
4.435 + r = list_next(r);
4.436 + }
4.437 + }
4.438 +
4.439 + prop_end = set->properties.data + set->properties.size;
4.440 + a = pkgs;
4.441 + for (prop = set->properties.data; prop < prop_end; prop++, a++) {
4.442 + list_set_array(&prop->packages, &set->package_pool, a, 0);
4.443 + array_release(a);
4.444 + }
4.445 + free(pkgs);
4.446 +}
4.447 +
4.448 +static void
4.449 +rebuild_file_package_lists(struct razor_set *set)
4.450 +{
4.451 + struct array *pkgs, *a;
4.452 + struct razor_package *pkg, *pkg_end;
4.453 + struct razor_entry *entry, *entry_end;
4.454 + struct list *r;
4.455 + uint32_t *q;
4.456 + int count;
4.457 +
4.458 + count = set->files.size / sizeof (struct razor_entry);
4.459 + pkgs = zalloc(count * sizeof *pkgs);
4.460 + pkg_end = set->packages.data + set->packages.size;
4.461 +
4.462 + for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
4.463 + r = list_first(&pkg->files, &set->file_pool);
4.464 + while (r) {
4.465 + q = array_add(&pkgs[r->data], sizeof *q);
4.466 + *q = pkg - (struct razor_package *) set->packages.data;
4.467 + r = list_next(r);
4.468 + }
4.469 + }
4.470 +
4.471 + entry_end = set->files.data + set->files.size;
4.472 + a = pkgs;
4.473 + for (entry = set->files.data; entry < entry_end; entry++, a++) {
4.474 + list_set_array(&entry->packages, &set->package_pool, a, 0);
4.475 + array_release(a);
4.476 + }
4.477 + free(pkgs);
4.478 +}
4.479 +
4.480 +struct razor_set *
4.481 +razor_merger_finish(struct razor_merger *merger)
4.482 +{
4.483 + struct razor_set *result;
4.484 + struct razor_package *p, *pend;
4.485 +
4.486 + /* As we built the package list, we filled out a bitvector of
4.487 + * the properties that are referenced by the packages in the
4.488 + * new set. Now we do a parallel loop through the properties
4.489 + * and emit those marked in the bit vector to the new set. In
4.490 + * the process, we update the bit vector to actually map from
4.491 + * indices in the old property list to indices in the new
4.492 + * property list for both sets. */
4.493 +
4.494 + merge_properties(merger);
4.495 + merge_files(merger);
4.496 +
4.497 + /* Now we loop through the packages again and emit the
4.498 + * property lists, remapped to point to the new properties. */
4.499 +
4.500 + pend = merger->set->packages.data + merger->set->packages.size;
4.501 + for (p = merger->set->packages.data; p < pend; p++) {
4.502 + struct source *src;
4.503 +
4.504 + if (p->flags & UPSTREAM_SOURCE)
4.505 + src = &merger->source2;
4.506 + else
4.507 + src = &merger->source1;
4.508 +
4.509 + emit_properties(&p->properties,
4.510 + &src->set->property_pool,
4.511 + src->property_map,
4.512 + &merger->set->property_pool);
4.513 + emit_files(&p->files,
4.514 + &src->set->file_pool,
4.515 + src->file_map,
4.516 + &merger->set->file_pool);
4.517 + p->flags &= ~UPSTREAM_SOURCE;
4.518 + }
4.519 +
4.520 + rebuild_property_package_lists(merger->set);
4.521 + rebuild_file_package_lists(merger->set);
4.522 +
4.523 + result = merger->set;
4.524 + hashtable_release(&merger->table);
4.525 + free(merger);
4.526 +
4.527 + return result;
4.528 +}
5.1 --- a/librazor/razor-internal.h Fri Jun 20 14:18:52 2008 -0400
5.2 +++ b/librazor/razor-internal.h Fri Jun 20 15:10:34 2008 -0400
5.3 @@ -1,8 +1,166 @@
5.4 #ifndef _RAZOR_INTERNAL_H_
5.5 #define _RAZOR_INTERNAL_H_
5.6
5.7 +#include <stdlib.h>
5.8 +#include <stdint.h>
5.9 +
5.10 +void *zalloc(size_t size);
5.11 +
5.12 +struct array {
5.13 + void *data;
5.14 + int size, alloc;
5.15 +};
5.16 +
5.17 +void array_init(struct array *array);
5.18 +void array_release(struct array *array);
5.19 +void *array_add(struct array *array, int size);
5.20 +
5.21 +
5.22 +struct list_head {
5.23 + uint32_t list_ptr : 24;
5.24 + uint32_t flags : 8;
5.25 +};
5.26 +
5.27 +struct list {
5.28 + uint32_t data : 24;
5.29 + uint32_t flags : 8;
5.30 +};
5.31 +
5.32 +void list_set_empty(struct list_head *head);
5.33 +void list_set_ptr(struct list_head *head, uint32_t ptr);
5.34 +void list_set_array(struct list_head *head, struct array *pool, struct array *items, int force_indirect);
5.35 +
5.36 +struct list *list_first(struct list_head *head, struct array *pool);
5.37 +struct list *list_next(struct list *list);
5.38 +
5.39 +void list_remap_pool(struct array *pool, uint32_t *map);
5.40 +void list_remap_head(struct list_head *list, uint32_t *map);
5.41 +
5.42 +
5.43 +struct hashtable {
5.44 + struct array buckets;
5.45 + struct array *pool;
5.46 +};
5.47 +
5.48 +void hashtable_init(struct hashtable *table, struct array *pool);
5.49 +void hashtable_release(struct hashtable *table);
5.50 +uint32_t hashtable_insert(struct hashtable *table, const char *key);
5.51 +uint32_t hashtable_lookup(struct hashtable *table, const char *key);
5.52 +uint32_t hashtable_tokenize(struct hashtable *table, const char *string);
5.53 +
5.54 +
5.55 +struct razor_set_section {
5.56 + uint32_t type;
5.57 + uint32_t offset;
5.58 + uint32_t size;
5.59 +};
5.60 +
5.61 +struct razor_set_header {
5.62 + uint32_t magic;
5.63 + uint32_t version;
5.64 + struct razor_set_section sections[0];
5.65 +};
5.66 +
5.67 +#define RAZOR_MAGIC 0x7a7a7a7a
5.68 +#define RAZOR_VERSION 1
5.69 +
5.70 +#define RAZOR_STRING_POOL 0
5.71 +#define RAZOR_PACKAGES 1
5.72 +#define RAZOR_PROPERTIES 2
5.73 +#define RAZOR_FILES 3
5.74 +#define RAZOR_PACKAGE_POOL 4
5.75 +#define RAZOR_PROPERTY_POOL 5
5.76 +#define RAZOR_FILE_POOL 6
5.77 +
5.78 +struct razor_package {
5.79 + uint32_t name : 24;
5.80 + uint32_t flags : 8;
5.81 + uint32_t version;
5.82 + uint32_t arch;
5.83 + struct list_head properties;
5.84 + struct list_head files;
5.85 +};
5.86 +
5.87 +struct razor_property {
5.88 + uint32_t name;
5.89 + uint32_t flags;
5.90 + uint32_t version;
5.91 + struct list_head packages;
5.92 +};
5.93 +
5.94 +struct razor_entry {
5.95 + uint32_t name : 24;
5.96 + uint32_t flags : 8;
5.97 + uint32_t start;
5.98 + struct list_head packages;
5.99 +};
5.100 +
5.101 +#define RAZOR_ENTRY_LAST 0x80
5.102 +
5.103 +struct razor_set {
5.104 + struct array string_pool;
5.105 + struct array packages;
5.106 + struct array properties;
5.107 + struct array files;
5.108 + struct array package_pool;
5.109 + struct array property_pool;
5.110 + struct array file_pool;
5.111 + struct razor_set_header *header;
5.112 +};
5.113 +
5.114 +struct import_entry {
5.115 + uint32_t package;
5.116 + char *name;
5.117 +};
5.118 +
5.119 +struct import_directory {
5.120 + uint32_t name, count;
5.121 + struct array files;
5.122 + struct array packages;
5.123 + struct import_directory *last;
5.124 +};
5.125 +
5.126 +struct razor_importer {
5.127 + struct razor_set *set;
5.128 + struct hashtable table;
5.129 + struct razor_package *package;
5.130 + struct array properties;
5.131 + struct array files;
5.132 + struct array file_requires;
5.133 +};
5.134 +
5.135 +struct razor_package_iterator {
5.136 + struct razor_set *set;
5.137 + struct razor_package *package, *end;
5.138 + struct list *index;
5.139 + int free_index;
5.140 +};
5.141 +
5.142 +void
5.143 +razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
5.144 + struct razor_set *set,
5.145 + struct razor_property *property);
5.146 +
5.147 +struct razor_property_iterator {
5.148 + struct razor_set *set;
5.149 + struct razor_property *property, *end;
5.150 + struct list *index;
5.151 +};
5.152 +
5.153 #define ALIGN(value, base) (((value) + (base - 1)) & ~((base) - 1))
5.154
5.155 +struct razor_entry *
5.156 +razor_set_find_entry(struct razor_set *set,
5.157 + struct razor_entry *dir, const char *pattern);
5.158 +
5.159 +struct razor_merger *
5.160 +razor_merger_create(struct razor_set *set1, struct razor_set *set2);
5.161 +void
5.162 +razor_merger_add_package(struct razor_merger *merger,
5.163 + struct razor_package *package);
5.164 +struct razor_set *
5.165 +razor_merger_finish(struct razor_merger *merger);
5.166 +
5.167 /* Utility functions */
5.168
5.169 int razor_create_dir(const char *root, const char *path);
6.1 --- a/librazor/razor-root.c Fri Jun 20 14:18:52 2008 -0400
6.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
6.3 @@ -1,168 +0,0 @@
6.4 -#include <stdlib.h>
6.5 -#include <stdint.h>
6.6 -#include <stdio.h>
6.7 -#include <sys/stat.h>
6.8 -#include <dirent.h>
6.9 -#include <unistd.h>
6.10 -#include <fcntl.h>
6.11 -#include "razor.h"
6.12 -#include "razor-internal.h"
6.13 -
6.14 -static const char system_repo_filename[] = "system.repo";
6.15 -static const char next_repo_filename[] = "system-next.repo";
6.16 -static const char razor_root_path[] = "/var/lib/razor";
6.17 -
6.18 -struct razor_root {
6.19 - struct razor_set *system;
6.20 - struct razor_set *next;
6.21 - int fd;
6.22 - char path[PATH_MAX];
6.23 - char new_path[PATH_MAX];
6.24 -};
6.25 -
6.26 -int
6.27 -razor_root_create(const char *root)
6.28 -{
6.29 - struct stat buf;
6.30 - struct razor_set *set;
6.31 - char path[PATH_MAX];
6.32 -
6.33 - if (stat(root, &buf) < 0) {
6.34 - if (mkdir(root, 0777) < 0) {
6.35 - fprintf(stderr,
6.36 - "could not create install root \"%s\"\n",
6.37 - root);
6.38 - return -1;
6.39 - }
6.40 - fprintf(stderr, "created install root \"%s\"\n", root);
6.41 - } else if (!S_ISDIR(buf.st_mode)) {
6.42 - fprintf(stderr,
6.43 - "install root \"%s\" exists, but is not a directory\n",
6.44 - root);
6.45 - return -1;
6.46 - }
6.47 -
6.48 - snprintf(path, sizeof path, "%s/%s",
6.49 - razor_root_path, system_repo_filename);
6.50 - if (razor_create_dir(root, path) < 0) {
6.51 - fprintf(stderr, "could not create %s%s\n",
6.52 - root, razor_root_path);
6.53 - return -1;
6.54 - }
6.55 -
6.56 - set = razor_set_create();
6.57 - snprintf(path, sizeof path, "%s%s/%s",
6.58 - root, razor_root_path, system_repo_filename);
6.59 - if (stat(path, &buf) == 0) {
6.60 - fprintf(stderr,
6.61 - "a razor install root is already initialized\n");
6.62 - return -1;
6.63 - }
6.64 - if (razor_set_write(set, path) < 0) {
6.65 - fprintf(stderr, "could not write initial package set\n");
6.66 - return -1;
6.67 - }
6.68 - razor_set_destroy(set);
6.69 -
6.70 - return 0;
6.71 -}
6.72 -
6.73 -struct razor_root *
6.74 -razor_root_open(const char *root, int flags)
6.75 -{
6.76 - struct razor_root *image;
6.77 -
6.78 - image = malloc(sizeof *image);
6.79 - if (image == NULL)
6.80 - return NULL;
6.81 -
6.82 - /* Create the new next repo file up front to ensure exclusive
6.83 - * access. */
6.84 - snprintf(image->new_path, sizeof image->new_path,
6.85 - "%s%s/%s", root, razor_root_path, next_repo_filename);
6.86 - image->fd = open(image->new_path,
6.87 - O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
6.88 - if (image->fd < 0) {
6.89 - fprintf(stderr, "failed to get lock file, "
6.90 - "maybe previous operation crashed?\n");
6.91 -
6.92 - /* FIXME: Use fcntl advisory locking on the system
6.93 - * package set file to figure out whether previous
6.94 - * operation crashed or is still in progress. */
6.95 -
6.96 - free(image);
6.97 - return NULL;
6.98 - }
6.99 -
6.100 - snprintf(image->path, sizeof image->path,
6.101 - "%s%s/%s", root, razor_root_path, system_repo_filename);
6.102 - image->system = razor_set_open(image->path);
6.103 - if (image->system == NULL) {
6.104 - unlink(image->new_path);
6.105 - close(image->fd);
6.106 - free(image);
6.107 - return NULL;
6.108 - }
6.109 -
6.110 - return image;
6.111 -}
6.112 -
6.113 -struct razor_set *
6.114 -razor_root_open_read_only(const char *root)
6.115 -{
6.116 - char path[PATH_MAX];
6.117 -
6.118 - snprintf(path, sizeof path, "%s%s/%s",
6.119 - root, razor_root_path, system_repo_filename);
6.120 -
6.121 - return razor_set_open(path);
6.122 -}
6.123 -
6.124 -struct razor_transaction *
6.125 -razor_root_create_transaction(struct razor_root *image,
6.126 - struct razor_set *upstream)
6.127 -{
6.128 - /* FIXME: This should take a number of upstream repos. */
6.129 - return razor_transaction_create(image->system, upstream);
6.130 -}
6.131 -
6.132 -int
6.133 -razor_root_close(struct razor_root *image)
6.134 -{
6.135 - unlink(image->new_path);
6.136 - close(image->fd);
6.137 - free(image);
6.138 -
6.139 - return 0;
6.140 -}
6.141 -
6.142 -void
6.143 -razor_root_update(struct razor_root *root, struct razor_set *next)
6.144 -{
6.145 - razor_set_write_to_fd(next, root->fd);
6.146 - root->next = next;
6.147 -
6.148 - /* Sync the new repo file so the new package set is on disk
6.149 - * before we start upgrading. */
6.150 - fsync(root->fd);
6.151 - printf("wrote %s\n", root->new_path);
6.152 -}
6.153 -
6.154 -int
6.155 -razor_root_commit(struct razor_root *image)
6.156 -{
6.157 - /* Make it so. */
6.158 - rename(image->new_path, image->path);
6.159 - printf("renamed %s to %s\n", image->new_path, image->path);
6.160 - close(image->fd);
6.161 - free(image);
6.162 -
6.163 - return 0;
6.164 -}
6.165 -
6.166 -void
6.167 -razor_root_diff(struct razor_root *root,
6.168 - razor_package_callback_t callback, void *data)
6.169 -{
6.170 - return razor_set_diff(root->system, root->next, callback, data);
6.171 -}
7.1 --- a/librazor/razor.c Fri Jun 20 14:18:52 2008 -0400
7.2 +++ b/librazor/razor.c Fri Jun 20 15:10:34 2008 -0400
7.3 @@ -35,89 +35,8 @@
7.4
7.5 #include "razor.h"
7.6 #include "razor-internal.h"
7.7 -#include "types.h"
7.8
7.9 -struct razor_set_section {
7.10 - uint32_t type;
7.11 - uint32_t offset;
7.12 - uint32_t size;
7.13 -};
7.14 -
7.15 -struct razor_set_header {
7.16 - uint32_t magic;
7.17 - uint32_t version;
7.18 - struct razor_set_section sections[0];
7.19 -};
7.20 -
7.21 -#define RAZOR_MAGIC 0x7a7a7a7a
7.22 -#define RAZOR_VERSION 1
7.23 -
7.24 -#define RAZOR_STRING_POOL 0
7.25 -#define RAZOR_PACKAGES 1
7.26 -#define RAZOR_PROPERTIES 2
7.27 -#define RAZOR_FILES 3
7.28 -#define RAZOR_PACKAGE_POOL 4
7.29 -#define RAZOR_PROPERTY_POOL 5
7.30 -#define RAZOR_FILE_POOL 6
7.31 -
7.32 -struct razor_package {
7.33 - uint name : 24;
7.34 - uint flags : 8;
7.35 - uint32_t version;
7.36 - uint32_t arch;
7.37 - struct list_head properties;
7.38 - struct list_head files;
7.39 -};
7.40 -
7.41 -struct razor_property {
7.42 - uint32_t name;
7.43 - uint32_t flags;
7.44 - uint32_t version;
7.45 - struct list_head packages;
7.46 -};
7.47 -
7.48 -struct razor_entry {
7.49 - uint name : 24;
7.50 - uint flags : 8;
7.51 - uint32_t start;
7.52 - struct list_head packages;
7.53 -};
7.54 -
7.55 -#define RAZOR_ENTRY_LAST 0x80
7.56 -
7.57 -struct razor_set {
7.58 - struct array string_pool;
7.59 - struct array packages;
7.60 - struct array properties;
7.61 - struct array files;
7.62 - struct array package_pool;
7.63 - struct array property_pool;
7.64 - struct array file_pool;
7.65 - struct razor_set_header *header;
7.66 -};
7.67 -
7.68 -struct import_entry {
7.69 - uint32_t package;
7.70 - char *name;
7.71 -};
7.72 -
7.73 -struct import_directory {
7.74 - uint32_t name, count;
7.75 - struct array files;
7.76 - struct array packages;
7.77 - struct import_directory *last;
7.78 -};
7.79 -
7.80 -struct razor_importer {
7.81 - struct razor_set *set;
7.82 - struct hashtable table;
7.83 - struct razor_package *package;
7.84 - struct array properties;
7.85 - struct array files;
7.86 - struct array file_requires;
7.87 -};
7.88 -
7.89 -static void *
7.90 +void *
7.91 zalloc(size_t size)
7.92 {
7.93 void *p;
7.94 @@ -296,95 +215,8 @@
7.95 snprintf(evr_buf, size, "-%s", release);
7.96 }
7.97
7.98 -void
7.99 -razor_importer_begin_package(struct razor_importer *importer,
7.100 - const char *name,
7.101 - const char *version,
7.102 - const char *arch)
7.103 -{
7.104 - struct razor_package *p;
7.105 -
7.106 - p = array_add(&importer->set->packages, sizeof *p);
7.107 - p->name = hashtable_tokenize(&importer->table, name);
7.108 - p->flags = 0;
7.109 - p->version = hashtable_tokenize(&importer->table, version);
7.110 - p->arch = hashtable_tokenize(&importer->table, arch);
7.111 -
7.112 - importer->package = p;
7.113 - array_init(&importer->properties);
7.114 -}
7.115 -
7.116 -
7.117 -void
7.118 -razor_importer_finish_package(struct razor_importer *importer)
7.119 -{
7.120 - list_set_array(&importer->package->properties,
7.121 - &importer->set->property_pool,
7.122 - &importer->properties,
7.123 - 1);
7.124 -
7.125 - array_release(&importer->properties);
7.126 -}
7.127 -
7.128 -void
7.129 -razor_importer_add_property(struct razor_importer *importer,
7.130 - const char *name,
7.131 - uint32_t flags,
7.132 - const char *version)
7.133 -{
7.134 - struct razor_property *p;
7.135 - uint32_t *r;
7.136 -
7.137 - p = array_add(&importer->set->properties, sizeof *p);
7.138 - p->name = hashtable_tokenize(&importer->table, name);
7.139 - p->flags = flags;
7.140 - p->version = hashtable_tokenize(&importer->table, version);
7.141 - list_set_ptr(&p->packages, importer->package -
7.142 - (struct razor_package *) importer->set->packages.data);
7.143 -
7.144 - r = array_add(&importer->properties, sizeof *r);
7.145 - *r = p - (struct razor_property *) importer->set->properties.data;
7.146 -
7.147 - if (((flags & RAZOR_PROPERTY_TYPE_MASK) == RAZOR_PROPERTY_REQUIRES) &&
7.148 - *name == '/') {
7.149 - r = array_add(&importer->file_requires, sizeof *r);
7.150 - *r = p->name;
7.151 - }
7.152 -}
7.153 -
7.154 -void
7.155 -razor_importer_add_file(struct razor_importer *importer, const char *name)
7.156 -{
7.157 - struct import_entry *e;
7.158 -
7.159 - e = array_add(&importer->files, sizeof *e);
7.160 -
7.161 - e->package = importer->package -
7.162 - (struct razor_package *) importer->set->packages.data;
7.163 - e->name = strdup(name);
7.164 -}
7.165 -
7.166 -struct razor_importer *
7.167 -razor_importer_new(void)
7.168 -{
7.169 - struct razor_importer *importer;
7.170 -
7.171 - importer = zalloc(sizeof *importer);
7.172 - importer->set = razor_set_create();
7.173 - hashtable_init(&importer->table, &importer->set->string_pool);
7.174 -
7.175 - return importer;
7.176 -}
7.177 -
7.178 -/* Destroy an importer without creating the set. */
7.179 -void
7.180 -razor_importer_destroy(struct razor_importer *importer)
7.181 -{
7.182 - /* FIXME: write this */
7.183 -}
7.184 -
7.185 -static int
7.186 -versioncmp(const char *s1, const char *s2)
7.187 +int
7.188 +razor_versioncmp(const char *s1, const char *s2)
7.189 {
7.190 const char *p1, *p2;
7.191 long n1, n2;
7.192 @@ -414,489 +246,12 @@
7.193 p1++;
7.194 p2++;
7.195 if (isdigit(*p1) && isdigit(*p2))
7.196 - return versioncmp(p1, p2);
7.197 + return razor_versioncmp(p1, p2);
7.198 }
7.199
7.200 return *p1 - *p2;
7.201 }
7.202
7.203 -static int
7.204 -compare_packages(const void *p1, const void *p2, void *data)
7.205 -{
7.206 - const struct razor_package *pkg1 = p1, *pkg2 = p2;
7.207 - struct razor_set *set = data;
7.208 - char *pool = set->string_pool.data;
7.209 -
7.210 - /* FIXME: what if the flags are different? */
7.211 - if (pkg1->name == pkg2->name)
7.212 - return versioncmp(&pool[pkg1->version], &pool[pkg2->version]);
7.213 - else
7.214 - return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
7.215 -}
7.216 -
7.217 -static int
7.218 -compare_properties(const void *p1, const void *p2, void *data)
7.219 -{
7.220 - const struct razor_property *prop1 = p1, *prop2 = p2;
7.221 - struct razor_set *set = data;
7.222 - char *pool = set->string_pool.data;
7.223 -
7.224 - if (prop1->name != prop2->name)
7.225 - return strcmp(&pool[prop1->name], &pool[prop2->name]);
7.226 - else if (prop1->flags != prop2->flags)
7.227 - return prop1->flags - prop2->flags;
7.228 - else
7.229 - return versioncmp(&pool[prop1->version], &pool[prop2->version]);
7.230 -}
7.231 -
7.232 -static uint32_t *
7.233 -uniqueify_properties(struct razor_set *set)
7.234 -{
7.235 - struct razor_property *rp, *up, *rp_end;
7.236 - struct array *pkgs, *p;
7.237 - struct list_head *r;
7.238 - uint32_t *map, *rmap;
7.239 - int i, count, unique;
7.240 -
7.241 - count = set->properties.size / sizeof(struct razor_property);
7.242 - map = razor_qsort_with_data(set->properties.data,
7.243 - count,
7.244 - sizeof(struct razor_property),
7.245 - compare_properties,
7.246 - set);
7.247 -
7.248 - rp_end = set->properties.data + set->properties.size;
7.249 - rmap = malloc(count * sizeof *map);
7.250 - pkgs = zalloc(count * sizeof *pkgs);
7.251 - for (rp = set->properties.data, up = rp, i = 0; rp < rp_end; rp++, i++) {
7.252 - if (rp->name != up->name ||
7.253 - rp->flags != up->flags ||
7.254 - rp->version != up->version) {
7.255 - up++;
7.256 - up->name = rp->name;
7.257 - up->flags = rp->flags;
7.258 - up->version = rp->version;
7.259 - }
7.260 -
7.261 - unique = up - (struct razor_property *) set->properties.data;
7.262 - rmap[map[i]] = unique;
7.263 - r = array_add(&pkgs[unique], sizeof *r);
7.264 - *r = rp->packages;
7.265 - }
7.266 - free(map);
7.267 -
7.268 - if (up != rp)
7.269 - up++;
7.270 - set->properties.size = (void *) up - set->properties.data;
7.271 - rp_end = up;
7.272 - for (rp = set->properties.data, p = pkgs; rp < rp_end; rp++, p++) {
7.273 - list_set_array(&rp->packages, &set->package_pool, p, 0);
7.274 - array_release(p);
7.275 - }
7.276 -
7.277 - free(pkgs);
7.278 -
7.279 - return rmap;
7.280 -}
7.281 -
7.282 -static int
7.283 -compare_filenames(const void *p1, const void *p2, void *data)
7.284 -{
7.285 - const struct import_entry *e1 = p1;
7.286 - const struct import_entry *e2 = p2;
7.287 - const char *n1 = e1->name;
7.288 - const char *n2 = e2->name;
7.289 -
7.290 - /* Need to make sure that the contents of a directory
7.291 - * are sorted immediately after it. So "foo/bar" has to
7.292 - * sort before "foo.conf"
7.293 - *
7.294 - * FIXME: this is about 60% slower than strcmp
7.295 - */
7.296 - while (*n1 && *n2) {
7.297 - if (*n1 < *n2)
7.298 - return *n2 == '/' ? 1 : -1;
7.299 - else if (*n1 > *n2)
7.300 - return *n1 == '/' ? -1 : 1;
7.301 - n1++;
7.302 - n2++;
7.303 - }
7.304 - if (*n1)
7.305 - return 1;
7.306 - else if (*n2)
7.307 - return -1;
7.308 - else
7.309 - return 0;
7.310 -}
7.311 -
7.312 -static void
7.313 -count_entries(struct import_directory *d)
7.314 -{
7.315 - struct import_directory *p, *end;
7.316 -
7.317 - p = d->files.data;
7.318 - end = d->files.data + d->files.size;
7.319 - d->count = 0;
7.320 - while (p < end) {
7.321 - count_entries(p);
7.322 - d->count += p->count + 1;
7.323 - p++;
7.324 - }
7.325 -}
7.326 -
7.327 -static void
7.328 -serialize_files(struct razor_set *set,
7.329 - struct import_directory *d, struct array *array)
7.330 -{
7.331 - struct import_directory *p, *end;
7.332 - struct razor_entry *e = NULL;
7.333 - uint32_t s;
7.334 -
7.335 - p = d->files.data;
7.336 - end = d->files.data + d->files.size;
7.337 - s = array->size / sizeof *e + d->files.size / sizeof *p;
7.338 - while (p < end) {
7.339 - e = array_add(array, sizeof *e);
7.340 - e->name = p->name;
7.341 - e->flags = 0;
7.342 - e->start = p->count > 0 ? s : 0;
7.343 - s += p->count;
7.344 -
7.345 - list_set_array(&e->packages, &set->package_pool, &p->packages, 0);
7.346 - array_release(&p->packages);
7.347 - p++;
7.348 - }
7.349 - if (e != NULL)
7.350 - e->flags |= RAZOR_ENTRY_LAST;
7.351 -
7.352 - p = d->files.data;
7.353 - end = d->files.data + d->files.size;
7.354 - while (p < end) {
7.355 - serialize_files(set, p, array);
7.356 - p++;
7.357 - }
7.358 -}
7.359 -
7.360 -static void
7.361 -remap_property_package_links(struct array *properties, uint32_t *rmap)
7.362 -{
7.363 - struct razor_property *p, *end;
7.364 -
7.365 - end = properties->data + properties->size;
7.366 - for (p = properties->data; p < end; p++)
7.367 - list_remap_head(&p->packages, rmap);
7.368 -}
7.369 -
7.370 -static void
7.371 -build_file_tree(struct razor_importer *importer)
7.372 -{
7.373 - int count, i, length;
7.374 - struct import_entry *filenames;
7.375 - char *f, *end;
7.376 - uint32_t name, *r;
7.377 - char dirname[256];
7.378 - struct import_directory *d, root;
7.379 - struct razor_entry *e;
7.380 -
7.381 - count = importer->files.size / sizeof (struct import_entry);
7.382 - razor_qsort_with_data(importer->files.data,
7.383 - count,
7.384 - sizeof (struct import_entry),
7.385 - compare_filenames,
7.386 - NULL);
7.387 -
7.388 - root.name = hashtable_tokenize(&importer->table, "");
7.389 - array_init(&root.files);
7.390 - array_init(&root.packages);
7.391 - root.last = NULL;
7.392 -
7.393 - filenames = importer->files.data;
7.394 - for (i = 0; i < count; i++) {
7.395 - f = filenames[i].name;
7.396 - if (*f != '/')
7.397 - continue;
7.398 - f++;
7.399 -
7.400 - d = &root;
7.401 - while (*f) {
7.402 - end = strchr(f, '/');
7.403 - if (end == NULL)
7.404 - end = f + strlen(f);
7.405 - length = end - f;
7.406 - memcpy(dirname, f, length);
7.407 - dirname[length] ='\0';
7.408 - name = hashtable_tokenize(&importer->table, dirname);
7.409 - if (d->last == NULL || d->last->name != name) {
7.410 - d->last = array_add(&d->files, sizeof *d);
7.411 - d->last->name = name;
7.412 - d->last->last = NULL;
7.413 - array_init(&d->last->files);
7.414 - array_init(&d->last->packages);
7.415 - }
7.416 - d = d->last;
7.417 - f = end + 1;
7.418 - if (*end == '\0')
7.419 - break;
7.420 - }
7.421 -
7.422 - r = array_add(&d->packages, sizeof *r);
7.423 - *r = filenames[i].package;
7.424 - free(filenames[i].name);
7.425 - }
7.426 -
7.427 - count_entries(&root);
7.428 - e = importer->set->files.data;
7.429 - e->name = root.name;
7.430 - e->flags = RAZOR_ENTRY_LAST;
7.431 - e->start = importer->files.size ? 1 : 0;
7.432 - list_set_empty(&e->packages);
7.433 -
7.434 - serialize_files(importer->set, &root, &importer->set->files);
7.435 -
7.436 - array_release(&importer->files);
7.437 -}
7.438 -
7.439 -static struct razor_entry *
7.440 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern);
7.441 -
7.442 -static void
7.443 -list_to_array(struct list *list, struct array *array)
7.444 -{
7.445 - uint32_t *item;
7.446 -
7.447 - while (list) {
7.448 - item = array_add(array, sizeof *item);
7.449 - *item = list->data;
7.450 - list = list_next(list);
7.451 - }
7.452 -}
7.453 -
7.454 -static int
7.455 -compare_file_requires(const void *p1, const void *p2, void *data)
7.456 -{
7.457 - uint32_t *f1 = (void *)p1, *f2 = (void *)p2;
7.458 - const char *pool = data;
7.459 -
7.460 - return strcmp(&pool[*f1], &pool[*f2]);
7.461 -}
7.462 -
7.463 -static void
7.464 -find_file_provides(struct razor_importer *importer)
7.465 -{
7.466 - struct razor_property *prop;
7.467 - struct razor_entry *top, *entry;
7.468 - struct razor_package *packages;
7.469 - struct array pkgprops;
7.470 - struct list *pkg;
7.471 - uint32_t *req, *req_start, *req_end;
7.472 - uint32_t *map, *newprop;
7.473 - char *pool;
7.474 -
7.475 - pool = importer->set->string_pool.data;
7.476 - packages = importer->set->packages.data;
7.477 - top = importer->set->files.data;
7.478 -
7.479 - req = req_start = importer->file_requires.data;
7.480 - req_end = importer->file_requires.data + importer->file_requires.size;
7.481 - map = razor_qsort_with_data(req, req_end - req, sizeof *req,
7.482 - compare_file_requires, pool);
7.483 - free(map);
7.484 -
7.485 - for (req = req_start; req < req_end; req++) {
7.486 - if (req > req_start && req[0] == req[-1])
7.487 - continue;
7.488 - entry = find_entry(importer->set, top, &pool[*req]);
7.489 - if (!entry)
7.490 - continue;
7.491 -
7.492 - for (pkg = list_first(&entry->packages, &importer->set->package_pool); pkg; pkg = list_next(pkg)) {
7.493 - prop = array_add(&importer->set->properties, sizeof *prop);
7.494 - prop->name = *req;
7.495 - prop->flags =
7.496 - RAZOR_PROPERTY_PROVIDES | RAZOR_PROPERTY_EQUAL;
7.497 - prop->version = hashtable_tokenize(&importer->table, "");
7.498 - list_set_ptr(&prop->packages, pkg->data);
7.499 -
7.500 - /* Update property list of pkg */
7.501 - array_init(&pkgprops);
7.502 - list_to_array(list_first(&packages[pkg->data].properties, &importer->set->property_pool), &pkgprops);
7.503 - newprop = array_add(&pkgprops, sizeof *newprop);
7.504 - *newprop = prop - (struct razor_property *)importer->set->properties.data;
7.505 - list_set_array(&packages[pkg->data].properties, &importer->set->property_pool, &pkgprops, 1);
7.506 - array_release(&pkgprops);
7.507 - }
7.508 - }
7.509 -
7.510 - array_release(&importer->file_requires);
7.511 -}
7.512 -
7.513 -static void
7.514 -build_package_file_lists(struct razor_set *set, uint32_t *rmap)
7.515 -{
7.516 - struct razor_package *p, *packages;
7.517 - struct array *pkgs;
7.518 - struct razor_entry *e, *end;
7.519 - struct list *r;
7.520 - uint32_t *q;
7.521 - int i, count;
7.522 -
7.523 - count = set->packages.size / sizeof *p;
7.524 - pkgs = zalloc(count * sizeof *pkgs);
7.525 -
7.526 - end = set->files.data + set->files.size;
7.527 - for (e = set->files.data; e < end; e++) {
7.528 - list_remap_head(&e->packages, rmap);
7.529 - r = list_first(&e->packages, &set->package_pool);
7.530 - while (r) {
7.531 - q = array_add(&pkgs[r->data], sizeof *q);
7.532 - *q = e - (struct razor_entry *) set->files.data;
7.533 - r = list_next(r);
7.534 - }
7.535 - }
7.536 -
7.537 - packages = set->packages.data;
7.538 - for (i = 0; i < count; i++) {
7.539 - list_set_array(&packages[i].files, &set->file_pool, &pkgs[i], 0);
7.540 - array_release(&pkgs[i]);
7.541 - }
7.542 - free(pkgs);
7.543 -}
7.544 -
7.545 -struct razor_set *
7.546 -razor_importer_finish(struct razor_importer *importer)
7.547 -{
7.548 - struct razor_set *set;
7.549 - uint32_t *map, *rmap;
7.550 - int i, count;
7.551 -
7.552 - build_file_tree(importer);
7.553 - find_file_provides(importer);
7.554 -
7.555 - map = uniqueify_properties(importer->set);
7.556 - list_remap_pool(&importer->set->property_pool, map);
7.557 - free(map);
7.558 -
7.559 - count = importer->set->packages.size / sizeof(struct razor_package);
7.560 - map = razor_qsort_with_data(importer->set->packages.data,
7.561 - count,
7.562 - sizeof(struct razor_package),
7.563 - compare_packages,
7.564 - importer->set);
7.565 -
7.566 - rmap = malloc(count * sizeof *rmap);
7.567 - for (i = 0; i < count; i++)
7.568 - rmap[map[i]] = i;
7.569 - free(map);
7.570 -
7.571 - list_remap_pool(&importer->set->package_pool, rmap);
7.572 - build_package_file_lists(importer->set, rmap);
7.573 - remap_property_package_links(&importer->set->properties, rmap);
7.574 - free(rmap);
7.575 -
7.576 - set = importer->set;
7.577 - hashtable_release(&importer->table);
7.578 - free(importer);
7.579 -
7.580 - return set;
7.581 -}
7.582 -
7.583 -struct razor_package_iterator {
7.584 - struct razor_set *set;
7.585 - struct razor_package *package, *end;
7.586 - struct list *index;
7.587 - int free_index;
7.588 -};
7.589 -
7.590 -static struct razor_package_iterator *
7.591 -razor_package_iterator_create_with_index(struct razor_set *set,
7.592 - struct list *index)
7.593 -{
7.594 - struct razor_package_iterator *pi;
7.595 -
7.596 - pi = zalloc(sizeof *pi);
7.597 - pi->set = set;
7.598 - pi->index = index;
7.599 -
7.600 - return pi;
7.601 -}
7.602 -
7.603 -struct razor_package_iterator *
7.604 -razor_package_iterator_create(struct razor_set *set)
7.605 -{
7.606 - struct razor_package_iterator *pi;
7.607 -
7.608 - pi = zalloc(sizeof *pi);
7.609 - pi->set = set;
7.610 - pi->end = set->packages.data + set->packages.size;
7.611 - pi->package = set->packages.data;
7.612 -
7.613 - return pi;
7.614 -}
7.615 -
7.616 -static void
7.617 -razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
7.618 - struct razor_set *set,
7.619 - struct razor_property *property)
7.620 -{
7.621 - memset(pi, 0, sizeof *pi);
7.622 - pi->set = set;
7.623 - pi->index = list_first(&property->packages, &set->package_pool);
7.624 -}
7.625 -
7.626 -struct razor_package_iterator *
7.627 -razor_package_iterator_create_for_property(struct razor_set *set,
7.628 - struct razor_property *property)
7.629 -{
7.630 - struct list *index;
7.631 -
7.632 - index = list_first(&property->packages, &set->package_pool);
7.633 - return razor_package_iterator_create_with_index(set, index);
7.634 -}
7.635 -
7.636 -int
7.637 -razor_package_iterator_next(struct razor_package_iterator *pi,
7.638 - struct razor_package **package,
7.639 - const char **name,
7.640 - const char **version,
7.641 - const char **arch)
7.642 -{
7.643 - char *pool;
7.644 - int valid;
7.645 - struct razor_package *p, *packages;
7.646 -
7.647 - if (pi->package) {
7.648 - p = pi->package++;
7.649 - valid = p < pi->end;
7.650 - } else if (pi->index) {
7.651 - packages = pi->set->packages.data;
7.652 - p = &packages[pi->index->data];
7.653 - pi->index = list_next(pi->index);
7.654 - valid = 1;
7.655 - } else
7.656 - valid = 0;
7.657 -
7.658 - if (valid) {
7.659 - pool = pi->set->string_pool.data;
7.660 - *package = p;
7.661 - *name = &pool[p->name];
7.662 - *version = &pool[p->version];
7.663 - *arch = &pool[p->arch];
7.664 - } else {
7.665 - *package = NULL;
7.666 - }
7.667 -
7.668 - return valid;
7.669 -}
7.670 -
7.671 -void
7.672 -razor_package_iterator_destroy(struct razor_package_iterator *pi)
7.673 -{
7.674 - if (pi->free_index)
7.675 - free(pi->index);
7.676 -
7.677 - free(pi);
7.678 -}
7.679 -
7.680 struct razor_package *
7.681 razor_set_get_package(struct razor_set *set, const char *package)
7.682 {
7.683 @@ -914,75 +269,9 @@
7.684 return p;
7.685 }
7.686
7.687 -struct razor_property_iterator {
7.688 - struct razor_set *set;
7.689 - struct razor_property *property, *end;
7.690 - struct list *index;
7.691 -};
7.692 -
7.693 -struct razor_property_iterator *
7.694 -razor_property_iterator_create(struct razor_set *set,
7.695 - struct razor_package *package)
7.696 -{
7.697 - struct razor_property_iterator *pi;
7.698 -
7.699 - pi = zalloc(sizeof *pi);
7.700 - pi->set = set;
7.701 -
7.702 - if (package) {
7.703 - pi->index = list_first(&package->properties,
7.704 - &set->property_pool);
7.705 - } else {
7.706 - pi->property = set->properties.data;
7.707 - pi->end = set->properties.data + set->properties.size;
7.708 - }
7.709 -
7.710 - return pi;
7.711 -}
7.712 -
7.713 -int
7.714 -razor_property_iterator_next(struct razor_property_iterator *pi,
7.715 - struct razor_property **property,
7.716 - const char **name,
7.717 - uint32_t *flags,
7.718 - const char **version)
7.719 -{
7.720 - char *pool;
7.721 - int valid;
7.722 - struct razor_property *p, *properties;
7.723 -
7.724 - if (pi->property) {
7.725 - p = pi->property++;
7.726 - valid = p < pi->end;
7.727 - } else if (pi->index) {
7.728 - properties = pi->set->properties.data;
7.729 - p = &properties[pi->index->data];
7.730 - pi->index = list_next(pi->index);
7.731 - valid = 1;
7.732 - } else
7.733 - valid = 0;
7.734 -
7.735 - if (valid) {
7.736 - pool = pi->set->string_pool.data;
7.737 - *property = p;
7.738 - *name = &pool[p->name];
7.739 - *flags = p->flags;
7.740 - *version = &pool[p->version];
7.741 - } else {
7.742 - *property = NULL;
7.743 - }
7.744 -
7.745 - return valid;
7.746 -}
7.747 -
7.748 -void
7.749 -razor_property_iterator_destroy(struct razor_property_iterator *pi)
7.750 -{
7.751 - free(pi);
7.752 -}
7.753 -
7.754 -static struct razor_entry *
7.755 -find_entry(struct razor_set *set, struct razor_entry *dir, const char *pattern)
7.756 +struct razor_entry *
7.757 +razor_set_find_entry(struct razor_set *set,
7.758 + struct razor_entry *dir, const char *pattern)
7.759 {
7.760 struct razor_entry *e;
7.761 const char *n, *pool = set->string_pool.data;
7.762 @@ -996,7 +285,7 @@
7.763 len = strlen(n);
7.764 if (e->start != 0 && strncmp(pattern + 1, n, len) == 0 &&
7.765 pattern[len + 1] == '/') {
7.766 - return find_entry(set, e, pattern + len + 1);
7.767 + return razor_set_find_entry(set, e, pattern + len + 1);
7.768 }
7.769 } while (!((e++)->flags & RAZOR_ENTRY_LAST));
7.770
7.771 @@ -1039,7 +328,7 @@
7.772 }
7.773
7.774 strcpy(buffer, pattern);
7.775 - e = find_entry(set, set->files.data, buffer);
7.776 + e = razor_set_find_entry(set, set->files.data, buffer);
7.777 if (e && e->start > 0) {
7.778 base = NULL;
7.779 } else {
7.780 @@ -1051,26 +340,11 @@
7.781 base = NULL;
7.782 }
7.783 }
7.784 - e = find_entry(set, set->files.data, buffer);
7.785 + e = razor_set_find_entry(set, set->files.data, buffer);
7.786 if (e->start != 0)
7.787 list_dir(set, e, buffer, base);
7.788 }
7.789
7.790 -struct razor_package_iterator *
7.791 -razor_package_iterator_create_for_file(struct razor_set *set,
7.792 - const char *filename)
7.793 -{
7.794 - struct razor_entry *entry;
7.795 - struct list *index;
7.796 -
7.797 - entry = find_entry(set, set->files.data, filename);
7.798 - if (entry == NULL)
7.799 - return NULL;
7.800 -
7.801 - index = list_first(&entry->packages, &set->package_pool);
7.802 - return razor_package_iterator_create_with_index(set, index);
7.803 -}
7.804 -
7.805 static struct list *
7.806 list_package_files(struct razor_set *set, struct list *r,
7.807 struct razor_entry *dir, uint32_t end,
7.808 @@ -1142,509 +416,6 @@
7.809 list_package_files(set, r, set->files.data, end, buffer);
7.810 }
7.811
7.812 -#define UPSTREAM_SOURCE 0x80
7.813 -
7.814 -struct source {
7.815 - struct razor_set *set;
7.816 - uint32_t *property_map;
7.817 - uint32_t *file_map;
7.818 -};
7.819 -
7.820 -struct razor_merger {
7.821 - struct razor_set *set;
7.822 - struct hashtable table;
7.823 - struct source source1;
7.824 - struct source source2;
7.825 -};
7.826 -
7.827 -static struct razor_merger *
7.828 -razor_merger_create(struct razor_set *set1, struct razor_set *set2)
7.829 -{
7.830 - struct razor_merger *merger;
7.831 - int count;
7.832 - size_t size;
7.833 -
7.834 - merger = zalloc(sizeof *merger);
7.835 - merger->set = razor_set_create();
7.836 - hashtable_init(&merger->table, &merger->set->string_pool);
7.837 -
7.838 - merger->source1.set = set1;
7.839 - count = set1->properties.size / sizeof (struct razor_property);
7.840 - size = count * sizeof merger->source1.property_map[0];
7.841 - merger->source1.property_map = zalloc(size);
7.842 - count = set1->files.size / sizeof (struct razor_entry);
7.843 - size = count * sizeof merger->source1.file_map[0];
7.844 - merger->source1.file_map = zalloc(size);
7.845 -
7.846 - merger->source2.set = set2;
7.847 - count = set2->properties.size / sizeof (struct razor_property);
7.848 - size = count * sizeof merger->source2.property_map[0];
7.849 - merger->source2.property_map = zalloc(size);
7.850 - count = set2->files.size / sizeof (struct razor_entry);
7.851 - size = count * sizeof merger->source2.file_map[0];
7.852 - merger->source2.file_map = zalloc(size);
7.853 -
7.854 - return merger;
7.855 -}
7.856 -
7.857 -static void
7.858 -razor_merger_add_package(struct razor_merger *merger,
7.859 - struct razor_package *package)
7.860 -{
7.861 - char *pool;
7.862 - struct list *r;
7.863 - struct razor_package *p;
7.864 - struct razor_set *set1;
7.865 - struct source *source;
7.866 - uint32_t flags;
7.867 -
7.868 - set1 = merger->source1.set;
7.869 - if (set1->packages.data <= (void *) package &&
7.870 - (void *) package < set1->packages.data + set1->packages.size) {
7.871 - source = &merger->source1;
7.872 - flags = 0;
7.873 - } else {
7.874 - source = &merger->source2;
7.875 - flags = UPSTREAM_SOURCE;
7.876 - }
7.877 -
7.878 - pool = source->set->string_pool.data;
7.879 - p = array_add(&merger->set->packages, sizeof *p);
7.880 - p->name = hashtable_tokenize(&merger->table, &pool[package->name]);
7.881 - p->flags = flags;
7.882 - p->version = hashtable_tokenize(&merger->table,
7.883 - &pool[package->version]);
7.884 - p->arch = hashtable_tokenize(&merger->table,
7.885 - &pool[package->arch]);
7.886 -
7.887 - p->properties = package->properties;
7.888 - r = list_first(&package->properties, &source->set->property_pool);
7.889 - while (r) {
7.890 - source->property_map[r->data] = 1;
7.891 - r = list_next(r);
7.892 - }
7.893 -
7.894 - p->files = package->files;
7.895 - r = list_first(&package->files, &source->set->file_pool);
7.896 - while (r) {
7.897 - source->file_map[r->data] = 1;
7.898 - r = list_next(r);
7.899 - }
7.900 -}
7.901 -
7.902 -static uint32_t
7.903 -add_property(struct razor_merger *merger,
7.904 - const char *name, uint32_t flags, const char *version)
7.905 -{
7.906 - struct razor_property *p;
7.907 -
7.908 - p = array_add(&merger->set->properties, sizeof *p);
7.909 - p->name = hashtable_tokenize(&merger->table, name);
7.910 - p->flags = flags;
7.911 - p->version = hashtable_tokenize(&merger->table, version);
7.912 -
7.913 - return p - (struct razor_property *) merger->set->properties.data;
7.914 -}
7.915 -
7.916 -static void
7.917 -merge_properties(struct razor_merger *merger)
7.918 -{
7.919 - struct razor_property *p1, *p2;
7.920 - struct razor_set *set1, *set2;
7.921 - uint32_t *map1, *map2;
7.922 - int i, j, cmp, count1, count2;
7.923 - char *pool1, *pool2;
7.924 -
7.925 - set1 = merger->source1.set;
7.926 - set2 = merger->source2.set;
7.927 - map1 = merger->source1.property_map;
7.928 - map2 = merger->source2.property_map;
7.929 -
7.930 - i = 0;
7.931 - j = 0;
7.932 - pool1 = set1->string_pool.data;
7.933 - pool2 = set2->string_pool.data;
7.934 -
7.935 - count1 = set1->properties.size / sizeof *p1;
7.936 - count2 = set2->properties.size / sizeof *p2;
7.937 - while (i < count1 || j < count2) {
7.938 - if (i < count1 && map1[i] == 0) {
7.939 - i++;
7.940 - continue;
7.941 - }
7.942 - if (j < count2 && map2[j] == 0) {
7.943 - j++;
7.944 - continue;
7.945 - }
7.946 - p1 = (struct razor_property *) set1->properties.data + i;
7.947 - p2 = (struct razor_property *) set2->properties.data + j;
7.948 - if (i < count1 && j < count2)
7.949 - cmp = strcmp(&pool1[p1->name], &pool2[p2->name]);
7.950 - else if (i < count1)
7.951 - cmp = -1;
7.952 - else
7.953 - cmp = 1;
7.954 - if (cmp == 0)
7.955 - cmp = p1->flags - p2->flags;
7.956 - if (cmp == 0)
7.957 - cmp = versioncmp(&pool1[p1->version],
7.958 - &pool2[p2->version]);
7.959 - if (cmp < 0) {
7.960 - map1[i++] = add_property(merger,
7.961 - &pool1[p1->name],
7.962 - p1->flags,
7.963 - &pool1[p1->version]);
7.964 - } else if (cmp > 0) {
7.965 - map2[j++] = add_property(merger,
7.966 - &pool2[p2->name],
7.967 - p2->flags,
7.968 - &pool2[p2->version]);
7.969 - } else {
7.970 - map1[i++] = map2[j++] =
7.971 - add_property(merger,
7.972 - &pool1[p1->name],
7.973 - p1->flags,
7.974 - &pool1[p1->version]);
7.975 - }
7.976 - }
7.977 -}
7.978 -
7.979 -static void
7.980 -emit_properties(struct list_head *properties, struct array *source_pool,
7.981 - uint32_t *map, struct array *pool)
7.982 -{
7.983 - uint32_t r;
7.984 - struct list *p, *q;
7.985 -
7.986 - r = pool->size / sizeof *q;
7.987 - p = list_first(properties, source_pool);
7.988 - while (p) {
7.989 - q = array_add(pool, sizeof *q);
7.990 - q->data = map[p->data];
7.991 - q->flags = p->flags;
7.992 - p = list_next(p);
7.993 - }
7.994 -
7.995 - list_set_ptr(properties, r);
7.996 -}
7.997 -
7.998 -static uint32_t
7.999 -add_file(struct razor_merger *merger, const char *name)
7.1000 -{
7.1001 - struct razor_entry *e;
7.1002 -
7.1003 - e = array_add(&merger->set->files, sizeof *e);
7.1004 - e->name = hashtable_tokenize(&merger->table, name);
7.1005 - e->flags = 0;
7.1006 - e->start = 0;
7.1007 -
7.1008 - return e - (struct razor_entry *)merger->set->files.data;
7.1009 -}
7.1010 -
7.1011 -/* FIXME. Blah */
7.1012 -static int
7.1013 -fix_file_map(uint32_t *map,
7.1014 - struct razor_entry *files,
7.1015 - struct razor_entry *top)
7.1016 -{
7.1017 - uint32_t e;
7.1018 - int found_file = 0;
7.1019 -
7.1020 - e = top->start;
7.1021 - do {
7.1022 - if (files[e].start)
7.1023 - fix_file_map(map, files, &files[e]);
7.1024 - if (map[e])
7.1025 - found_file = 1;
7.1026 - } while (!(files[e++].flags & RAZOR_ENTRY_LAST));
7.1027 -
7.1028 - if (found_file)
7.1029 - map[top - files] = 1;
7.1030 - return found_file;
7.1031 -}
7.1032 -
7.1033 -struct merge_directory {
7.1034 - uint32_t merged, dir1, dir2;
7.1035 -};
7.1036 -
7.1037 -static void
7.1038 -merge_one_directory(struct razor_merger *merger, struct merge_directory *md)
7.1039 -{
7.1040 - struct razor_entry *root1, *root2, *mroot, *e1, *e2;
7.1041 - struct razor_set *set1, *set2;
7.1042 - struct array merge_stack;
7.1043 - struct merge_directory *child_md, *end_md;
7.1044 - uint32_t *map1, *map2, start, last;
7.1045 - int cmp;
7.1046 - char *pool1, *pool2;
7.1047 -
7.1048 - set1 = merger->source1.set;
7.1049 - set2 = merger->source2.set;
7.1050 - map1 = merger->source1.file_map;
7.1051 - map2 = merger->source2.file_map;
7.1052 - pool1 = set1->string_pool.data;
7.1053 - pool2 = set2->string_pool.data;
7.1054 - root1 = (struct razor_entry *) set1->files.data;
7.1055 - root2 = (struct razor_entry *) set2->files.data;
7.1056 -
7.1057 - array_init(&merge_stack);
7.1058 -
7.1059 - start = merger->set->files.size / sizeof (struct razor_entry);
7.1060 - last = 0;
7.1061 - e1 = md->dir1 ? root1 + md->dir1 : NULL;
7.1062 - e2 = md->dir2 ? root2 + md->dir2 : NULL;
7.1063 - while (e1 || e2) {
7.1064 - if (!e2 && !map1[e1 - root1]) {
7.1065 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
7.1066 - e1 = NULL;
7.1067 - continue;
7.1068 - }
7.1069 - if (!e1 && !map2[e2 - root2]) {
7.1070 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
7.1071 - e2 = NULL;
7.1072 - continue;
7.1073 - }
7.1074 - if (e1 && !map1[e1 - root1] &&
7.1075 - e2 && !map1[e2 - root2]) {
7.1076 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
7.1077 - e1 = NULL;
7.1078 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
7.1079 - e2 = NULL;
7.1080 - continue;
7.1081 - }
7.1082 -
7.1083 - if (!e1)
7.1084 - cmp = 1;
7.1085 - else if (!e2)
7.1086 - cmp = -1;
7.1087 - else {
7.1088 - cmp = strcmp (&pool1[e1->name],
7.1089 - &pool2[e2->name]);
7.1090 - }
7.1091 -
7.1092 - if (cmp < 0) {
7.1093 - if (map1[e1 - root1]) {
7.1094 - map1[e1 - root1] = last =
7.1095 - add_file(merger, &pool1[e1->name]);
7.1096 - if (e1->start) {
7.1097 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
7.1098 - child_md->merged = last;
7.1099 - child_md->dir1 = e1->start;
7.1100 - child_md->dir2 = 0;
7.1101 - }
7.1102 - }
7.1103 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
7.1104 - e1 = NULL;
7.1105 - } else if (cmp > 0) {
7.1106 - if (map2[e2 - root2]) {
7.1107 - map2[e2 - root2] = last =
7.1108 - add_file(merger, &pool2[e2->name]);
7.1109 - if (e2->start) {
7.1110 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
7.1111 - child_md->merged = last;
7.1112 - child_md->dir1 = 0;
7.1113 - child_md->dir2 = e2->start;
7.1114 - }
7.1115 - }
7.1116 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
7.1117 - e2 = NULL;
7.1118 - } else {
7.1119 - map1[e1 - root1] = map2[e2- root2] = last =
7.1120 - add_file(merger, &pool1[e1->name]);
7.1121 - if (e1->start || e2->start) {
7.1122 - child_md = array_add(&merge_stack, sizeof (struct merge_directory));
7.1123 - child_md->merged = last;
7.1124 - child_md->dir1 = e1->start;
7.1125 - child_md->dir2 = e2->start;
7.1126 - }
7.1127 - if ((e1++)->flags & RAZOR_ENTRY_LAST)
7.1128 - e1 = NULL;
7.1129 - if ((e2++)->flags & RAZOR_ENTRY_LAST)
7.1130 - e2 = NULL;
7.1131 - }
7.1132 - }
7.1133 -
7.1134 - mroot = (struct razor_entry *)merger->set->files.data;
7.1135 - if (last) {
7.1136 - mroot[last].flags = RAZOR_ENTRY_LAST;
7.1137 - mroot[md->merged].start = start;
7.1138 - } else
7.1139 - mroot[md->merged].start = 0;
7.1140 -
7.1141 - end_md = merge_stack.data + merge_stack.size;
7.1142 - for (child_md = merge_stack.data; child_md < end_md; child_md++)
7.1143 - merge_one_directory(merger, child_md);
7.1144 - array_release(&merge_stack);
7.1145 -}
7.1146 -
7.1147 -static void
7.1148 -merge_files(struct razor_merger *merger)
7.1149 -{
7.1150 - struct razor_entry *root;
7.1151 - struct merge_directory md;
7.1152 - uint32_t *map1, *map2;
7.1153 -
7.1154 - map1 = merger->source1.file_map;
7.1155 - map2 = merger->source2.file_map;
7.1156 -
7.1157 - md.merged = 0;
7.1158 -
7.1159 - if (merger->source1.set->files.size) {
7.1160 - root = (struct razor_entry *) merger->source1.set->files.data;
7.1161 - if (root->start)
7.1162 - fix_file_map(map1, root, root);
7.1163 - md.dir1 = root->start;
7.1164 - } else
7.1165 - md.dir1 = 0;
7.1166 -
7.1167 - if (merger->source2.set->files.size) {
7.1168 - root = (struct razor_entry *) merger->source2.set->files.data;
7.1169 - if (root->start)
7.1170 - fix_file_map(map2, root, root);
7.1171 - md.dir2 = root->start;
7.1172 - } else
7.1173 - md.dir2 = 0;
7.1174 -
7.1175 - merge_one_directory(merger, &md);
7.1176 -}
7.1177 -
7.1178 -static void
7.1179 -emit_files(struct list_head *files, struct array *source_pool,
7.1180 - uint32_t *map, struct array *pool)
7.1181 -{
7.1182 - uint32_t r;
7.1183 - struct list *p, *q;
7.1184 -
7.1185 - r = pool->size / sizeof *q;
7.1186 - p = list_first(files, source_pool);
7.1187 - while (p) {
7.1188 - q = array_add(pool, sizeof *q);
7.1189 - q->data = map[p->data];
7.1190 - q->flags = p->flags;
7.1191 - p = list_next(p);
7.1192 - }
7.1193 -
7.1194 - list_set_ptr(files, r);
7.1195 -}
7.1196 -
7.1197 -/* Rebuild property->packages maps. We can't just remap these, as a
7.1198 - * property may have lost or gained a number of packages. Allocate an
7.1199 - * array per property and loop through the packages and add them to
7.1200 - * the arrays for their properties. */
7.1201 -static void
7.1202 -rebuild_property_package_lists(struct razor_set *set)
7.1203 -{
7.1204 - struct array *pkgs, *a;
7.1205 - struct razor_package *pkg, *pkg_end;
7.1206 - struct razor_property *prop, *prop_end;
7.1207 - struct list *r;
7.1208 - uint32_t *q;
7.1209 - int count;
7.1210 -
7.1211 - count = set->properties.size / sizeof (struct razor_property);
7.1212 - pkgs = zalloc(count * sizeof *pkgs);
7.1213 - pkg_end = set->packages.data + set->packages.size;
7.1214 -
7.1215 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
7.1216 - r = list_first(&pkg->properties, &set->property_pool);
7.1217 - while (r) {
7.1218 - q = array_add(&pkgs[r->data], sizeof *q);
7.1219 - *q = pkg - (struct razor_package *) set->packages.data;
7.1220 - r = list_next(r);
7.1221 - }
7.1222 - }
7.1223 -
7.1224 - prop_end = set->properties.data + set->properties.size;
7.1225 - a = pkgs;
7.1226 - for (prop = set->properties.data; prop < prop_end; prop++, a++) {
7.1227 - list_set_array(&prop->packages, &set->package_pool, a, 0);
7.1228 - array_release(a);
7.1229 - }
7.1230 - free(pkgs);
7.1231 -}
7.1232 -
7.1233 -static void
7.1234 -rebuild_file_package_lists(struct razor_set *set)
7.1235 -{
7.1236 - struct array *pkgs, *a;
7.1237 - struct razor_package *pkg, *pkg_end;
7.1238 - struct razor_entry *entry, *entry_end;
7.1239 - struct list *r;
7.1240 - uint32_t *q;
7.1241 - int count;
7.1242 -
7.1243 - count = set->files.size / sizeof (struct razor_entry);
7.1244 - pkgs = zalloc(count * sizeof *pkgs);
7.1245 - pkg_end = set->packages.data + set->packages.size;
7.1246 -
7.1247 - for (pkg = set->packages.data; pkg < pkg_end; pkg++) {
7.1248 - r = list_first(&pkg->files, &set->file_pool);
7.1249 - while (r) {
7.1250 - q = array_add(&pkgs[r->data], sizeof *q);
7.1251 - *q = pkg - (struct razor_package *) set->packages.data;
7.1252 - r = list_next(r);
7.1253 - }
7.1254 - }
7.1255 -
7.1256 - entry_end = set->files.data + set->files.size;
7.1257 - a = pkgs;
7.1258 - for (entry = set->files.data; entry < entry_end; entry++, a++) {
7.1259 - list_set_array(&entry->packages, &set->package_pool, a, 0);
7.1260 - array_release(a);
7.1261 - }
7.1262 - free(pkgs);
7.1263 -}
7.1264 -
7.1265 -static struct razor_set *
7.1266 -razor_merger_finish(struct razor_merger *merger)
7.1267 -{
7.1268 - struct razor_set *result;
7.1269 - struct razor_package *p, *pend;
7.1270 -
7.1271 - /* As we built the package list, we filled out a bitvector of
7.1272 - * the properties that are referenced by the packages in the
7.1273 - * new set. Now we do a parallel loop through the properties
7.1274 - * and emit those marked in the bit vector to the new set. In
7.1275 - * the process, we update the bit vector to actually map from
7.1276 - * indices in the old property list to indices in the new
7.1277 - * property list for both sets. */
7.1278 -
7.1279 - merge_properties(merger);
7.1280 - merge_files(merger);
7.1281 -
7.1282 - /* Now we loop through the packages again and emit the
7.1283 - * property lists, remapped to point to the new properties. */
7.1284 -
7.1285 - pend = merger->set->packages.data + merger->set->packages.size;
7.1286 - for (p = merger->set->packages.data; p < pend; p++) {
7.1287 - struct source *src;
7.1288 -
7.1289 - if (p->flags & UPSTREAM_SOURCE)
7.1290 - src = &merger->source2;
7.1291 - else
7.1292 - src = &merger->source1;
7.1293 -
7.1294 - emit_properties(&p->properties,
7.1295 - &src->set->property_pool,
7.1296 - src->property_map,
7.1297 - &merger->set->property_pool);
7.1298 - emit_files(&p->files,
7.1299 - &src->set->file_pool,
7.1300 - src->file_map,
7.1301 - &merger->set->file_pool);
7.1302 - p->flags &= ~UPSTREAM_SOURCE;
7.1303 - }
7.1304 -
7.1305 - rebuild_property_package_lists(merger->set);
7.1306 - rebuild_file_package_lists(merger->set);
7.1307 -
7.1308 - result = merger->set;
7.1309 - hashtable_release(&merger->table);
7.1310 - free(merger);
7.1311 -
7.1312 - return result;
7.1313 -}
7.1314 -
7.1315 /* The diff order matters. We should sort the packages so that a
7.1316 * REMOVE of a package comes before the INSTALL, and so that all
7.1317 * requires for a package have been installed before the package.
7.1318 @@ -1669,7 +440,7 @@
7.1319 if (p1 && p2) {
7.1320 res = strcmp(name1, name2);
7.1321 if (res == 0)
7.1322 - res = versioncmp(version1, version2);
7.1323 + res = razor_versioncmp(version1, version2);
7.1324 } else {
7.1325 res = 0;
7.1326 }
7.1327 @@ -1690,953 +461,3 @@
7.1328 razor_package_iterator_destroy(pi1);
7.1329 razor_package_iterator_destroy(pi2);
7.1330 }
7.1331 -
7.1332 -static int
7.1333 -provider_satisfies_requirement(struct razor_property *provider,
7.1334 - const char *provider_strings,
7.1335 - uint32_t flags,
7.1336 - const char *required)
7.1337 -{
7.1338 - int cmp, len;
7.1339 - const char *provided = &provider_strings[provider->version];
7.1340 -
7.1341 - if (!*required)
7.1342 - return 1;
7.1343 - if (!*provided) {
7.1344 - if (flags & RAZOR_PROPERTY_LESS)
7.1345 - return 0;
7.1346 - else
7.1347 - return 1;
7.1348 - }
7.1349 -
7.1350 - cmp = versioncmp(provided, required);
7.1351 -
7.1352 - switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
7.1353 - case RAZOR_PROPERTY_LESS:
7.1354 - return cmp < 0;
7.1355 -
7.1356 - case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
7.1357 - if (cmp <= 0)
7.1358 - return 1;
7.1359 - /* fall through: FIXME, make sure this is correct */
7.1360 -
7.1361 - case RAZOR_PROPERTY_EQUAL:
7.1362 - if (cmp == 0)
7.1363 - return 1;
7.1364 -
7.1365 - /* "foo == 1.1" is satisfied by "foo 1.1-2" */
7.1366 - len = strlen(required);
7.1367 - if (!strncmp(required, provided, len) && provided[len] == '-')
7.1368 - return 1;
7.1369 - return 0;
7.1370 -
7.1371 - case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
7.1372 - return cmp >= 0;
7.1373 -
7.1374 - case RAZOR_PROPERTY_GREATER:
7.1375 - return cmp > 0;
7.1376 - }
7.1377 -
7.1378 - /* shouldn't happen */
7.1379 - return 0;
7.1380 -}
7.1381 -
7.1382 -#define TRANS_PACKAGE_PRESENT 1
7.1383 -#define TRANS_PACKAGE_UPDATE 2
7.1384 -#define TRANS_PROPERTY_SATISFIED 0x80000000
7.1385 -
7.1386 -struct transaction_set {
7.1387 - struct razor_set *set;
7.1388 - uint32_t *packages;
7.1389 - uint32_t *properties;
7.1390 -};
7.1391 -
7.1392 -struct razor_transaction {
7.1393 - int package_count, errors;
7.1394 - struct transaction_set system, upstream;
7.1395 - int changes;
7.1396 -};
7.1397 -
7.1398 -static void
7.1399 -transaction_set_init(struct transaction_set *ts, struct razor_set *set)
7.1400 -{
7.1401 - int count;
7.1402 -
7.1403 - ts->set = set;
7.1404 - count = set->packages.size / sizeof (struct razor_package);
7.1405 - ts->packages = zalloc(count * sizeof *ts->packages);
7.1406 - count = set->properties.size / sizeof (struct razor_property);
7.1407 - ts->properties = zalloc(count * sizeof *ts->properties);
7.1408 -}
7.1409 -
7.1410 -static void
7.1411 -transaction_set_release(struct transaction_set *ts)
7.1412 -{
7.1413 - free(ts->packages);
7.1414 - free(ts->properties);
7.1415 -}
7.1416 -
7.1417 -static void
7.1418 -transaction_set_install_package(struct transaction_set *ts,
7.1419 - struct razor_package *package)
7.1420 -{
7.1421 - struct razor_package *pkgs;
7.1422 - struct list *prop;
7.1423 - int i;
7.1424 -
7.1425 - pkgs = ts->set->packages.data;
7.1426 - i = package - pkgs;
7.1427 - if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
7.1428 - return;
7.1429 -
7.1430 - ts->packages[i] = TRANS_PACKAGE_PRESENT;
7.1431 -
7.1432 - prop = list_first(&package->properties, &ts->set->property_pool);
7.1433 - while (prop) {
7.1434 - ts->properties[prop->data]++;
7.1435 - prop = list_next(prop);
7.1436 - }
7.1437 -}
7.1438 -
7.1439 -static void
7.1440 -transaction_set_remove_package(struct transaction_set *ts,
7.1441 - struct razor_package *package)
7.1442 -{
7.1443 - struct razor_package *pkgs;
7.1444 - struct list *prop;
7.1445 - int i;
7.1446 -
7.1447 - pkgs = ts->set->packages.data;
7.1448 - i = package - pkgs;
7.1449 - if (ts->packages[i] == 0)
7.1450 - return;
7.1451 -
7.1452 - ts->packages[i] = 0;
7.1453 -
7.1454 - prop = list_first(&package->properties, &ts->set->property_pool);
7.1455 - while (prop) {
7.1456 - ts->properties[prop->data]--;
7.1457 - prop = list_next(prop);
7.1458 - }
7.1459 -}
7.1460 -
7.1461 -struct razor_transaction *
7.1462 -razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
7.1463 -{
7.1464 - struct razor_transaction *trans;
7.1465 - struct razor_package *p, *spkgs, *pend;
7.1466 -
7.1467 - trans = zalloc(sizeof *trans);
7.1468 - transaction_set_init(&trans->system, system);
7.1469 - transaction_set_init(&trans->upstream, upstream);
7.1470 -
7.1471 - spkgs = trans->system.set->packages.data;
7.1472 - pend = trans->system.set->packages.data +
7.1473 - trans->system.set->packages.size;
7.1474 - for (p = spkgs; p < pend; p++)
7.1475 - transaction_set_install_package(&trans->system, p);
7.1476 -
7.1477 - return trans;
7.1478 -}
7.1479 -
7.1480 -void
7.1481 -razor_transaction_install_package(struct razor_transaction *trans,
7.1482 - struct razor_package *package)
7.1483 -{
7.1484 - transaction_set_install_package(&trans->upstream, package);
7.1485 - trans->changes++;
7.1486 -}
7.1487 -
7.1488 -void
7.1489 -razor_transaction_remove_package(struct razor_transaction *trans,
7.1490 - struct razor_package *package)
7.1491 -{
7.1492 - transaction_set_remove_package(&trans->system, package);
7.1493 - trans->changes++;
7.1494 -}
7.1495 -
7.1496 -void
7.1497 -razor_transaction_update_package(struct razor_transaction *trans,
7.1498 - struct razor_package *package)
7.1499 -{
7.1500 - struct razor_package *spkgs, *upkgs, *end;
7.1501 -
7.1502 - spkgs = trans->system.set->packages.data;
7.1503 - upkgs = trans->upstream.set->packages.data;
7.1504 - end = trans->system.set->packages.data +
7.1505 - trans->system.set->packages.size;
7.1506 - if (spkgs <= package && package < end)
7.1507 - trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
7.1508 - else
7.1509 - trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
7.1510 -}
7.1511 -
7.1512 -struct prop_iter {
7.1513 - struct razor_property *p, *start, *end;
7.1514 - const char *pool;
7.1515 - uint32_t *present;
7.1516 -};
7.1517 -
7.1518 -static void
7.1519 -prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
7.1520 -{
7.1521 - pi->p = ts->set->properties.data;
7.1522 - pi->start = ts->set->properties.data;
7.1523 - pi->end = ts->set->properties.data + ts->set->properties.size;
7.1524 - pi->pool = ts->set->string_pool.data;
7.1525 - pi->present = ts->properties;
7.1526 -}
7.1527 -
7.1528 -static int
7.1529 -prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
7.1530 -{
7.1531 - while (pi->p < pi->end) {
7.1532 - if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
7.1533 - (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
7.1534 - *p = pi->p++;
7.1535 - return 1;
7.1536 - }
7.1537 - pi->p++;
7.1538 - }
7.1539 -
7.1540 - return 0;
7.1541 -}
7.1542 -
7.1543 -static struct razor_property *
7.1544 -prop_iter_seek_to(struct prop_iter *pi,
7.1545 - uint32_t flags, const char *match)
7.1546 -{
7.1547 - uint32_t name;
7.1548 -
7.1549 - while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
7.1550 - pi->p++;
7.1551 -
7.1552 - if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
7.1553 - return NULL;
7.1554 -
7.1555 - name = pi->p->name;
7.1556 - while (pi->p < pi->end &&
7.1557 - pi->p->name == name &&
7.1558 - (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
7.1559 - pi->p++;
7.1560 -
7.1561 - if (pi->p == pi->end || pi->p->name != name)
7.1562 - return NULL;
7.1563 -
7.1564 - return pi->p;
7.1565 -}
7.1566 -
7.1567 -/* Remove packages from set that provide any of the matching (same
7.1568 - * name and type) providers from ppi onwards that match the
7.1569 - * requirement that rpi points to. */
7.1570 -static void
7.1571 -remove_matching_providers(struct razor_transaction *trans,
7.1572 - struct prop_iter *ppi,
7.1573 - uint32_t flags,
7.1574 - const char *version)
7.1575 -{
7.1576 - struct razor_property *p;
7.1577 - struct razor_package *pkg, *pkgs;
7.1578 - struct razor_package_iterator pkg_iter;
7.1579 - struct razor_set *set;
7.1580 - const char *n, *v, *a;
7.1581 - uint32_t type;
7.1582 -
7.1583 - if (ppi->present == trans->system.properties)
7.1584 - set = trans->system.set;
7.1585 - else
7.1586 - set = trans->upstream.set;
7.1587 -
7.1588 - pkgs = (struct razor_package *) set->packages.data;
7.1589 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
7.1590 - for (p = ppi->p;
7.1591 - p < ppi->end &&
7.1592 - p->name == ppi->p->name &&
7.1593 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
7.1594 - p++) {
7.1595 - if (!ppi->present[p - ppi->start])
7.1596 - continue;
7.1597 - if (!provider_satisfies_requirement(p, ppi->pool,
7.1598 - flags, version))
7.1599 - continue;
7.1600 -
7.1601 - razor_package_iterator_init_for_property(&pkg_iter, set, p);
7.1602 - while (razor_package_iterator_next(&pkg_iter,
7.1603 - &pkg, &n, &v, &a)) {
7.1604 - fprintf(stderr, "removing %s-%s\n", n, v);
7.1605 - razor_transaction_remove_package(trans, pkg);
7.1606 - }
7.1607 - }
7.1608 -}
7.1609 -
7.1610 -static void
7.1611 -flag_matching_providers(struct razor_transaction *trans,
7.1612 - struct prop_iter *ppi,
7.1613 - struct razor_property *r,
7.1614 - struct prop_iter *rpi,
7.1615 - unsigned int flag)
7.1616 -{
7.1617 - struct razor_property *p;
7.1618 - struct razor_package *pkg, *pkgs;
7.1619 - struct razor_package_iterator pkg_iter;
7.1620 - struct razor_set *set;
7.1621 - const char *name, *version, *arch;
7.1622 - uint32_t *flags, type;
7.1623 -
7.1624 - if (ppi->present == trans->system.properties) {
7.1625 - set = trans->system.set;
7.1626 - flags = trans->system.packages;
7.1627 - } else {
7.1628 - set = trans->upstream.set;
7.1629 - flags = trans->upstream.packages;
7.1630 - }
7.1631 -
7.1632 - pkgs = (struct razor_package *) set->packages.data;
7.1633 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
7.1634 - for (p = ppi->p;
7.1635 - p < ppi->end &&
7.1636 - p->name == ppi->p->name &&
7.1637 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
7.1638 - p++) {
7.1639 - if (!ppi->present[p - ppi->start])
7.1640 - continue;
7.1641 - if (!provider_satisfies_requirement(p, ppi->pool,
7.1642 - r->flags,
7.1643 - &rpi->pool[r->version]))
7.1644 - continue;
7.1645 -
7.1646 - razor_package_iterator_init_for_property(&pkg_iter, set, p);
7.1647 - while (razor_package_iterator_next(&pkg_iter, &pkg,
7.1648 - &name, &version, &arch)) {
7.1649 -
7.1650 - fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
7.1651 - name, version,
7.1652 - ppi->pool + p->name,
7.1653 - rpi->pool + r->name,
7.1654 - rpi->pool + r->version);
7.1655 - flags[pkg - pkgs] |= flag;
7.1656 - }
7.1657 - }
7.1658 -}
7.1659 -
7.1660 -static struct razor_package *
7.1661 -pick_matching_provider(struct razor_set *set,
7.1662 - struct prop_iter *ppi,
7.1663 - uint32_t flags,
7.1664 - const char *version)
7.1665 -{
7.1666 - struct razor_property *p;
7.1667 - struct razor_package *pkgs;
7.1668 - struct list *i;
7.1669 - uint32_t type;
7.1670 -
7.1671 - /* This is where we decide which pkgs to pull in to satisfy a
7.1672 - * requirement. There may be several different providers
7.1673 - * (different versions) and each version of a provider may
7.1674 - * come from a number of packages. We pick the first package
7.1675 - * from the first provider that matches. */
7.1676 -
7.1677 - pkgs = set->packages.data;
7.1678 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
7.1679 - for (p = ppi->p;
7.1680 - p < ppi->end &&
7.1681 - p->name == ppi->p->name &&
7.1682 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
7.1683 - ppi->present[p - ppi->start] == 0;
7.1684 - p++) {
7.1685 - if (!provider_satisfies_requirement(p, ppi->pool,
7.1686 - flags, version))
7.1687 - continue;
7.1688 -
7.1689 - i = list_first(&p->packages, &set->package_pool);
7.1690 -
7.1691 - return &pkgs[i->data];
7.1692 - }
7.1693 -
7.1694 - return NULL;
7.1695 -}
7.1696 -
7.1697 -static void
7.1698 -remove_obsoleted_packages(struct razor_transaction *trans)
7.1699 -{
7.1700 - struct razor_property *up;
7.1701 - struct razor_package *spkgs;
7.1702 - struct prop_iter spi, upi;
7.1703 -
7.1704 - spkgs = trans->system.set->packages.data;
7.1705 - prop_iter_init(&spi, &trans->system);
7.1706 - prop_iter_init(&upi, &trans->upstream);
7.1707 -
7.1708 - while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
7.1709 - if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
7.1710 - &upi.pool[up->name]))
7.1711 - continue;
7.1712 - remove_matching_providers(trans, &spi, up->flags,
7.1713 - &upi.pool[up->version]);
7.1714 - }
7.1715 -}
7.1716 -
7.1717 -static int
7.1718 -any_provider_satisfies_requirement(struct prop_iter *ppi,
7.1719 - uint32_t flags,
7.1720 - const char *version)
7.1721 -{
7.1722 - struct razor_property *p;
7.1723 - uint32_t type;
7.1724 -
7.1725 - type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
7.1726 - for (p = ppi->p;
7.1727 - p < ppi->end &&
7.1728 - p->name == ppi->p->name &&
7.1729 - (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
7.1730 - p++) {
7.1731 - if (ppi->present[p - ppi->start] > 0 &&
7.1732 - provider_satisfies_requirement(p, ppi->pool,
7.1733 - flags, version))
7.1734 - return 1;
7.1735 - }
7.1736 -
7.1737 - return 0;
7.1738 -}
7.1739 -
7.1740 -static void
7.1741 -clear_requires_flags(struct transaction_set *ts)
7.1742 -{
7.1743 - struct razor_property *p;
7.1744 - const char *pool;
7.1745 - int i, count;
7.1746 -
7.1747 - count = ts->set->properties.size / sizeof *p;
7.1748 - p = ts->set->properties.data;
7.1749 - pool = ts->set->string_pool.data;
7.1750 - for (i = 0; i < count; i++) {
7.1751 - ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
7.1752 - if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
7.1753 - ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
7.1754 - }
7.1755 -}
7.1756 -
7.1757 -const char *
7.1758 -razor_property_relation_to_string(struct razor_property *p)
7.1759 -{
7.1760 - switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
7.1761 - case RAZOR_PROPERTY_LESS:
7.1762 - return "<";
7.1763 -
7.1764 - case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
7.1765 - return "<=";
7.1766 -
7.1767 - case RAZOR_PROPERTY_EQUAL:
7.1768 - return "=";
7.1769 -
7.1770 - case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
7.1771 - return ">=";
7.1772 -
7.1773 - case RAZOR_PROPERTY_GREATER:
7.1774 - return ">";
7.1775 -
7.1776 - default:
7.1777 - return "?";
7.1778 - }
7.1779 -}
7.1780 -
7.1781 -const char *
7.1782 -razor_property_type_to_string(struct razor_property *p)
7.1783 -{
7.1784 - switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
7.1785 - case RAZOR_PROPERTY_REQUIRES:
7.1786 - return "requires";
7.1787 - case RAZOR_PROPERTY_PROVIDES:
7.1788 - return "provides";
7.1789 - case RAZOR_PROPERTY_CONFLICTS:
7.1790 - return "conflicts";
7.1791 - case RAZOR_PROPERTY_OBSOLETES:
7.1792 - return "obsoletes";
7.1793 - default:
7.1794 - return NULL;
7.1795 - }
7.1796 -}
7.1797 -
7.1798 -static void
7.1799 -mark_satisfied_requires(struct razor_transaction *trans,
7.1800 - struct transaction_set *rts,
7.1801 - struct transaction_set *pts)
7.1802 -{
7.1803 - struct prop_iter rpi, ppi;
7.1804 - struct razor_property *rp;
7.1805 -
7.1806 - prop_iter_init(&rpi, rts);
7.1807 - prop_iter_init(&ppi, pts);
7.1808 -
7.1809 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
7.1810 - if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
7.1811 - &rpi.pool[rp->name]))
7.1812 - continue;
7.1813 -
7.1814 - if (any_provider_satisfies_requirement(&ppi, rp->flags,
7.1815 - &rpi.pool[rp->version]))
7.1816 - rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
7.1817 - }
7.1818 -}
7.1819 -
7.1820 -static void
7.1821 -mark_all_satisfied_requires(struct razor_transaction *trans)
7.1822 -{
7.1823 - clear_requires_flags(&trans->system);
7.1824 - clear_requires_flags(&trans->upstream);
7.1825 - mark_satisfied_requires(trans, &trans->system, &trans->system);
7.1826 - mark_satisfied_requires(trans, &trans->system, &trans->upstream);
7.1827 - mark_satisfied_requires(trans, &trans->upstream, &trans->system);
7.1828 - mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
7.1829 -}
7.1830 -
7.1831 -static void
7.1832 -update_unsatisfied_packages(struct razor_transaction *trans)
7.1833 -{
7.1834 - struct razor_package *spkgs, *pkg;
7.1835 - struct razor_property *sp;
7.1836 - struct prop_iter spi;
7.1837 - struct razor_package_iterator pkg_iter;
7.1838 - const char *name, *version, *arch;
7.1839 -
7.1840 - spkgs = trans->system.set->packages.data;
7.1841 - prop_iter_init(&spi, &trans->system);
7.1842 -
7.1843 - while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
7.1844 - if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
7.1845 - continue;
7.1846 -
7.1847 - razor_package_iterator_init_for_property(&pkg_iter,
7.1848 - trans->system.set,
7.1849 - sp);
7.1850 - while (razor_package_iterator_next(&pkg_iter, &pkg,
7.1851 - &name, &version, &arch)) {
7.1852 - fprintf(stderr, "updating %s because %s %s %s "
7.1853 - "isn't satisfied\n",
7.1854 - name, spi.pool + sp->name,
7.1855 - razor_property_relation_to_string(sp),
7.1856 - spi.pool + sp->version);
7.1857 - trans->system.packages[pkg - spkgs] |=
7.1858 - TRANS_PACKAGE_UPDATE;
7.1859 - }
7.1860 - }
7.1861 -}
7.1862 -
7.1863 -void
7.1864 -razor_transaction_update_all(struct razor_transaction *trans)
7.1865 -{
7.1866 - struct razor_package *p;
7.1867 - int i, count;
7.1868 -
7.1869 - count = trans->system.set->packages.size / sizeof *p;
7.1870 - for (i = 0; i < count; i++)
7.1871 - trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
7.1872 -}
7.1873 -
7.1874 -static void
7.1875 -update_conflicted_packages(struct razor_transaction *trans)
7.1876 -{
7.1877 - struct razor_package *pkg, *spkgs;
7.1878 - struct razor_property *up, *sp;
7.1879 - struct prop_iter spi, upi;
7.1880 - struct razor_package_iterator pkg_iter;
7.1881 - const char *name, *version, *arch;
7.1882 -
7.1883 - spkgs = trans->system.set->packages.data;
7.1884 - prop_iter_init(&spi, &trans->system);
7.1885 - prop_iter_init(&upi, &trans->upstream);
7.1886 -
7.1887 - while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
7.1888 - if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
7.1889 - &spi.pool[sp->name]))
7.1890 - continue;
7.1891 -
7.1892 - if (!any_provider_satisfies_requirement(&upi, sp->flags,
7.1893 - &spi.pool[sp->version]))
7.1894 - continue;
7.1895 -
7.1896 - razor_package_iterator_init_for_property(&pkg_iter,
7.1897 - trans->system.set,
7.1898 - sp);
7.1899 - while (razor_package_iterator_next(&pkg_iter, &pkg,
7.1900 - &name, &version, &arch)) {
7.1901 - fprintf(stderr, "updating %s %s because it conflicts with %s",
7.1902 - name, version, spi.pool + sp->name);
7.1903 - trans->system.packages[pkg - spkgs] |=
7.1904 - TRANS_PACKAGE_UPDATE;
7.1905 - }
7.1906 - }
7.1907 -
7.1908 - prop_iter_init(&spi, &trans->system);
7.1909 - prop_iter_init(&upi, &trans->upstream);
7.1910 -
7.1911 - while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
7.1912 - sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
7.1913 - &upi.pool[upi.p->name]);
7.1914 -
7.1915 - if (sp)
7.1916 - flag_matching_providers(trans, &spi, up, &upi,
7.1917 - TRANS_PACKAGE_UPDATE);
7.1918 - }
7.1919 -}
7.1920 -
7.1921 -static void
7.1922 -pull_in_requirements(struct razor_transaction *trans,
7.1923 - struct prop_iter *rpi, struct prop_iter *ppi)
7.1924 -{
7.1925 - struct razor_property *rp, *pp;
7.1926 - struct razor_package *pkg, *upkgs;
7.1927 -
7.1928 - upkgs = trans->upstream.set->packages.data;
7.1929 - while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
7.1930 - if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
7.1931 - continue;
7.1932 -
7.1933 - pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
7.1934 - &rpi->pool[rp->name]);
7.1935 - if (pp == NULL)
7.1936 - continue;
7.1937 - pkg = pick_matching_provider(trans->upstream.set,
7.1938 - ppi, rp->flags,
7.1939 - &rpi->pool[rp->version]);
7.1940 - if (pkg == NULL)
7.1941 - continue;
7.1942 -
7.1943 - rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
7.1944 -
7.1945 - fprintf(stderr, "pulling in %s which provides %s %s %s "
7.1946 - "to satisfy %s %s %s\n",
7.1947 - ppi->pool + pkg->name,
7.1948 - ppi->pool + pp->name,
7.1949 - razor_property_relation_to_string(pp),
7.1950 - ppi->pool + pp->version,
7.1951 - &rpi->pool[rp->name],
7.1952 - razor_property_relation_to_string(rp),
7.1953 - &rpi->pool[rp->version]);
7.1954 -
7.1955 - trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
7.1956 - }
7.1957 -}
7.1958 -
7.1959 -static void
7.1960 -pull_in_all_requirements(struct razor_transaction *trans)
7.1961 -{
7.1962 - struct prop_iter rpi, ppi;
7.1963 -
7.1964 - prop_iter_init(&rpi, &trans->system);
7.1965 - prop_iter_init(&ppi, &trans->upstream);
7.1966 - pull_in_requirements(trans, &rpi, &ppi);
7.1967 -
7.1968 - prop_iter_init(&rpi, &trans->upstream);
7.1969 - prop_iter_init(&ppi, &trans->upstream);
7.1970 - pull_in_requirements(trans, &rpi, &ppi);
7.1971 -}
7.1972 -
7.1973 -static void
7.1974 -flush_scheduled_system_updates(struct razor_transaction *trans)
7.1975 -{
7.1976 - struct razor_package_iterator *pi;
7.1977 - struct razor_package *p, *pkg, *spkgs;
7.1978 - struct prop_iter ppi;
7.1979 - const char *name, *version, *arch;
7.1980 -
7.1981 - spkgs = trans->system.set->packages.data;
7.1982 - pi = razor_package_iterator_create(trans->system.set);
7.1983 - prop_iter_init(&ppi, &trans->upstream);
7.1984 -
7.1985 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
7.1986 - if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
7.1987 - continue;
7.1988 -
7.1989 - if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
7.1990 - continue;
7.1991 -
7.1992 - pkg = pick_matching_provider(trans->upstream.set, &ppi,
7.1993 - RAZOR_PROPERTY_GREATER, version);
7.1994 - if (pkg == NULL)
7.1995 - continue;
7.1996 -
7.1997 - fprintf(stderr, "updating %s-%s to %s-%s\n",
7.1998 - name, version,
7.1999 - &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
7.2000 -
7.2001 - razor_transaction_remove_package(trans, p);
7.2002 - razor_transaction_install_package(trans, pkg);
7.2003 - }
7.2004 -
7.2005 - razor_package_iterator_destroy(pi);
7.2006 -}
7.2007 -
7.2008 -static void
7.2009 -flush_scheduled_upstream_updates(struct razor_transaction *trans)
7.2010 -{
7.2011 - struct razor_package_iterator *pi;
7.2012 - struct razor_package *p, *upkgs;
7.2013 - struct prop_iter spi;
7.2014 - const char *name, *version, *arch;
7.2015 -
7.2016 - upkgs = trans->upstream.set->packages.data;
7.2017 - pi = razor_package_iterator_create(trans->upstream.set);
7.2018 - prop_iter_init(&spi, &trans->system);
7.2019 -
7.2020 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
7.2021 - if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
7.2022 - continue;
7.2023 -
7.2024 - if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
7.2025 - remove_matching_providers(trans,
7.2026 - &spi,
7.2027 - RAZOR_PROPERTY_LESS,
7.2028 - version);
7.2029 - razor_transaction_install_package(trans, p);
7.2030 - fprintf(stderr, "installing %s-%s\n", name, version);
7.2031 - }
7.2032 -}
7.2033 -
7.2034 -int
7.2035 -razor_transaction_resolve(struct razor_transaction *trans)
7.2036 -{
7.2037 - int last = 0;
7.2038 -
7.2039 - flush_scheduled_system_updates(trans);
7.2040 - flush_scheduled_upstream_updates(trans);
7.2041 -
7.2042 - while (last < trans->changes) {
7.2043 - last = trans->changes;
7.2044 - remove_obsoleted_packages(trans);
7.2045 - mark_all_satisfied_requires(trans);
7.2046 - update_unsatisfied_packages(trans);
7.2047 - update_conflicted_packages(trans);
7.2048 - pull_in_all_requirements(trans);
7.2049 - flush_scheduled_system_updates(trans);
7.2050 - flush_scheduled_upstream_updates(trans);
7.2051 - }
7.2052 -
7.2053 - return trans->changes;
7.2054 -}
7.2055 -
7.2056 -static void
7.2057 -describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
7.2058 -{
7.2059 - struct razor_package_iterator pi;
7.2060 - struct razor_package *pkg;
7.2061 - const char *name, *version, *arch, *pool;
7.2062 -
7.2063 - pool = set->string_pool.data;
7.2064 - if (pool[rp->version] == '\0') {
7.2065 - razor_package_iterator_init_for_property(&pi, set, rp);
7.2066 - while (razor_package_iterator_next(&pi, &pkg,
7.2067 - &name, &version, &arch))
7.2068 - fprintf(stderr, "%s is needed by %s-%s.%s\n",
7.2069 - &pool[rp->name],
7.2070 - name, version, arch);
7.2071 - } else {
7.2072 - razor_package_iterator_init_for_property(&pi, set, rp);
7.2073 - while (razor_package_iterator_next(&pi, &pkg,
7.2074 - &name, &version, &arch))
7.2075 - fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
7.2076 - &pool[rp->name],
7.2077 - razor_property_relation_to_string(rp),
7.2078 - &pool[rp->version],
7.2079 - name, version, arch);
7.2080 - }
7.2081 -}
7.2082 -
7.2083 -int
7.2084 -razor_transaction_describe(struct razor_transaction *trans)
7.2085 -{
7.2086 - struct prop_iter rpi;
7.2087 - struct razor_property *rp;
7.2088 - int unsatisfied;
7.2089 -
7.2090 - flush_scheduled_system_updates(trans);
7.2091 - flush_scheduled_upstream_updates(trans);
7.2092 - mark_all_satisfied_requires(trans);
7.2093 -
7.2094 - unsatisfied = 0;
7.2095 - prop_iter_init(&rpi, &trans->system);
7.2096 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
7.2097 - if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
7.2098 - describe_unsatisfied(trans->system.set, rp);
7.2099 - unsatisfied++;
7.2100 - }
7.2101 - }
7.2102 -
7.2103 - prop_iter_init(&rpi, &trans->upstream);
7.2104 - while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
7.2105 - if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
7.2106 - describe_unsatisfied(trans->upstream.set, rp);
7.2107 - unsatisfied++;
7.2108 - }
7.2109 - }
7.2110 -
7.2111 - return unsatisfied;
7.2112 -}
7.2113 -
7.2114 -int
7.2115 -razor_transaction_unsatisfied_property(struct razor_transaction *trans,
7.2116 - const char *name,
7.2117 - uint32_t flags,
7.2118 - const char *version)
7.2119 -{
7.2120 - struct prop_iter pi;
7.2121 - struct razor_property *p;
7.2122 -
7.2123 - prop_iter_init(&pi, &trans->system);
7.2124 - while (prop_iter_next(&pi, flags, &p)) {
7.2125 - if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
7.2126 - p->flags == flags &&
7.2127 - strcmp(&pi.pool[p->name], name) == 0 &&
7.2128 - strcmp(&pi.pool[p->version], version) == 0)
7.2129 -
7.2130 - return 1;
7.2131 - }
7.2132 -
7.2133 - prop_iter_init(&pi, &trans->upstream);
7.2134 - while (prop_iter_next(&pi, flags, &p)) {
7.2135 - if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
7.2136 - p->flags == flags &&
7.2137 - strcmp(&pi.pool[p->name], name) == 0 &&
7.2138 - strcmp(&pi.pool[p->version], version) == 0)
7.2139 -
7.2140 - return 1;
7.2141 - }
7.2142 -
7.2143 - return 0;
7.2144 -}
7.2145 -
7.2146 -struct razor_set *
7.2147 -razor_transaction_finish(struct razor_transaction *trans)
7.2148 -{
7.2149 - struct razor_merger *merger;
7.2150 - struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
7.2151 - char *upool, *spool;
7.2152 - int cmp;
7.2153 -
7.2154 - s = trans->system.set->packages.data;
7.2155 - spkgs = trans->system.set->packages.data;
7.2156 - send = trans->system.set->packages.data +
7.2157 - trans->system.set->packages.size;
7.2158 - spool = trans->system.set->string_pool.data;
7.2159 -
7.2160 - u = trans->upstream.set->packages.data;
7.2161 - upkgs = trans->upstream.set->packages.data;
7.2162 - uend = trans->upstream.set->packages.data +
7.2163 - trans->upstream.set->packages.size;
7.2164 - upool = trans->upstream.set->string_pool.data;
7.2165 -
7.2166 - merger = razor_merger_create(trans->system.set, trans->upstream.set);
7.2167 - while (s < send || u < uend) {
7.2168 - if (s < send && u < uend)
7.2169 - cmp = strcmp(&spool[s->name], &upool[u->name]);
7.2170 - else if (s < send)
7.2171 - cmp = -1;
7.2172 - else
7.2173 - cmp = 1;
7.2174 -
7.2175 - if (cmp < 0) {
7.2176 - if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
7.2177 - razor_merger_add_package(merger, s);
7.2178 - s++;
7.2179 - } else if (cmp == 0) {
7.2180 - if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
7.2181 - razor_merger_add_package(merger, s);
7.2182 - if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
7.2183 - razor_merger_add_package(merger, u);
7.2184 -
7.2185 - s++;
7.2186 - u++;
7.2187 - } else {
7.2188 - if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
7.2189 - razor_merger_add_package(merger, u);
7.2190 - u++;
7.2191 - }
7.2192 - }
7.2193 -
7.2194 - razor_transaction_destroy(trans);
7.2195 -
7.2196 - return razor_merger_finish(merger);
7.2197 -}
7.2198 -
7.2199 -void
7.2200 -razor_transaction_destroy(struct razor_transaction *trans)
7.2201 -{
7.2202 - transaction_set_release(&trans->system);
7.2203 - transaction_set_release(&trans->upstream);
7.2204 - free(trans);
7.2205 -}
7.2206 -
7.2207 -struct razor_package_query {
7.2208 - struct razor_set *set;
7.2209 - char *vector;
7.2210 - int count;
7.2211 -};
7.2212 -
7.2213 -struct razor_package_query *
7.2214 -razor_package_query_create(struct razor_set *set)
7.2215 -{
7.2216 - struct razor_package_query *pq;
7.2217 - int count;
7.2218 -
7.2219 - pq = zalloc(sizeof *pq);
7.2220 - pq->set = set;
7.2221 - count = set->packages.size / sizeof(struct razor_package);
7.2222 - pq->vector = zalloc(count * sizeof(char));
7.2223 -
7.2224 - return pq;
7.2225 -}
7.2226 -
7.2227 -void
7.2228 -razor_package_query_add_package(struct razor_package_query *pq,
7.2229 - struct razor_package *p)
7.2230 -{
7.2231 - struct razor_package *packages;
7.2232 -
7.2233 - packages = pq->set->packages.data;
7.2234 - pq->count += pq->vector[p - packages] ^ 1;
7.2235 - pq->vector[p - packages] = 1;
7.2236 -}
7.2237 -
7.2238 -void
7.2239 -razor_package_query_add_iterator(struct razor_package_query *pq,
7.2240 - struct razor_package_iterator *pi)
7.2241 -{
7.2242 - struct razor_package *packages, *p;
7.2243 - const char *name, *version, *arch;
7.2244 -
7.2245 - packages = pq->set->packages.data;
7.2246 - while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
7.2247 - pq->count += pq->vector[p - packages] ^ 1;
7.2248 - pq->vector[p - packages] = 1;
7.2249 - }
7.2250 -}
7.2251 -
7.2252 -struct razor_package_iterator *
7.2253 -razor_package_query_finish(struct razor_package_query *pq)
7.2254 -{
7.2255 - struct razor_package_iterator *pi;
7.2256 - struct razor_set *set;
7.2257 - struct list *index;
7.2258 - int i, j, count;
7.2259 -
7.2260 - set = pq->set;
7.2261 - count = set->packages.size / sizeof(struct razor_package);
7.2262 - index = zalloc(pq->count * sizeof *index);
7.2263 -
7.2264 - for (i = 0, j = 0; i < count; i++) {
7.2265 - if (!pq->vector[i])
7.2266 - continue;
7.2267 -
7.2268 - index[j].data = i;
7.2269 - if (j == pq->count - 1)
7.2270 - index[j].flags = 0x80;
7.2271 - j++;
7.2272 - }
7.2273 -
7.2274 - free(pq);
7.2275 -
7.2276 - pi = razor_package_iterator_create_with_index(set, index);
7.2277 - pi->free_index = 1;
7.2278 -
7.2279 - return pi;
7.2280 -}
8.1 --- a/librazor/razor.h Fri Jun 20 14:18:52 2008 -0400
8.2 +++ b/librazor/razor.h Fri Jun 20 15:10:34 2008 -0400
8.3 @@ -164,6 +164,7 @@
8.4
8.5 void razor_build_evr(char *evr_buf, int size, const char *epoch,
8.6 const char *version, const char *release);
8.7 +int razor_versioncmp(const char *s1, const char *s2);
8.8
8.9 struct razor_set *razor_set_create_from_yum(void);
8.10 struct razor_set *razor_set_create_from_rpmdb(void);
9.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
9.2 +++ b/librazor/root.c Fri Jun 20 15:10:34 2008 -0400
9.3 @@ -0,0 +1,168 @@
9.4 +#include <stdlib.h>
9.5 +#include <stdint.h>
9.6 +#include <stdio.h>
9.7 +#include <sys/stat.h>
9.8 +#include <dirent.h>
9.9 +#include <unistd.h>
9.10 +#include <fcntl.h>
9.11 +#include "razor.h"
9.12 +#include "razor-internal.h"
9.13 +
9.14 +static const char system_repo_filename[] = "system.repo";
9.15 +static const char next_repo_filename[] = "system-next.repo";
9.16 +static const char razor_root_path[] = "/var/lib/razor";
9.17 +
9.18 +struct razor_root {
9.19 + struct razor_set *system;
9.20 + struct razor_set *next;
9.21 + int fd;
9.22 + char path[PATH_MAX];
9.23 + char new_path[PATH_MAX];
9.24 +};
9.25 +
9.26 +int
9.27 +razor_root_create(const char *root)
9.28 +{
9.29 + struct stat buf;
9.30 + struct razor_set *set;
9.31 + char path[PATH_MAX];
9.32 +
9.33 + if (stat(root, &buf) < 0) {
9.34 + if (mkdir(root, 0777) < 0) {
9.35 + fprintf(stderr,
9.36 + "could not create install root \"%s\"\n",
9.37 + root);
9.38 + return -1;
9.39 + }
9.40 + fprintf(stderr, "created install root \"%s\"\n", root);
9.41 + } else if (!S_ISDIR(buf.st_mode)) {
9.42 + fprintf(stderr,
9.43 + "install root \"%s\" exists, but is not a directory\n",
9.44 + root);
9.45 + return -1;
9.46 + }
9.47 +
9.48 + snprintf(path, sizeof path, "%s/%s",
9.49 + razor_root_path, system_repo_filename);
9.50 + if (razor_create_dir(root, path) < 0) {
9.51 + fprintf(stderr, "could not create %s%s\n",
9.52 + root, razor_root_path);
9.53 + return -1;
9.54 + }
9.55 +
9.56 + set = razor_set_create();
9.57 + snprintf(path, sizeof path, "%s%s/%s",
9.58 + root, razor_root_path, system_repo_filename);
9.59 + if (stat(path, &buf) == 0) {
9.60 + fprintf(stderr,
9.61 + "a razor install root is already initialized\n");
9.62 + return -1;
9.63 + }
9.64 + if (razor_set_write(set, path) < 0) {
9.65 + fprintf(stderr, "could not write initial package set\n");
9.66 + return -1;
9.67 + }
9.68 + razor_set_destroy(set);
9.69 +
9.70 + return 0;
9.71 +}
9.72 +
9.73 +struct razor_root *
9.74 +razor_root_open(const char *root, int flags)
9.75 +{
9.76 + struct razor_root *image;
9.77 +
9.78 + image = malloc(sizeof *image);
9.79 + if (image == NULL)
9.80 + return NULL;
9.81 +
9.82 + /* Create the new next repo file up front to ensure exclusive
9.83 + * access. */
9.84 + snprintf(image->new_path, sizeof image->new_path,
9.85 + "%s%s/%s", root, razor_root_path, next_repo_filename);
9.86 + image->fd = open(image->new_path,
9.87 + O_CREAT | O_WRONLY | O_TRUNC | O_EXCL, 0666);
9.88 + if (image->fd < 0) {
9.89 + fprintf(stderr, "failed to get lock file, "
9.90 + "maybe previous operation crashed?\n");
9.91 +
9.92 + /* FIXME: Use fcntl advisory locking on the system
9.93 + * package set file to figure out whether previous
9.94 + * operation crashed or is still in progress. */
9.95 +
9.96 + free(image);
9.97 + return NULL;
9.98 + }
9.99 +
9.100 + snprintf(image->path, sizeof image->path,
9.101 + "%s%s/%s", root, razor_root_path, system_repo_filename);
9.102 + image->system = razor_set_open(image->path);
9.103 + if (image->system == NULL) {
9.104 + unlink(image->new_path);
9.105 + close(image->fd);
9.106 + free(image);
9.107 + return NULL;
9.108 + }
9.109 +
9.110 + return image;
9.111 +}
9.112 +
9.113 +struct razor_set *
9.114 +razor_root_open_read_only(const char *root)
9.115 +{
9.116 + char path[PATH_MAX];
9.117 +
9.118 + snprintf(path, sizeof path, "%s%s/%s",
9.119 + root, razor_root_path, system_repo_filename);
9.120 +
9.121 + return razor_set_open(path);
9.122 +}
9.123 +
9.124 +struct razor_transaction *
9.125 +razor_root_create_transaction(struct razor_root *image,
9.126 + struct razor_set *upstream)
9.127 +{
9.128 + /* FIXME: This should take a number of upstream repos. */
9.129 + return razor_transaction_create(image->system, upstream);
9.130 +}
9.131 +
9.132 +int
9.133 +razor_root_close(struct razor_root *image)
9.134 +{
9.135 + unlink(image->new_path);
9.136 + close(image->fd);
9.137 + free(image);
9.138 +
9.139 + return 0;
9.140 +}
9.141 +
9.142 +void
9.143 +razor_root_update(struct razor_root *root, struct razor_set *next)
9.144 +{
9.145 + razor_set_write_to_fd(next, root->fd);
9.146 + root->next = next;
9.147 +
9.148 + /* Sync the new repo file so the new package set is on disk
9.149 + * before we start upgrading. */
9.150 + fsync(root->fd);
9.151 + printf("wrote %s\n", root->new_path);
9.152 +}
9.153 +
9.154 +int
9.155 +razor_root_commit(struct razor_root *image)
9.156 +{
9.157 + /* Make it so. */
9.158 + rename(image->new_path, image->path);
9.159 + printf("renamed %s to %s\n", image->new_path, image->path);
9.160 + close(image->fd);
9.161 + free(image);
9.162 +
9.163 + return 0;
9.164 +}
9.165 +
9.166 +void
9.167 +razor_root_diff(struct razor_root *root,
9.168 + razor_package_callback_t callback, void *data)
9.169 +{
9.170 + return razor_set_diff(root->system, root->next, callback, data);
9.171 +}
10.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000
10.2 +++ b/librazor/transaction.c Fri Jun 20 15:10:34 2008 -0400
10.3 @@ -0,0 +1,912 @@
10.4 +/*
10.5 + * Copyright (C) 2008 Kristian Høgsberg <krh@redhat.com>
10.6 + * Copyright (C) 2008 Red Hat, Inc
10.7 + *
10.8 + * This program is free software; you can redistribute it and/or modify
10.9 + * it under the terms of the GNU General Public License as published by
10.10 + * the Free Software Foundation; either version 2 of the License, or
10.11 + * (at your option) any later version.
10.12 + *
10.13 + * This program is distributed in the hope that it will be useful,
10.14 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
10.15 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10.16 + * GNU General Public License for more details.
10.17 + *
10.18 + * You should have received a copy of the GNU General Public License along
10.19 + * with this program; if not, write to the Free Software Foundation, Inc.,
10.20 + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
10.21 + */
10.22 +
10.23 +#define _GNU_SOURCE
10.24 +
10.25 +#include <stdlib.h>
10.26 +#include <stddef.h>
10.27 +#include <stdint.h>
10.28 +#include <stdio.h>
10.29 +#include <string.h>
10.30 +#include <sys/types.h>
10.31 +#include <sys/stat.h>
10.32 +#include <sys/mman.h>
10.33 +#include <unistd.h>
10.34 +#include <fcntl.h>
10.35 +#include <errno.h>
10.36 +#include <ctype.h>
10.37 +#include <fnmatch.h>
10.38 +
10.39 +#include "razor-internal.h"
10.40 +#include "razor.h"
10.41 +
10.42 +static int
10.43 +provider_satisfies_requirement(struct razor_property *provider,
10.44 + const char *provider_strings,
10.45 + uint32_t flags,
10.46 + const char *required)
10.47 +{
10.48 + int cmp, len;
10.49 + const char *provided = &provider_strings[provider->version];
10.50 +
10.51 + if (!*required)
10.52 + return 1;
10.53 + if (!*provided) {
10.54 + if (flags & RAZOR_PROPERTY_LESS)
10.55 + return 0;
10.56 + else
10.57 + return 1;
10.58 + }
10.59 +
10.60 + cmp = razor_versioncmp(provided, required);
10.61 +
10.62 + switch (flags & RAZOR_PROPERTY_RELATION_MASK) {
10.63 + case RAZOR_PROPERTY_LESS:
10.64 + return cmp < 0;
10.65 +
10.66 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
10.67 + if (cmp <= 0)
10.68 + return 1;
10.69 + /* fall through: FIXME, make sure this is correct */
10.70 +
10.71 + case RAZOR_PROPERTY_EQUAL:
10.72 + if (cmp == 0)
10.73 + return 1;
10.74 +
10.75 + /* "foo == 1.1" is satisfied by "foo 1.1-2" */
10.76 + len = strlen(required);
10.77 + if (!strncmp(required, provided, len) && provided[len] == '-')
10.78 + return 1;
10.79 + return 0;
10.80 +
10.81 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
10.82 + return cmp >= 0;
10.83 +
10.84 + case RAZOR_PROPERTY_GREATER:
10.85 + return cmp > 0;
10.86 + }
10.87 +
10.88 + /* shouldn't happen */
10.89 + return 0;
10.90 +}
10.91 +
10.92 +#define TRANS_PACKAGE_PRESENT 1
10.93 +#define TRANS_PACKAGE_UPDATE 2
10.94 +#define TRANS_PROPERTY_SATISFIED 0x80000000
10.95 +
10.96 +struct transaction_set {
10.97 + struct razor_set *set;
10.98 + uint32_t *packages;
10.99 + uint32_t *properties;
10.100 +};
10.101 +
10.102 +struct razor_transaction {
10.103 + int package_count, errors;
10.104 + struct transaction_set system, upstream;
10.105 + int changes;
10.106 +};
10.107 +
10.108 +static void
10.109 +transaction_set_init(struct transaction_set *ts, struct razor_set *set)
10.110 +{
10.111 + int count;
10.112 +
10.113 + ts->set = set;
10.114 + count = set->packages.size / sizeof (struct razor_package);
10.115 + ts->packages = zalloc(count * sizeof *ts->packages);
10.116 + count = set->properties.size / sizeof (struct razor_property);
10.117 + ts->properties = zalloc(count * sizeof *ts->properties);
10.118 +}
10.119 +
10.120 +static void
10.121 +transaction_set_release(struct transaction_set *ts)
10.122 +{
10.123 + free(ts->packages);
10.124 + free(ts->properties);
10.125 +}
10.126 +
10.127 +static void
10.128 +transaction_set_install_package(struct transaction_set *ts,
10.129 + struct razor_package *package)
10.130 +{
10.131 + struct razor_package *pkgs;
10.132 + struct list *prop;
10.133 + int i;
10.134 +
10.135 + pkgs = ts->set->packages.data;
10.136 + i = package - pkgs;
10.137 + if (ts->packages[i] == TRANS_PACKAGE_PRESENT)
10.138 + return;
10.139 +
10.140 + ts->packages[i] = TRANS_PACKAGE_PRESENT;
10.141 +
10.142 + prop = list_first(&package->properties, &ts->set->property_pool);
10.143 + while (prop) {
10.144 + ts->properties[prop->data]++;
10.145 + prop = list_next(prop);
10.146 + }
10.147 +}
10.148 +
10.149 +static void
10.150 +transaction_set_remove_package(struct transaction_set *ts,
10.151 + struct razor_package *package)
10.152 +{
10.153 + struct razor_package *pkgs;
10.154 + struct list *prop;
10.155 + int i;
10.156 +
10.157 + pkgs = ts->set->packages.data;
10.158 + i = package - pkgs;
10.159 + if (ts->packages[i] == 0)
10.160 + return;
10.161 +
10.162 + ts->packages[i] = 0;
10.163 +
10.164 + prop = list_first(&package->properties, &ts->set->property_pool);
10.165 + while (prop) {
10.166 + ts->properties[prop->data]--;
10.167 + prop = list_next(prop);
10.168 + }
10.169 +}
10.170 +
10.171 +struct razor_transaction *
10.172 +razor_transaction_create(struct razor_set *system, struct razor_set *upstream)
10.173 +{
10.174 + struct razor_transaction *trans;
10.175 + struct razor_package *p, *spkgs, *pend;
10.176 +
10.177 + trans = zalloc(sizeof *trans);
10.178 + transaction_set_init(&trans->system, system);
10.179 + transaction_set_init(&trans->upstream, upstream);
10.180 +
10.181 + spkgs = trans->system.set->packages.data;
10.182 + pend = trans->system.set->packages.data +
10.183 + trans->system.set->packages.size;
10.184 + for (p = spkgs; p < pend; p++)
10.185 + transaction_set_install_package(&trans->system, p);
10.186 +
10.187 + return trans;
10.188 +}
10.189 +
10.190 +void
10.191 +razor_transaction_install_package(struct razor_transaction *trans,
10.192 + struct razor_package *package)
10.193 +{
10.194 + transaction_set_install_package(&trans->upstream, package);
10.195 + trans->changes++;
10.196 +}
10.197 +
10.198 +void
10.199 +razor_transaction_remove_package(struct razor_transaction *trans,
10.200 + struct razor_package *package)
10.201 +{
10.202 + transaction_set_remove_package(&trans->system, package);
10.203 + trans->changes++;
10.204 +}
10.205 +
10.206 +void
10.207 +razor_transaction_update_package(struct razor_transaction *trans,
10.208 + struct razor_package *package)
10.209 +{
10.210 + struct razor_package *spkgs, *upkgs, *end;
10.211 +
10.212 + spkgs = trans->system.set->packages.data;
10.213 + upkgs = trans->upstream.set->packages.data;
10.214 + end = trans->system.set->packages.data +
10.215 + trans->system.set->packages.size;
10.216 + if (spkgs <= package && package < end)
10.217 + trans->system.packages[package - spkgs] |= TRANS_PACKAGE_UPDATE;
10.218 + else
10.219 + trans->upstream.packages[package - upkgs] |= TRANS_PACKAGE_UPDATE;
10.220 +}
10.221 +
10.222 +struct prop_iter {
10.223 + struct razor_property *p, *start, *end;
10.224 + const char *pool;
10.225 + uint32_t *present;
10.226 +};
10.227 +
10.228 +static void
10.229 +prop_iter_init(struct prop_iter *pi, struct transaction_set *ts)
10.230 +{
10.231 + pi->p = ts->set->properties.data;
10.232 + pi->start = ts->set->properties.data;
10.233 + pi->end = ts->set->properties.data + ts->set->properties.size;
10.234 + pi->pool = ts->set->string_pool.data;
10.235 + pi->present = ts->properties;
10.236 +}
10.237 +
10.238 +static int
10.239 +prop_iter_next(struct prop_iter *pi, uint32_t flags, struct razor_property **p)
10.240 +{
10.241 + while (pi->p < pi->end) {
10.242 + if ((pi->present[pi->p - pi->start] & ~TRANS_PROPERTY_SATISFIED) &&
10.243 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) == flags) {
10.244 + *p = pi->p++;
10.245 + return 1;
10.246 + }
10.247 + pi->p++;
10.248 + }
10.249 +
10.250 + return 0;
10.251 +}
10.252 +
10.253 +static struct razor_property *
10.254 +prop_iter_seek_to(struct prop_iter *pi,
10.255 + uint32_t flags, const char *match)
10.256 +{
10.257 + uint32_t name;
10.258 +
10.259 + while (pi->p < pi->end && strcmp(&pi->pool[pi->p->name], match) < 0)
10.260 + pi->p++;
10.261 +
10.262 + if (pi->p == pi->end || strcmp(&pi->pool[pi->p->name], match) > 0)
10.263 + return NULL;
10.264 +
10.265 + name = pi->p->name;
10.266 + while (pi->p < pi->end &&
10.267 + pi->p->name == name &&
10.268 + (pi->p->flags & RAZOR_PROPERTY_TYPE_MASK) != flags)
10.269 + pi->p++;
10.270 +
10.271 + if (pi->p == pi->end || pi->p->name != name)
10.272 + return NULL;
10.273 +
10.274 + return pi->p;
10.275 +}
10.276 +
10.277 +/* Remove packages from set that provide any of the matching (same
10.278 + * name and type) providers from ppi onwards that match the
10.279 + * requirement that rpi points to. */
10.280 +static void
10.281 +remove_matching_providers(struct razor_transaction *trans,
10.282 + struct prop_iter *ppi,
10.283 + uint32_t flags,
10.284 + const char *version)
10.285 +{
10.286 + struct razor_property *p;
10.287 + struct razor_package *pkg, *pkgs;
10.288 + struct razor_package_iterator pkg_iter;
10.289 + struct razor_set *set;
10.290 + const char *n, *v, *a;
10.291 + uint32_t type;
10.292 +
10.293 + if (ppi->present == trans->system.properties)
10.294 + set = trans->system.set;
10.295 + else
10.296 + set = trans->upstream.set;
10.297 +
10.298 + pkgs = (struct razor_package *) set->packages.data;
10.299 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
10.300 + for (p = ppi->p;
10.301 + p < ppi->end &&
10.302 + p->name == ppi->p->name &&
10.303 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
10.304 + p++) {
10.305 + if (!ppi->present[p - ppi->start])
10.306 + continue;
10.307 + if (!provider_satisfies_requirement(p, ppi->pool,
10.308 + flags, version))
10.309 + continue;
10.310 +
10.311 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
10.312 + while (razor_package_iterator_next(&pkg_iter,
10.313 + &pkg, &n, &v, &a)) {
10.314 + fprintf(stderr, "removing %s-%s\n", n, v);
10.315 + razor_transaction_remove_package(trans, pkg);
10.316 + }
10.317 + }
10.318 +}
10.319 +
10.320 +static void
10.321 +flag_matching_providers(struct razor_transaction *trans,
10.322 + struct prop_iter *ppi,
10.323 + struct razor_property *r,
10.324 + struct prop_iter *rpi,
10.325 + unsigned int flag)
10.326 +{
10.327 + struct razor_property *p;
10.328 + struct razor_package *pkg, *pkgs;
10.329 + struct razor_package_iterator pkg_iter;
10.330 + struct razor_set *set;
10.331 + const char *name, *version, *arch;
10.332 + uint32_t *flags, type;
10.333 +
10.334 + if (ppi->present == trans->system.properties) {
10.335 + set = trans->system.set;
10.336 + flags = trans->system.packages;
10.337 + } else {
10.338 + set = trans->upstream.set;
10.339 + flags = trans->upstream.packages;
10.340 + }
10.341 +
10.342 + pkgs = (struct razor_package *) set->packages.data;
10.343 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
10.344 + for (p = ppi->p;
10.345 + p < ppi->end &&
10.346 + p->name == ppi->p->name &&
10.347 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
10.348 + p++) {
10.349 + if (!ppi->present[p - ppi->start])
10.350 + continue;
10.351 + if (!provider_satisfies_requirement(p, ppi->pool,
10.352 + r->flags,
10.353 + &rpi->pool[r->version]))
10.354 + continue;
10.355 +
10.356 + razor_package_iterator_init_for_property(&pkg_iter, set, p);
10.357 + while (razor_package_iterator_next(&pkg_iter, &pkg,
10.358 + &name, &version, &arch)) {
10.359 +
10.360 + fprintf(stderr, "flagging %s-%s for providing %s matching %s %s\n",
10.361 + name, version,
10.362 + ppi->pool + p->name,
10.363 + rpi->pool + r->name,
10.364 + rpi->pool + r->version);
10.365 + flags[pkg - pkgs] |= flag;
10.366 + }
10.367 + }
10.368 +}
10.369 +
10.370 +static struct razor_package *
10.371 +pick_matching_provider(struct razor_set *set,
10.372 + struct prop_iter *ppi,
10.373 + uint32_t flags,
10.374 + const char *version)
10.375 +{
10.376 + struct razor_property *p;
10.377 + struct razor_package *pkgs;
10.378 + struct list *i;
10.379 + uint32_t type;
10.380 +
10.381 + /* This is where we decide which pkgs to pull in to satisfy a
10.382 + * requirement. There may be several different providers
10.383 + * (different versions) and each version of a provider may
10.384 + * come from a number of packages. We pick the first package
10.385 + * from the first provider that matches. */
10.386 +
10.387 + pkgs = set->packages.data;
10.388 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
10.389 + for (p = ppi->p;
10.390 + p < ppi->end &&
10.391 + p->name == ppi->p->name &&
10.392 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type &&
10.393 + ppi->present[p - ppi->start] == 0;
10.394 + p++) {
10.395 + if (!provider_satisfies_requirement(p, ppi->pool,
10.396 + flags, version))
10.397 + continue;
10.398 +
10.399 + i = list_first(&p->packages, &set->package_pool);
10.400 +
10.401 + return &pkgs[i->data];
10.402 + }
10.403 +
10.404 + return NULL;
10.405 +}
10.406 +
10.407 +static void
10.408 +remove_obsoleted_packages(struct razor_transaction *trans)
10.409 +{
10.410 + struct razor_property *up;
10.411 + struct razor_package *spkgs;
10.412 + struct prop_iter spi, upi;
10.413 +
10.414 + spkgs = trans->system.set->packages.data;
10.415 + prop_iter_init(&spi, &trans->system);
10.416 + prop_iter_init(&upi, &trans->upstream);
10.417 +
10.418 + while (prop_iter_next(&upi, RAZOR_PROPERTY_OBSOLETES, &up)) {
10.419 + if (!prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
10.420 + &upi.pool[up->name]))
10.421 + continue;
10.422 + remove_matching_providers(trans, &spi, up->flags,
10.423 + &upi.pool[up->version]);
10.424 + }
10.425 +}
10.426 +
10.427 +static int
10.428 +any_provider_satisfies_requirement(struct prop_iter *ppi,
10.429 + uint32_t flags,
10.430 + const char *version)
10.431 +{
10.432 + struct razor_property *p;
10.433 + uint32_t type;
10.434 +
10.435 + type = ppi->p->flags & RAZOR_PROPERTY_TYPE_MASK;
10.436 + for (p = ppi->p;
10.437 + p < ppi->end &&
10.438 + p->name == ppi->p->name &&
10.439 + (p->flags & RAZOR_PROPERTY_TYPE_MASK) == type;
10.440 + p++) {
10.441 + if (ppi->present[p - ppi->start] > 0 &&
10.442 + provider_satisfies_requirement(p, ppi->pool,
10.443 + flags, version))
10.444 + return 1;
10.445 + }
10.446 +
10.447 + return 0;
10.448 +}
10.449 +
10.450 +static void
10.451 +clear_requires_flags(struct transaction_set *ts)
10.452 +{
10.453 + struct razor_property *p;
10.454 + const char *pool;
10.455 + int i, count;
10.456 +
10.457 + count = ts->set->properties.size / sizeof *p;
10.458 + p = ts->set->properties.data;
10.459 + pool = ts->set->string_pool.data;
10.460 + for (i = 0; i < count; i++) {
10.461 + ts->properties[i] &= ~TRANS_PROPERTY_SATISFIED;
10.462 + if (strncmp(&pool[p[i].name], "rpmlib(", 7) == 0)
10.463 + ts->properties[i] |= TRANS_PROPERTY_SATISFIED;
10.464 + }
10.465 +}
10.466 +
10.467 +const char *
10.468 +razor_property_relation_to_string(struct razor_property *p)
10.469 +{
10.470 + switch (p->flags & RAZOR_PROPERTY_RELATION_MASK) {
10.471 + case RAZOR_PROPERTY_LESS:
10.472 + return "<";
10.473 +
10.474 + case RAZOR_PROPERTY_LESS | RAZOR_PROPERTY_EQUAL:
10.475 + return "<=";
10.476 +
10.477 + case RAZOR_PROPERTY_EQUAL:
10.478 + return "=";
10.479 +
10.480 + case RAZOR_PROPERTY_GREATER | RAZOR_PROPERTY_EQUAL:
10.481 + return ">=";
10.482 +
10.483 + case RAZOR_PROPERTY_GREATER:
10.484 + return ">";
10.485 +
10.486 + default:
10.487 + return "?";
10.488 + }
10.489 +}
10.490 +
10.491 +const char *
10.492 +razor_property_type_to_string(struct razor_property *p)
10.493 +{
10.494 + switch (p->flags & RAZOR_PROPERTY_TYPE_MASK) {
10.495 + case RAZOR_PROPERTY_REQUIRES:
10.496 + return "requires";
10.497 + case RAZOR_PROPERTY_PROVIDES:
10.498 + return "provides";
10.499 + case RAZOR_PROPERTY_CONFLICTS:
10.500 + return "conflicts";
10.501 + case RAZOR_PROPERTY_OBSOLETES:
10.502 + return "obsoletes";
10.503 + default:
10.504 + return NULL;
10.505 + }
10.506 +}
10.507 +
10.508 +static void
10.509 +mark_satisfied_requires(struct razor_transaction *trans,
10.510 + struct transaction_set *rts,
10.511 + struct transaction_set *pts)
10.512 +{
10.513 + struct prop_iter rpi, ppi;
10.514 + struct razor_property *rp;
10.515 +
10.516 + prop_iter_init(&rpi, rts);
10.517 + prop_iter_init(&ppi, pts);
10.518 +
10.519 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
10.520 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES,
10.521 + &rpi.pool[rp->name]))
10.522 + continue;
10.523 +
10.524 + if (any_provider_satisfies_requirement(&ppi, rp->flags,
10.525 + &rpi.pool[rp->version]))
10.526 + rpi.present[rp - rpi.start] |= TRANS_PROPERTY_SATISFIED;
10.527 + }
10.528 +}
10.529 +
10.530 +static void
10.531 +mark_all_satisfied_requires(struct razor_transaction *trans)
10.532 +{
10.533 + clear_requires_flags(&trans->system);
10.534 + clear_requires_flags(&trans->upstream);
10.535 + mark_satisfied_requires(trans, &trans->system, &trans->system);
10.536 + mark_satisfied_requires(trans, &trans->system, &trans->upstream);
10.537 + mark_satisfied_requires(trans, &trans->upstream, &trans->system);
10.538 + mark_satisfied_requires(trans, &trans->upstream, &trans->upstream);
10.539 +}
10.540 +
10.541 +static void
10.542 +update_unsatisfied_packages(struct razor_transaction *trans)
10.543 +{
10.544 + struct razor_package *spkgs, *pkg;
10.545 + struct razor_property *sp;
10.546 + struct prop_iter spi;
10.547 + struct razor_package_iterator pkg_iter;
10.548 + const char *name, *version, *arch;
10.549 +
10.550 + spkgs = trans->system.set->packages.data;
10.551 + prop_iter_init(&spi, &trans->system);
10.552 +
10.553 + while (prop_iter_next(&spi, RAZOR_PROPERTY_REQUIRES, &sp)) {
10.554 + if (spi.present[sp - spi.start] & TRANS_PROPERTY_SATISFIED)
10.555 + continue;
10.556 +
10.557 + razor_package_iterator_init_for_property(&pkg_iter,
10.558 + trans->system.set,
10.559 + sp);
10.560 + while (razor_package_iterator_next(&pkg_iter, &pkg,
10.561 + &name, &version, &arch)) {
10.562 + fprintf(stderr, "updating %s because %s %s %s "
10.563 + "isn't satisfied\n",
10.564 + name, spi.pool + sp->name,
10.565 + razor_property_relation_to_string(sp),
10.566 + spi.pool + sp->version);
10.567 + trans->system.packages[pkg - spkgs] |=
10.568 + TRANS_PACKAGE_UPDATE;
10.569 + }
10.570 + }
10.571 +}
10.572 +
10.573 +void
10.574 +razor_transaction_update_all(struct razor_transaction *trans)
10.575 +{
10.576 + struct razor_package *p;
10.577 + int i, count;
10.578 +
10.579 + count = trans->system.set->packages.size / sizeof *p;
10.580 + for (i = 0; i < count; i++)
10.581 + trans->system.packages[i] |= TRANS_PACKAGE_UPDATE;
10.582 +}
10.583 +
10.584 +static void
10.585 +update_conflicted_packages(struct razor_transaction *trans)
10.586 +{
10.587 + struct razor_package *pkg, *spkgs;
10.588 + struct razor_property *up, *sp;
10.589 + struct prop_iter spi, upi;
10.590 + struct razor_package_iterator pkg_iter;
10.591 + const char *name, *version, *arch;
10.592 +
10.593 + spkgs = trans->system.set->packages.data;
10.594 + prop_iter_init(&spi, &trans->system);
10.595 + prop_iter_init(&upi, &trans->upstream);
10.596 +
10.597 + while (prop_iter_next(&spi, RAZOR_PROPERTY_CONFLICTS, &sp)) {
10.598 + if (!prop_iter_seek_to(&upi, RAZOR_PROPERTY_PROVIDES,
10.599 + &spi.pool[sp->name]))
10.600 + continue;
10.601 +
10.602 + if (!any_provider_satisfies_requirement(&upi, sp->flags,
10.603 + &spi.pool[sp->version]))
10.604 + continue;
10.605 +
10.606 + razor_package_iterator_init_for_property(&pkg_iter,
10.607 + trans->system.set,
10.608 + sp);
10.609 + while (razor_package_iterator_next(&pkg_iter, &pkg,
10.610 + &name, &version, &arch)) {
10.611 + fprintf(stderr, "updating %s %s because it conflicts with %s",
10.612 + name, version, spi.pool + sp->name);
10.613 + trans->system.packages[pkg - spkgs] |=
10.614 + TRANS_PACKAGE_UPDATE;
10.615 + }
10.616 + }
10.617 +
10.618 + prop_iter_init(&spi, &trans->system);
10.619 + prop_iter_init(&upi, &trans->upstream);
10.620 +
10.621 + while (prop_iter_next(&upi, RAZOR_PROPERTY_CONFLICTS, &up)) {
10.622 + sp = prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES,
10.623 + &upi.pool[upi.p->name]);
10.624 +
10.625 + if (sp)
10.626 + flag_matching_providers(trans, &spi, up, &upi,
10.627 + TRANS_PACKAGE_UPDATE);
10.628 + }
10.629 +}
10.630 +
10.631 +static void
10.632 +pull_in_requirements(struct razor_transaction *trans,
10.633 + struct prop_iter *rpi, struct prop_iter *ppi)
10.634 +{
10.635 + struct razor_property *rp, *pp;
10.636 + struct razor_package *pkg, *upkgs;
10.637 +
10.638 + upkgs = trans->upstream.set->packages.data;
10.639 + while (prop_iter_next(rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
10.640 + if (rpi->present[rp - rpi->start] & TRANS_PROPERTY_SATISFIED)
10.641 + continue;
10.642 +
10.643 + pp = prop_iter_seek_to(ppi, RAZOR_PROPERTY_PROVIDES,
10.644 + &rpi->pool[rp->name]);
10.645 + if (pp == NULL)
10.646 + continue;
10.647 + pkg = pick_matching_provider(trans->upstream.set,
10.648 + ppi, rp->flags,
10.649 + &rpi->pool[rp->version]);
10.650 + if (pkg == NULL)
10.651 + continue;
10.652 +
10.653 + rpi->present[rp - rpi->start] |= TRANS_PROPERTY_SATISFIED;
10.654 +
10.655 + fprintf(stderr, "pulling in %s which provides %s %s %s "
10.656 + "to satisfy %s %s %s\n",
10.657 + ppi->pool + pkg->name,
10.658 + ppi->pool + pp->name,
10.659 + razor_property_relation_to_string(pp),
10.660 + ppi->pool + pp->version,
10.661 + &rpi->pool[rp->name],
10.662 + razor_property_relation_to_string(rp),
10.663 + &rpi->pool[rp->version]);
10.664 +
10.665 + trans->upstream.packages[pkg - upkgs] |= TRANS_PACKAGE_UPDATE;
10.666 + }
10.667 +}
10.668 +
10.669 +static void
10.670 +pull_in_all_requirements(struct razor_transaction *trans)
10.671 +{
10.672 + struct prop_iter rpi, ppi;
10.673 +
10.674 + prop_iter_init(&rpi, &trans->system);
10.675 + prop_iter_init(&ppi, &trans->upstream);
10.676 + pull_in_requirements(trans, &rpi, &ppi);
10.677 +
10.678 + prop_iter_init(&rpi, &trans->upstream);
10.679 + prop_iter_init(&ppi, &trans->upstream);
10.680 + pull_in_requirements(trans, &rpi, &ppi);
10.681 +}
10.682 +
10.683 +static void
10.684 +flush_scheduled_system_updates(struct razor_transaction *trans)
10.685 +{
10.686 + struct razor_package_iterator *pi;
10.687 + struct razor_package *p, *pkg, *spkgs;
10.688 + struct prop_iter ppi;
10.689 + const char *name, *version, *arch;
10.690 +
10.691 + spkgs = trans->system.set->packages.data;
10.692 + pi = razor_package_iterator_create(trans->system.set);
10.693 + prop_iter_init(&ppi, &trans->upstream);
10.694 +
10.695 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
10.696 + if (!(trans->system.packages[p - spkgs] & TRANS_PACKAGE_UPDATE))
10.697 + continue;
10.698 +
10.699 + if (!prop_iter_seek_to(&ppi, RAZOR_PROPERTY_PROVIDES, name))
10.700 + continue;
10.701 +
10.702 + pkg = pick_matching_provider(trans->upstream.set, &ppi,
10.703 + RAZOR_PROPERTY_GREATER, version);
10.704 + if (pkg == NULL)
10.705 + continue;
10.706 +
10.707 + fprintf(stderr, "updating %s-%s to %s-%s\n",
10.708 + name, version,
10.709 + &ppi.pool[pkg->name], &ppi.pool[pkg->version]);
10.710 +
10.711 + razor_transaction_remove_package(trans, p);
10.712 + razor_transaction_install_package(trans, pkg);
10.713 + }
10.714 +
10.715 + razor_package_iterator_destroy(pi);
10.716 +}
10.717 +
10.718 +static void
10.719 +flush_scheduled_upstream_updates(struct razor_transaction *trans)
10.720 +{
10.721 + struct razor_package_iterator *pi;
10.722 + struct razor_package *p, *upkgs;
10.723 + struct prop_iter spi;
10.724 + const char *name, *version, *arch;
10.725 +
10.726 + upkgs = trans->upstream.set->packages.data;
10.727 + pi = razor_package_iterator_create(trans->upstream.set);
10.728 + prop_iter_init(&spi, &trans->system);
10.729 +
10.730 + while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
10.731 + if (!(trans->upstream.packages[p - upkgs] & TRANS_PACKAGE_UPDATE))
10.732 + continue;
10.733 +
10.734 + if (prop_iter_seek_to(&spi, RAZOR_PROPERTY_PROVIDES, name))
10.735 + remove_matching_providers(trans,
10.736 + &spi,
10.737 + RAZOR_PROPERTY_LESS,
10.738 + version);
10.739 + razor_transaction_install_package(trans, p);
10.740 + fprintf(stderr, "installing %s-%s\n", name, version);
10.741 + }
10.742 +}
10.743 +
10.744 +int
10.745 +razor_transaction_resolve(struct razor_transaction *trans)
10.746 +{
10.747 + int last = 0;
10.748 +
10.749 + flush_scheduled_system_updates(trans);
10.750 + flush_scheduled_upstream_updates(trans);
10.751 +
10.752 + while (last < trans->changes) {
10.753 + last = trans->changes;
10.754 + remove_obsoleted_packages(trans);
10.755 + mark_all_satisfied_requires(trans);
10.756 + update_unsatisfied_packages(trans);
10.757 + update_conflicted_packages(trans);
10.758 + pull_in_all_requirements(trans);
10.759 + flush_scheduled_system_updates(trans);
10.760 + flush_scheduled_upstream_updates(trans);
10.761 + }
10.762 +
10.763 + return trans->changes;
10.764 +}
10.765 +
10.766 +static void
10.767 +describe_unsatisfied(struct razor_set *set, struct razor_property *rp)
10.768 +{
10.769 + struct razor_package_iterator pi;
10.770 + struct razor_package *pkg;
10.771 + const char *name, *version, *arch, *pool;
10.772 +
10.773 + pool = set->string_pool.data;
10.774 + if (pool[rp->version] == '\0') {
10.775 + razor_package_iterator_init_for_property(&pi, set, rp);
10.776 + while (razor_package_iterator_next(&pi, &pkg,
10.777 + &name, &version, &arch))
10.778 + fprintf(stderr, "%s is needed by %s-%s.%s\n",
10.779 + &pool[rp->name],
10.780 + name, version, arch);
10.781 + } else {
10.782 + razor_package_iterator_init_for_property(&pi, set, rp);
10.783 + while (razor_package_iterator_next(&pi, &pkg,
10.784 + &name, &version, &arch))
10.785 + fprintf(stderr, "%s %s %s is needed by %s-%s.%s\n",
10.786 + &pool[rp->name],
10.787 + razor_property_relation_to_string(rp),
10.788 + &pool[rp->version],
10.789 + name, version, arch);
10.790 + }
10.791 +}
10.792 +
10.793 +int
10.794 +razor_transaction_describe(struct razor_transaction *trans)
10.795 +{
10.796 + struct prop_iter rpi;
10.797 + struct razor_property *rp;
10.798 + int unsatisfied;
10.799 +
10.800 + flush_scheduled_system_updates(trans);
10.801 + flush_scheduled_upstream_updates(trans);
10.802 + mark_all_satisfied_requires(trans);
10.803 +
10.804 + unsatisfied = 0;
10.805 + prop_iter_init(&rpi, &trans->system);
10.806 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
10.807 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
10.808 + describe_unsatisfied(trans->system.set, rp);
10.809 + unsatisfied++;
10.810 + }
10.811 + }
10.812 +
10.813 + prop_iter_init(&rpi, &trans->upstream);
10.814 + while (prop_iter_next(&rpi, RAZOR_PROPERTY_REQUIRES, &rp)) {
10.815 + if (!(rpi.present[rp - rpi.start] & TRANS_PROPERTY_SATISFIED)) {
10.816 + describe_unsatisfied(trans->upstream.set, rp);
10.817 + unsatisfied++;
10.818 + }
10.819 + }
10.820 +
10.821 + return unsatisfied;
10.822 +}
10.823 +
10.824 +int
10.825 +razor_transaction_unsatisfied_property(struct razor_transaction *trans,
10.826 + const char *name,
10.827 + uint32_t flags,
10.828 + const char *version)
10.829 +{
10.830 + struct prop_iter pi;
10.831 + struct razor_property *p;
10.832 +
10.833 + prop_iter_init(&pi, &trans->system);
10.834 + while (prop_iter_next(&pi, flags, &p)) {
10.835 + if (!(trans->system.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
10.836 + p->flags == flags &&
10.837 + strcmp(&pi.pool[p->name], name) == 0 &&
10.838 + strcmp(&pi.pool[p->version], version) == 0)
10.839 +
10.840 + return 1;
10.841 + }
10.842 +
10.843 + prop_iter_init(&pi, &trans->upstream);
10.844 + while (prop_iter_next(&pi, flags, &p)) {
10.845 + if (!(trans->upstream.properties[p - pi.start] & TRANS_PROPERTY_SATISFIED) &&
10.846 + p->flags == flags &&
10.847 + strcmp(&pi.pool[p->name], name) == 0 &&
10.848 + strcmp(&pi.pool[p->version], version) == 0)
10.849 +
10.850 + return 1;
10.851 + }
10.852 +
10.853 + return 0;
10.854 +}
10.855 +
10.856 +struct razor_set *
10.857 +razor_transaction_finish(struct razor_transaction *trans)
10.858 +{
10.859 + struct razor_merger *merger;
10.860 + struct razor_package *u, *uend, *upkgs, *s, *send, *spkgs;
10.861 + char *upool, *spool;
10.862 + int cmp;
10.863 +
10.864 + s = trans->system.set->packages.data;
10.865 + spkgs = trans->system.set->packages.data;
10.866 + send = trans->system.set->packages.data +
10.867 + trans->system.set->packages.size;
10.868 + spool = trans->system.set->string_pool.data;
10.869 +
10.870 + u = trans->upstream.set->packages.data;
10.871 + upkgs = trans->upstream.set->packages.data;
10.872 + uend = trans->upstream.set->packages.data +
10.873 + trans->upstream.set->packages.size;
10.874 + upool = trans->upstream.set->string_pool.data;
10.875 +
10.876 + merger = razor_merger_create(trans->system.set, trans->upstream.set);
10.877 + while (s < send || u < uend) {
10.878 + if (s < send && u < uend)
10.879 + cmp = strcmp(&spool[s->name], &upool[u->name]);
10.880 + else if (s < send)
10.881 + cmp = -1;
10.882 + else
10.883 + cmp = 1;
10.884 +
10.885 + if (cmp < 0) {
10.886 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
10.887 + razor_merger_add_package(merger, s);
10.888 + s++;
10.889 + } else if (cmp == 0) {
10.890 + if (trans->system.packages[s - spkgs] & TRANS_PACKAGE_PRESENT)
10.891 + razor_merger_add_package(merger, s);
10.892 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
10.893 + razor_merger_add_package(merger, u);
10.894 +
10.895 + s++;
10.896 + u++;
10.897 + } else {
10.898 + if (trans->upstream.packages[u - upkgs] & TRANS_PACKAGE_PRESENT)
10.899 + razor_merger_add_package(merger, u);
10.900 + u++;
10.901 + }
10.902 + }
10.903 +
10.904 + razor_transaction_destroy(trans);
10.905 +
10.906 + return razor_merger_finish(merger);
10.907 +}
10.908 +
10.909 +void
10.910 +razor_transaction_destroy(struct razor_transaction *trans)
10.911 +{
10.912 + transaction_set_release(&trans->system);
10.913 + transaction_set_release(&trans->upstream);
10.914 + free(trans);
10.915 +}
11.1 --- a/librazor/types.c Fri Jun 20 14:18:52 2008 -0400
11.2 +++ b/librazor/types.c Fri Jun 20 15:10:34 2008 -0400
11.3 @@ -1,7 +1,7 @@
11.4 #include <stdlib.h>
11.5 #include <string.h>
11.6
11.7 -#include "types.h"
11.8 +#include "razor-internal.h"
11.9
11.10 void
11.11 array_init(struct array *array)
12.1 --- a/librazor/types.h Fri Jun 20 14:18:52 2008 -0400
12.2 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000
12.3 @@ -1,59 +0,0 @@
12.4 -#ifndef _RAZOR_TYPES_H_
12.5 -#define _RAZOR_TYPES_H_
12.6 -
12.7 -#include <stdint.h>
12.8 -
12.9 -struct array {
12.10 - void *data;
12.11 - int size, alloc;
12.12 -};
12.13 -
12.14 -void array_init(struct array *array);
12.15 -void array_release(struct array *array);
12.16 -void *array_add(struct array *array, int size);
12.17 -
12.18 -
12.19 -struct list_head {
12.20 - uint list_ptr : 24;
12.21 - uint flags : 8;
12.22 -};
12.23 -
12.24 -struct list {
12.25 - uint data : 24;
12.26 - uint flags : 8;
12.27 -};
12.28 -
12.29 -void list_set_empty(struct list_head *head);
12.30 -void list_set_ptr(struct list_head *head, uint32_t ptr);
12.31 -void list_set_array(struct list_head *head, struct array *pool, struct array *items, int force_indirect);
12.32 -
12.33 -struct list *list_first(struct list_head *head, struct array *pool);
12.34 -struct list *list_next(struct list *list);
12.35 -
12.36 -void list_remap_pool(struct array *pool, uint32_t *map);
12.37 -void list_remap_head(struct list_head *list, uint32_t *map);
12.38 -
12.39 -
12.40 -struct hashtable {
12.41 - struct array buckets;
12.42 - struct array *pool;
12.43 -};
12.44 -
12.45 -void hashtable_init(struct hashtable *table, struct array *pool);
12.46 -void hashtable_release(struct hashtable *table);
12.47 -uint32_t hashtable_insert(struct hashtable *table, const char *key);
12.48 -uint32_t hashtable_lookup(struct hashtable *table, const char *key);
12.49 -uint32_t hashtable_tokenize(struct hashtable *table, const char *string);
12.50 -
12.51 -
12.52 -struct bitarray {
12.53 - uint32_t *bits;
12.54 -};
12.55 -
12.56 -void bitarray_init(struct bitarray *bitarray, int size, int intial_value);
12.57 -void bitarray_release(struct bitarray *bitarray);
12.58 -void bitarray_set(struct bitarray *bitarray, int bit, int value);
12.59 -int bitarray_get(struct bitarray *bitarray, int bit);
12.60 -
12.61 -
12.62 -#endif /* _RAZOR_TYPES_H_ */
13.1 --- a/src/.gitignore Fri Jun 20 14:18:52 2008 -0400
13.2 +++ b/src/.gitignore Fri Jun 20 15:10:34 2008 -0400
13.3 @@ -1,5 +1,8 @@
13.4 .deps
13.5 .libs
13.6 razor
13.7 -rpm-razor
13.8 -
13.9 +rpm
13.10 +*.repo
13.11 +*.xml.gz
13.12 +install
13.13 +rpms