razor.c
changeset 18 b2bf852ca8d1
parent 17 67029e580a0e
child 19 d2a716dd92bd
     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  	}