1.1 --- a/razor.c Fri Sep 07 14:17:39 2007 -0400
1.2 +++ b/razor.c Tue Sep 11 19:25:32 2007 -0400
1.3 @@ -141,14 +141,7 @@
1.4 struct razor_set *
1.5 razor_set_create(void)
1.6 {
1.7 - struct razor_set *set;
1.8 - char *p;
1.9 -
1.10 - set = zalloc(sizeof(struct razor_set));
1.11 - p = array_add(&set->string_pool, 1);
1.12 - *p = '\0';
1.13 -
1.14 - return set;
1.15 + return zalloc(sizeof(struct razor_set));
1.16 }
1.17
1.18 struct razor_set *
1.19 @@ -331,7 +324,7 @@
1.20 unsigned long *p;
1.21
1.22 p = array_add(properties, sizeof *p);
1.23 - *p = 0;
1.24 + *p = ~0ul;
1.25 p = array_add(&set->property_pool, properties->size);
1.26 memcpy(p, properties->data, properties->size);
1.27
1.28 @@ -390,7 +383,7 @@
1.29 unsigned long token;
1.30
1.31 if (string == NULL)
1.32 - return 0;
1.33 + return razor_set_tokenize(set, "");
1.34
1.35 token = razor_set_lookup(set, string);
1.36 if (token != 0)
1.37 @@ -408,11 +401,20 @@
1.38 struct razor_set *set;
1.39 struct import_property_context requires;
1.40 struct import_property_context provides;
1.41 - unsigned long package;
1.42 + struct array packages;
1.43 + struct import_package *package;
1.44 unsigned long *requires_map;
1.45 unsigned long *provides_map;
1.46 };
1.47
1.48 +struct import_package {
1.49 + unsigned long name;
1.50 + unsigned long version;
1.51 + unsigned long requires;
1.52 + unsigned long provides;
1.53 + unsigned long index;
1.54 +};
1.55 +
1.56 struct import_property {
1.57 unsigned long name;
1.58 unsigned long version;
1.59 @@ -425,13 +427,14 @@
1.60 import_context_add_package(struct import_context *ctx,
1.61 const char *name, const char *version)
1.62 {
1.63 - struct razor_package *p;
1.64 + struct import_package *p;
1.65
1.66 - p = array_add(&ctx->set->packages, sizeof *p);
1.67 + p = array_add(&ctx->packages, sizeof *p);
1.68 p->name = razor_set_tokenize(ctx->set, name);
1.69 p->version = razor_set_tokenize(ctx->set, version);
1.70 + p->index = p - (struct import_package *) ctx->packages.data;
1.71
1.72 - ctx->package = p - (struct razor_package *) ctx->set->packages.data;
1.73 + ctx->package = p;
1.74 array_init(&ctx->requires.package);
1.75 array_init(&ctx->provides.package);
1.76 }
1.77 @@ -439,9 +442,9 @@
1.78 void
1.79 import_context_finish_package(struct import_context *ctx)
1.80 {
1.81 - struct razor_package *p;
1.82 + struct import_package *p;
1.83
1.84 - p = (struct razor_package *) ctx->set->packages.data + ctx->package;
1.85 + p = ctx->package;
1.86 p->requires = add_to_property_pool(ctx->set, &ctx->requires.package);
1.87 p->provides = add_to_property_pool(ctx->set, &ctx->provides.package);
1.88
1.89 @@ -460,7 +463,7 @@
1.90 p = array_add(&pctx->all, sizeof *p);
1.91 p->name = razor_set_tokenize(ctx->set, name);
1.92 p->version = razor_set_tokenize(ctx->set, version);
1.93 - p->package = ctx->package;
1.94 + p->package = ctx->package->index;
1.95 p->index = p - (struct import_property *) pctx->all.data;
1.96
1.97 r = array_add(&pctx->package, sizeof *r);
1.98 @@ -609,7 +612,7 @@
1.99 static int
1.100 compare_packages(const void *p1, const void *p2)
1.101 {
1.102 - const struct razor_package *pkg1 = p1, *pkg2 = p2;
1.103 + const struct import_package *pkg1 = p1, *pkg2 = p2;
1.104 char *pool = qsort_set->string_pool.data;
1.105
1.106 return strcmp(&pool[pkg1->name], &pool[pkg2->name]);
1.107 @@ -630,12 +633,14 @@
1.108 }
1.109
1.110 static unsigned long *
1.111 -uniqueify_properties(struct array *in, struct array *out)
1.112 +uniqueify_properties(struct razor_set *set,
1.113 + struct array *in, struct array *out)
1.114 {
1.115 struct import_property *ip, *end;
1.116 - struct razor_property *rp;
1.117 - unsigned long *map;
1.118 - int i, count;
1.119 + struct razor_property *rp, *rp_end;
1.120 + struct array *pkgs, *p;
1.121 + unsigned long *map, *r;
1.122 + int i, count, unique;
1.123
1.124 count = in->size / sizeof(struct import_property);
1.125 qsort(in->data, count,
1.126 @@ -658,40 +663,107 @@
1.127 for (i = 0; i < count; i++)
1.128 map[ip[i].index] = ip[i].unique_index;
1.129
1.130 + unique = out->size / sizeof(*rp);
1.131 + pkgs = zalloc(unique * sizeof *pkgs);
1.132 + for (ip = in->data; ip < end; ip++) {
1.133 + r = array_add(&pkgs[ip->unique_index], sizeof *r);
1.134 + *r = ip->package;
1.135 + }
1.136 +
1.137 + rp_end = out->data + out->size;
1.138 + for (rp = out->data, p = pkgs; rp < rp_end; rp++, p++)
1.139 + rp->packages = add_to_property_pool(set, p);
1.140 +
1.141 + free(pkgs);
1.142 +
1.143 return map;
1.144 }
1.145
1.146 static void
1.147 -sort_packages(struct import_context *ctx)
1.148 +remap_package_links(struct import_context *ctx)
1.149 {
1.150 - struct razor_package *p, *end;
1.151 + struct import_package *p, *end;
1.152 unsigned long *pool, *r;
1.153
1.154 pool = ctx->set->property_pool.data;
1.155 - end = ctx->set->packages.data + ctx->set->packages.size;
1.156 - for (p = ctx->set->packages.data; p < end; p++) {
1.157 - for (r = &pool[p->requires]; *r; r++)
1.158 + end = ctx->packages.data + ctx->packages.size;
1.159 + for (p = ctx->packages.data; p < end; p++) {
1.160 + for (r = &pool[p->requires]; ~*r; r++)
1.161 *r = ctx->requires_map[*r];
1.162 - for (r = &pool[p->provides]; *r; r++)
1.163 + for (r = &pool[p->provides]; ~*r; r++)
1.164 *r = ctx->provides_map[*r];
1.165 }
1.166 +}
1.167
1.168 - qsort(ctx->set->packages.data,
1.169 - ctx->set->packages.size / sizeof(struct razor_package),
1.170 - sizeof(struct razor_package), compare_packages);
1.171 +static void
1.172 +remap_property_links(struct import_context *ctx)
1.173 +{
1.174 + struct razor_property *p, *end;
1.175 + struct import_package *ip;
1.176 + unsigned long *map, *pool, *r;
1.177 + int i, count;
1.178 +
1.179 + pool = ctx->set->property_pool.data;
1.180 + count = ctx->packages.size / sizeof(struct import_package);
1.181 + map = malloc(count * sizeof *map);
1.182 + ip = ctx->packages.data;
1.183 + for (i = 0; i < count; i++)
1.184 + map[ip[i].index] = i;
1.185 +
1.186 + /* FIXME: This will break if we implement package list sharing
1.187 + * for all properties, since we'll remap those lists more than
1.188 + * once. We should just have a separate pool for property
1.189 + * lists and a separate pool for package lists and remap it as
1.190 + * a flat pool. Right now, as property lists and package
1.191 + * lists are mixed, we can't do that. */
1.192 +
1.193 + end = ctx->set->requires.data + ctx->set->requires.size;
1.194 + for (p = ctx->set->requires.data; p < end; p++)
1.195 + for (r = &pool[p->packages]; ~*r; r++)
1.196 + *r = map[*r];
1.197 +
1.198 + end = ctx->set->provides.data + ctx->set->provides.size;
1.199 + for (p = ctx->set->provides.data; p < end; p++)
1.200 + for (r = &pool[p->packages]; ~*r; r++)
1.201 + *r = map[*r];
1.202 +
1.203 + free(map);
1.204 }
1.205
1.206 static struct razor_set *
1.207 razor_finish_import(struct import_context *ctx)
1.208 {
1.209 + struct import_package *ip;
1.210 + struct razor_package *rp;
1.211 + int i, count;
1.212 +
1.213 qsort_set = ctx->set;
1.214
1.215 ctx->requires_map =
1.216 - uniqueify_properties(&ctx->requires.all, &ctx->set->requires);
1.217 + uniqueify_properties(ctx->set,
1.218 + &ctx->requires.all,
1.219 + &ctx->set->requires);
1.220 ctx->provides_map =
1.221 - uniqueify_properties(&ctx->provides.all, &ctx->set->provides);
1.222 + uniqueify_properties(ctx->set,
1.223 + &ctx->provides.all,
1.224 + &ctx->set->provides);
1.225
1.226 - sort_packages(ctx);
1.227 + remap_package_links(ctx);
1.228 +
1.229 + count = ctx->packages.size / sizeof(struct import_package);
1.230 + qsort(ctx->packages.data, count,
1.231 + sizeof(struct import_package), compare_packages);
1.232 +
1.233 + ip = ctx->packages.data;
1.234 + for (i = 0; i < count; i++, ip++, rp++) {
1.235 + rp = array_add(&ctx->set->packages, sizeof *rp);
1.236 + rp->name = ip->name;
1.237 + rp->version = ip->version;
1.238 + rp->requires = ip->requires;
1.239 + rp->provides = ip->provides;
1.240 + }
1.241 +
1.242 + remap_property_links(ctx);
1.243
1.244 free(ctx->requires.all.data);
1.245 free(ctx->provides.all.data);
1.246 @@ -862,6 +934,36 @@
1.247 sizeof(struct razor_package), compare_package_name);
1.248 }
1.249
1.250 +static int
1.251 +compare_property_name(const void *key, const void *data)
1.252 +{
1.253 + const struct razor_property *p = data;
1.254 + char *pool;
1.255 +
1.256 + pool = bsearch_set->string_pool.data;
1.257 +
1.258 + return strcmp(key, &pool[p->name]);
1.259 +}
1.260 +
1.261 +struct razor_property *
1.262 +razor_set_get_property(struct razor_set *set,
1.263 + struct array *properties,
1.264 + const char *property)
1.265 +{
1.266 + struct razor_property *p, *start;
1.267 +
1.268 + bsearch_set = set;
1.269 + p = bsearch(property, properties->data,
1.270 + properties->size / sizeof(struct razor_property),
1.271 + sizeof(struct razor_property), compare_property_name);
1.272 +
1.273 + start = properties->data;
1.274 + while (p > start && (p - 1)->name == p->name)
1.275 + p--;
1.276 +
1.277 + return p;
1.278 +}
1.279 +
1.280 static void
1.281 razor_set_list_all_properties(struct razor_set *set, struct array *properties)
1.282 {
1.283 @@ -888,7 +990,7 @@
1.284 package->requires;
1.285 requires = set->requires.data;
1.286 pool = set->string_pool.data;
1.287 - while (*r) {
1.288 + while (~*r) {
1.289 p = &requires[*r++];
1.290 printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.291 }
1.292 @@ -910,7 +1012,7 @@
1.293 package->provides;
1.294 provides = set->provides.data;
1.295 pool = set->string_pool.data;
1.296 - while (*r) {
1.297 + while (~*r) {
1.298 p = &provides[*r++];
1.299 printf("%s %s\n", &pool[p->name], &pool[p->version]);
1.300 }
1.301 @@ -919,6 +1021,35 @@
1.302 }
1.303
1.304 void
1.305 +razor_set_list_property_packages(struct razor_set *set,
1.306 + struct array *properties,
1.307 + const char *name)
1.308 +{
1.309 + struct razor_property *property, *end;
1.310 + struct razor_package *p, *packages;
1.311 + unsigned long *r;
1.312 + char *pool;
1.313 +
1.314 + if (name == NULL)
1.315 + return;
1.316 +
1.317 + property = razor_set_get_property(set, properties, name);
1.318 + packages = set->packages.data;
1.319 + pool = set->string_pool.data;
1.320 + end = properties->data + properties->size;
1.321 + while (property < end && strcmp(name, &pool[property->name]) == 0) {
1.322 + r = (unsigned long *)
1.323 + set->property_pool.data + property->packages;
1.324 + while (~*r) {
1.325 + p = &packages[*r++];
1.326 + printf("%s %s\n",
1.327 + &pool[p->name], &pool[p->version]);
1.328 + }
1.329 + property++;
1.330 + }
1.331 +}
1.332 +
1.333 +void
1.334 razor_set_info(struct razor_set *set)
1.335 {
1.336 unsigned int offset, size;
1.337 @@ -926,7 +1057,7 @@
1.338
1.339 for (i = 0; i < set->header->sections[i].type; i++) {
1.340 offset = set->header->sections[i].offset;
1.341 - size = set->header->sections[i + 1].offset - offset;
1.342 + size = set->header->sections[i].size;
1.343
1.344 switch (set->header->sections[i].type) {
1.345 case RAZOR_STRINGS:
1.346 @@ -941,6 +1072,9 @@
1.347 case RAZOR_PROVIDES:
1.348 printf("provides section:\t%dkb\n", size / 1024);
1.349 break;
1.350 + case RAZOR_PROPERTIES:
1.351 + printf("properties section:\t%dkb\n", size / 1024);
1.352 + break;
1.353 }
1.354 }
1.355 }
1.356 @@ -1019,6 +1153,14 @@
1.357 set = razor_set_open(repo_filename);
1.358 razor_set_list_provides(set, argv[2]);
1.359 razor_set_destroy(set);
1.360 + } else if (strcmp(argv[1], "what-requires") == 0) {
1.361 + set = razor_set_open(repo_filename);
1.362 + razor_set_list_property_packages(set, &set->requires, argv[2]);
1.363 + razor_set_destroy(set);
1.364 + } else if (strcmp(argv[1], "what-provides") == 0) {
1.365 + set = razor_set_open(repo_filename);
1.366 + razor_set_list_property_packages(set, &set->provides, argv[2]);
1.367 + razor_set_destroy(set);
1.368 } else if (strcmp(argv[1], "info") == 0) {
1.369 set = razor_set_open(repo_filename);
1.370 razor_set_info(set);
1.371 @@ -1029,6 +1171,7 @@
1.372 return 1;
1.373 razor_set_write(set, rawhide_repo_filename);
1.374 razor_set_destroy(set);
1.375 + printf("wrote %s\n", rawhide_repo_filename);
1.376 } else {
1.377 usage();
1.378 }