Track the requires and provides per package.
1.1 --- a/razor.c Thu Sep 06 17:01:01 2007 -0400
1.2 +++ b/razor.c Thu Sep 06 23:31:26 2007 -0400
1.3 @@ -24,7 +24,7 @@
1.4 if (array->alloc > 0)
1.5 alloc = array->alloc;
1.6 else
1.7 - alloc = 1024;
1.8 + alloc = 16;
1.9
1.10 while (alloc < array->size + size)
1.11 alloc *= 2;
1.12 @@ -98,10 +98,13 @@
1.13 #define RAZOR_PACKAGES 3
1.14 #define RAZOR_REQUIRES 4
1.15 #define RAZOR_PROVIDES 5
1.16 +#define RAZOR_PROPERTIES 6
1.17
1.18 struct razor_package {
1.19 unsigned long name;
1.20 unsigned long version;
1.21 + unsigned long requires;
1.22 + unsigned long provides;
1.23 };
1.24
1.25 struct razor_property {
1.26 @@ -113,6 +116,7 @@
1.27 struct razor_set {
1.28 struct array buckets;
1.29 struct array string_pool;
1.30 + struct array property_pool;
1.31 struct array packages;
1.32 struct array requires;
1.33 struct array provides;
1.34 @@ -180,6 +184,11 @@
1.35 set->provides.size = size;
1.36 set->provides.size = size;
1.37 break;
1.38 + case RAZOR_PROPERTIES:
1.39 + set->property_pool.data = (void *) set->header + offset;
1.40 + set->property_pool.size = size;
1.41 + set->property_pool.size = size;
1.42 + break;
1.43 }
1.44 }
1.45 close(fd);
1.46 @@ -204,6 +213,7 @@
1.47 free(set->packages.data);
1.48 free(set->requires.data);
1.49 free(set->provides.data);
1.50 + free(set->property_pool.data);
1.51 }
1.52
1.53 free(set);
1.54 @@ -215,12 +225,14 @@
1.55 char data[4096];
1.56 struct razor_set_header *header = (struct razor_set_header *) data;
1.57 int fd, pool_size, packages_size, requires_size, provides_size;
1.58 + int properties_size;
1.59
1.60 /* Align these to pages sizes */
1.61 pool_size = (set->string_pool.size + 4095) & ~4095;
1.62 packages_size = (set->packages.size + 4095) & ~4095;
1.63 requires_size = (set->requires.size + 4095) & ~4095;
1.64 provides_size = (set->provides.size + 4095) & ~4095;
1.65 + properties_size = (set->property_pool.size + 4095) & ~4095;
1.66
1.67 memset(data, 0, sizeof data);
1.68 header->magic = RAZOR_MAGIC;
1.69 @@ -245,10 +257,14 @@
1.70 header->sections[4].offset =
1.71 header->sections[3].offset + requires_size;
1.72
1.73 - header->sections[5].type = 0;
1.74 + header->sections[5].type = RAZOR_PROPERTIES;
1.75 header->sections[5].offset =
1.76 header->sections[4].offset + provides_size;
1.77
1.78 + header->sections[6].type = 0;
1.79 + header->sections[6].offset =
1.80 + header->sections[5].offset + properties_size;
1.81 +
1.82 fd = open(filename, O_CREAT | O_WRONLY | O_TRUNC, 0666);
1.83 if (fd < 0)
1.84 return -1;
1.85 @@ -259,6 +275,7 @@
1.86 write_to_fd(fd, set->packages.data, packages_size);
1.87 write_to_fd(fd, set->requires.data, requires_size);
1.88 write_to_fd(fd, set->provides.data, provides_size);
1.89 + write_to_fd(fd, set->property_pool.data, properties_size);
1.90
1.91 return 0;
1.92 }
1.93 @@ -312,6 +329,19 @@
1.94 return p - (char *) set->string_pool.data;
1.95 }
1.96
1.97 +static unsigned long
1.98 +add_to_property_pool(struct razor_set *set, struct array *properties)
1.99 +{
1.100 + unsigned long *p;
1.101 +
1.102 + p = array_add(properties, sizeof *p);
1.103 + *p = 0;
1.104 + p = array_add(&set->property_pool, properties->size);
1.105 + memcpy(p, properties->data, properties->size);
1.106 +
1.107 + return p - (unsigned long *) set->property_pool.data;
1.108 +}
1.109 +
1.110 static void
1.111 do_insert(struct razor_set *set, unsigned long value)
1.112 {
1.113 @@ -412,11 +442,26 @@
1.114 return razor_set_insert(set, string);
1.115 }
1.116
1.117 +struct property_context {
1.118 + struct array all;
1.119 + struct array package;
1.120 +};
1.121 +
1.122 struct import_context {
1.123 struct razor_set *set;
1.124 - struct array requires;
1.125 - struct array provides;
1.126 + struct property_context requires;
1.127 + struct property_context provides;
1.128 unsigned long package;
1.129 + unsigned long *requires_map;
1.130 + unsigned long *provides_map;
1.131 +};
1.132 +
1.133 +struct import_property {
1.134 + unsigned long name;
1.135 + unsigned long version;
1.136 + unsigned long package;
1.137 + unsigned long index;
1.138 + unsigned long unique_index;
1.139 };
1.140
1.141 static void
1.142 @@ -439,6 +484,8 @@
1.143 }
1.144
1.145 ctx->package = razor_set_add_package(ctx->set, name, version);
1.146 + memset(&ctx->requires.package, 0, sizeof ctx->requires.package);
1.147 + memset(&ctx->provides.package, 0, sizeof ctx->provides.package);
1.148
1.149 return;
1.150 }
1.151 @@ -446,9 +493,9 @@
1.152 static void
1.153 parse_property(struct import_context *ctx, const char **atts, void *data)
1.154 {
1.155 - unsigned long name = 0, version = 0;
1.156 - struct razor_property *p;
1.157 - struct array *array = data;
1.158 + unsigned long name = 0, version = 0, *r;
1.159 + struct import_property *p;
1.160 + struct property_context *pctx = data;
1.161 int i;
1.162
1.163 for (i = 0; atts[i]; i += 2) {
1.164 @@ -463,10 +510,14 @@
1.165 return;
1.166 }
1.167
1.168 - p = array_add(array, sizeof *p);
1.169 + p = array_add(&pctx->all, sizeof *p);
1.170 p->name = name;
1.171 p->version = version;
1.172 - p->packages = ctx->package;
1.173 + p->package = ctx->package;
1.174 + p->index = p - (struct import_property *) pctx->all.data;
1.175 +
1.176 + r = array_add(&pctx->package, sizeof *r);
1.177 + *r = p->index;
1.178 }
1.179
1.180 static void
1.181 @@ -486,9 +537,19 @@
1.182 end_element (void *data, const char *name)
1.183 {
1.184 struct import_context *ctx = data;
1.185 + struct razor_package *package;
1.186
1.187 - if (strcmp(name, "package") == 0)
1.188 + if (strcmp(name, "package") == 0) {
1.189 + package = (struct razor_package *) ctx->set->packages.data +
1.190 + ctx->package;
1.191 + package->requires =
1.192 + add_to_property_pool(ctx->set, &ctx->requires.package);
1.193 + package->provides =
1.194 + add_to_property_pool(ctx->set, &ctx->provides.package);
1.195 + free(ctx->requires.package.data);
1.196 + free(ctx->provides.package.data);
1.197 ctx->package = 0;
1.198 + }
1.199 }
1.200
1.201 static char *
1.202 @@ -577,52 +638,86 @@
1.203 static int
1.204 compare_properties(const void *p1, const void *p2)
1.205 {
1.206 - const struct razor_property *prop1 = p1, *prop2 = p2;
1.207 + const struct import_property *prop1 = p1, *prop2 = p2;
1.208 char *pool = qsort_set->string_pool.data;
1.209
1.210 return strcmp(&pool[prop1->name], &pool[prop2->name]);
1.211 }
1.212
1.213 -static void
1.214 +static unsigned long *
1.215 uniqueify_properties(struct array *in, struct array *out)
1.216 {
1.217 - struct razor_property *p, *q, *end;
1.218 + struct import_property *ip, *end;
1.219 + struct razor_property *rp;
1.220 + unsigned long *map;
1.221 + int i, count;
1.222
1.223 - qsort(in->data, in->size / sizeof(struct razor_property),
1.224 - sizeof(struct razor_property), compare_properties);
1.225 + count = in->size / sizeof(struct import_property);
1.226 + qsort(in->data, count,
1.227 + sizeof(struct import_property), compare_properties);
1.228
1.229 - q = NULL;
1.230 + rp = NULL;
1.231 end = in->data + in->size;
1.232 - for (p = in->data; p < end && p->name; p++) {
1.233 - if (q == NULL ||
1.234 - p->name != q->name || p->version != q->version) {
1.235 - q = array_add(out, sizeof *q);
1.236 - q->name = p->name;
1.237 - q->version = p->version;
1.238 + for (ip = in->data; ip < end; ip++) {
1.239 + if (rp == NULL ||
1.240 + ip->name != rp->name || ip->version != rp->version) {
1.241 + rp = array_add(out, sizeof *rp);
1.242 + rp->name = ip->name;
1.243 + rp->version = ip->version;
1.244 + }
1.245 + ip->unique_index = rp - (struct razor_property *) out->data;
1.246 + }
1.247
1.248 - }
1.249 + map = malloc(count * sizeof (unsigned long));
1.250 + ip = in->data;
1.251 + for (i = 0; i < count; i++)
1.252 + map[ip[i].index] = ip[i].unique_index;
1.253 +
1.254 + return map;
1.255 +}
1.256 +
1.257 +static void
1.258 +sort_packages(struct import_context *ctx)
1.259 +{
1.260 + struct razor_package *p, *end;
1.261 + unsigned long *pool, *r;
1.262 +
1.263 + pool = ctx->set->property_pool.data;
1.264 + end = ctx->set->packages.data + ctx->set->packages.size;
1.265 + for (p = ctx->set->packages.data; p < end; p++) {
1.266 + for (r = &pool[p->requires]; *r; r++)
1.267 + *r = ctx->requires_map[*r];
1.268 + for (r = &pool[p->provides]; *r; r++)
1.269 + *r = ctx->provides_map[*r];
1.270 }
1.271 +
1.272 + qsort(ctx->set->packages.data,
1.273 + ctx->set->packages.size / sizeof(struct razor_package),
1.274 + sizeof(struct razor_package), compare_packages);
1.275 }
1.276
1.277 static void
1.278 razor_set_finish_import(struct import_context *ctx)
1.279 {
1.280 qsort_set = ctx->set;
1.281 - qsort(ctx->set->packages.data,
1.282 - ctx->set->packages.size / sizeof(struct razor_package),
1.283 - sizeof(struct razor_package), compare_packages);
1.284
1.285 - uniqueify_properties(&ctx->requires, &ctx->set->requires);
1.286 - uniqueify_properties(&ctx->provides, &ctx->set->provides);
1.287 + ctx->requires_map =
1.288 + uniqueify_properties(&ctx->requires.all, &ctx->set->requires);
1.289 + ctx->provides_map =
1.290 + uniqueify_properties(&ctx->provides.all, &ctx->set->provides);
1.291
1.292 - free(ctx->requires.data);
1.293 - free(ctx->provides.data);
1.294 + sort_packages(ctx);
1.295 +
1.296 + free(ctx->requires.all.data);
1.297 + free(ctx->provides.all.data);
1.298 + free(ctx->requires_map);
1.299 + free(ctx->provides_map);
1.300
1.301 fprintf(stderr, "parsed %d requires, %d unique\n",
1.302 - ctx->requires.size / sizeof(struct razor_property),
1.303 + ctx->requires.all.size / sizeof(struct import_property),
1.304 ctx->set->requires.size / sizeof(struct razor_property));
1.305 fprintf(stderr, "parsed %d provides, %d unique\n",
1.306 - ctx->provides.size / sizeof(struct razor_property),
1.307 + ctx->provides.all.size / sizeof(struct import_property),
1.308 ctx->set->provides.size / sizeof(struct razor_property));
1.309 }
1.310
1.311 @@ -639,28 +734,75 @@
1.312 printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.313 }
1.314
1.315 -void
1.316 -razor_set_list_requires(struct razor_set *set)
1.317 +struct razor_package *
1.318 +razor_set_get_package(struct razor_set *set, const char *package)
1.319 +{
1.320 + unsigned long name;
1.321 + struct razor_package *p, *end;
1.322 +
1.323 + name = razor_set_lookup(set, package);
1.324 + end = set->packages.data + set->packages.size;
1.325 + for (p = set->packages.data; p < end && p->name; p++)
1.326 + if (p->name == name)
1.327 + return p;
1.328 +
1.329 + return NULL;
1.330 +}
1.331 +
1.332 +static void
1.333 +razor_set_list_all_properties(struct razor_set *set, struct array *properties)
1.334 {
1.335 struct razor_property *p, *end;
1.336 char *pool;
1.337
1.338 pool = set->string_pool.data;
1.339 - end = set->requires.data + set->requires.size;
1.340 - for (p = set->requires.data; p < end && p->name; p++)
1.341 + end = properties->data + properties->size;
1.342 + for (p = properties->data; p < end && p->name; p++)
1.343 printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.344 }
1.345
1.346 void
1.347 -razor_set_list_provides(struct razor_set *set)
1.348 +razor_set_list_requires(struct razor_set *set, const char *name)
1.349 {
1.350 - struct razor_property *p, *end;
1.351 + struct razor_property *p, *requires;
1.352 + struct razor_package *package;
1.353 + unsigned long *r;
1.354 char *pool;
1.355
1.356 - pool = set->string_pool.data;
1.357 - end = set->provides.data + set->provides.size;
1.358 - for (p = set->provides.data; p < end && p->name; p++)
1.359 - printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.360 + if (name) {
1.361 + package = razor_set_get_package(set, name);
1.362 + r = (unsigned long *) set->property_pool.data +
1.363 + package->requires;
1.364 + requires = set->requires.data;
1.365 + pool = set->string_pool.data;
1.366 + while (*r) {
1.367 + p = &requires[*r++];
1.368 + printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.369 + }
1.370 + } else
1.371 + razor_set_list_all_properties(set, &set->requires);
1.372 +}
1.373 +
1.374 +void
1.375 +razor_set_list_provides(struct razor_set *set, const char *name)
1.376 +{
1.377 + struct razor_property *p, *provides;
1.378 + struct razor_package *package;
1.379 + unsigned long *r;
1.380 + char *pool;
1.381 +
1.382 + if (name) {
1.383 + package = razor_set_get_package(set, name);
1.384 + r = (unsigned long *) set->property_pool.data +
1.385 + package->provides;
1.386 + provides = set->provides.data;
1.387 + pool = set->string_pool.data;
1.388 + while (*r) {
1.389 + p = &provides[*r++];
1.390 + printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.391 + }
1.392 + } else
1.393 + razor_set_list_all_properties(set, &set->provides);
1.394 }
1.395
1.396 void
1.397 @@ -764,11 +906,11 @@
1.398 razor_set_destroy(set);
1.399 } else if (strcmp(argv[1], "list-requires") == 0) {
1.400 set = razor_set_open(repo_filename);
1.401 - razor_set_list_requires(set);
1.402 + razor_set_list_requires(set, argv[2]);
1.403 razor_set_destroy(set);
1.404 } else if (strcmp(argv[1], "list-provides") == 0) {
1.405 set = razor_set_open(repo_filename);
1.406 - razor_set_list_provides(set);
1.407 + razor_set_list_provides(set, argv[2]);
1.408 razor_set_destroy(set);
1.409 } else if (strcmp(argv[1], "info") == 0) {
1.410 set = razor_set_open(repo_filename);