librazor/iterator.c
author James Bowes <jbowes@redhat.com>
Mon Jun 23 14:51:56 2008 -0400 (2008-06-23)
changeset 264 634e54ca476c
parent 248 057933050c42
child 267 2464313cbced
permissions -rw-r--r--
Actually store the files strings in the files string pool
     1 /*
     2  * Copyright (C) 2008  Kristian Høgsberg <krh@redhat.com>
     3  * Copyright (C) 2008  Red Hat, Inc
     4  *
     5  * This program is free software; you can redistribute it and/or modify
     6  * it under the terms of the GNU General Public License as published by
     7  * the Free Software Foundation; either version 2 of the License, or
     8  * (at your option) any later version.
     9  *
    10  * This program is distributed in the hope that it will be useful,
    11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
    12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    13  * GNU General Public License for more details.
    14  *
    15  * You should have received a copy of the GNU General Public License along
    16  * with this program; if not, write to the Free Software Foundation, Inc.,
    17  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
    18  */
    19 
    20 #define _GNU_SOURCE
    21 
    22 #include <string.h>
    23 #include "razor-internal.h"
    24 #include "razor.h"
    25 
    26 static struct razor_package_iterator *
    27 razor_package_iterator_create_with_index(struct razor_set *set,
    28 					 struct list *index)
    29 {
    30 	struct razor_package_iterator *pi;
    31 
    32 	pi = zalloc(sizeof *pi);
    33 	pi->set = set;
    34 	pi->index = index;
    35 
    36 	return pi;
    37 }
    38 
    39 struct razor_package_iterator *
    40 razor_package_iterator_create(struct razor_set *set)
    41 {
    42 	struct razor_package_iterator *pi;
    43 
    44 	pi = zalloc(sizeof *pi);
    45 	pi->set = set;
    46 	pi->end = set->packages.data + set->packages.size;
    47 	pi->package = set->packages.data;
    48 
    49 	return pi;
    50 }
    51 
    52 void
    53 razor_package_iterator_init_for_property(struct razor_package_iterator *pi,
    54 					 struct razor_set *set,
    55 					 struct razor_property *property)
    56 {
    57 	memset(pi, 0, sizeof *pi);
    58 	pi->set = set;
    59 	pi->index = list_first(&property->packages, &set->package_pool);
    60 }
    61 
    62 struct razor_package_iterator *
    63 razor_package_iterator_create_for_property(struct razor_set *set,
    64 					   struct razor_property *property)
    65 {
    66 	struct list *index;
    67 
    68 	index = list_first(&property->packages, &set->package_pool);
    69 	return razor_package_iterator_create_with_index(set, index);
    70 }
    71 
    72 struct razor_package_iterator *
    73 razor_package_iterator_create_for_file(struct razor_set *set,
    74 				       const char *filename)
    75 {
    76 	struct razor_entry *entry;
    77 	struct list *index;
    78 
    79 	entry = razor_set_find_entry(set, set->files.data, filename);
    80 	if (entry == NULL)
    81 		return NULL;
    82 
    83 	index = list_first(&entry->packages, &set->package_pool);
    84 	return razor_package_iterator_create_with_index(set, index);
    85 }
    86 
    87 int
    88 razor_package_iterator_next(struct razor_package_iterator *pi,
    89 			    struct razor_package **package,
    90 			    const char **name,
    91 			    const char **version,
    92 			    const char **arch)
    93 {
    94 	char *pool;
    95 	int valid;
    96 	struct razor_package *p, *packages;
    97 
    98 	if (pi->package) {
    99 		p = pi->package++;
   100 		valid = p < pi->end;
   101 	} else if (pi->index) {
   102 		packages = pi->set->packages.data;
   103 		p = &packages[pi->index->data];
   104 		pi->index = list_next(pi->index);
   105 		valid = 1;
   106 	} else
   107 		valid = 0;
   108 
   109 	if (valid) {
   110 		pool = pi->set->string_pool.data;
   111 		*package = p;
   112 		*name = &pool[p->name];
   113 		*version = &pool[p->version];
   114 		*arch = &pool[p->arch];
   115 	} else {
   116 		*package = NULL;
   117 	}
   118 
   119 	return valid;
   120 }
   121 
   122 void
   123 razor_package_iterator_destroy(struct razor_package_iterator *pi)
   124 {
   125 	if (pi->free_index)
   126 		free(pi->index);
   127 
   128 	free(pi);
   129 }
   130 
   131 struct razor_property_iterator *
   132 razor_property_iterator_create(struct razor_set *set,
   133 			       struct razor_package *package)
   134 {
   135 	struct razor_property_iterator *pi;
   136 
   137 	pi = zalloc(sizeof *pi);
   138 	pi->set = set;
   139 
   140 	if (package) {
   141 		pi->index = list_first(&package->properties,
   142 				       &set->property_pool);
   143 	} else {
   144 		pi->property = set->properties.data;
   145 		pi->end = set->properties.data + set->properties.size;
   146 	}
   147 
   148 	return pi;
   149 }
   150 
   151 int
   152 razor_property_iterator_next(struct razor_property_iterator *pi,
   153 			     struct razor_property **property,
   154 			     const char **name,
   155 			     uint32_t *flags,
   156 			     const char **version)
   157 {
   158 	char *pool;
   159 	int valid;
   160 	struct razor_property *p, *properties;
   161 
   162 	if (pi->property) {
   163 		p = pi->property++;
   164 		valid = p < pi->end;
   165 	} else if (pi->index) {
   166 		properties = pi->set->properties.data;
   167 		p = &properties[pi->index->data];
   168 		pi->index = list_next(pi->index);
   169 		valid = 1;
   170 	} else
   171 		valid = 0;
   172 
   173 	if (valid) {
   174 		pool = pi->set->string_pool.data;
   175 		*property = p;
   176 		*name = &pool[p->name];
   177 		*flags = p->flags;
   178 		*version = &pool[p->version];
   179 	} else {
   180 		*property = NULL;
   181 	}
   182 
   183 	return valid;
   184 }
   185 
   186 void
   187 razor_property_iterator_destroy(struct razor_property_iterator *pi)
   188 {
   189 	free(pi);
   190 }
   191 
   192 struct razor_package_query {
   193 	struct razor_set *set;
   194 	char *vector;
   195 	int count;
   196 };
   197 
   198 struct razor_package_query *
   199 razor_package_query_create(struct razor_set *set)
   200 {
   201 	struct razor_package_query *pq;
   202 	int count;
   203 
   204 	pq = zalloc(sizeof *pq);
   205 	pq->set = set;
   206 	count = set->packages.size / sizeof(struct razor_package);
   207 	pq->vector = zalloc(count * sizeof(char));
   208 
   209 	return pq;
   210 }
   211 
   212 void
   213 razor_package_query_add_package(struct razor_package_query *pq,
   214 				struct razor_package *p)
   215 {
   216 	struct razor_package *packages;
   217 
   218 	packages = pq->set->packages.data;
   219 	pq->count += pq->vector[p - packages] ^ 1;
   220 	pq->vector[p - packages] = 1;
   221 }
   222 
   223 void
   224 razor_package_query_add_iterator(struct razor_package_query *pq,
   225 				 struct razor_package_iterator *pi)
   226 {
   227 	struct razor_package *packages, *p;
   228 	const char *name, *version, *arch;
   229 
   230 	packages = pq->set->packages.data;
   231 	while (razor_package_iterator_next(pi, &p, &name, &version, &arch)) {
   232 		pq->count += pq->vector[p - packages] ^ 1;
   233 		pq->vector[p - packages] = 1;
   234 	}
   235 }
   236 
   237 struct razor_package_iterator *
   238 razor_package_query_finish(struct razor_package_query *pq)
   239 {
   240 	struct razor_package_iterator *pi;
   241 	struct razor_set *set;
   242 	struct list *index;
   243 	int i, j;
   244 
   245 	set = pq->set;
   246 	if (pq->count > 0)
   247 		index = zalloc(pq->count * sizeof *index);
   248 	else
   249 		index = NULL;
   250 
   251 	for (i = 0, j = 0; i < pq->count; i++) {
   252 		if (!pq->vector[i])
   253 			continue;
   254 
   255 		index[j].data = i;
   256 		if (j == pq->count - 1)
   257 			index[j].flags = 0x80;
   258 		j++;
   259 	}
   260 
   261 	free(pq->vector);
   262 	free(pq);
   263 
   264 	pi = razor_package_iterator_create_with_index(set, index);
   265 	pi->free_index = 1;
   266 
   267 	return pi;
   268 }