librazor/iterator.c
author Kristian H?gsberg <krh@redhat.com>
Fri Jun 20 21:56:43 2008 -0400 (2008-06-20)
changeset 254 ccb1c11968ab
parent 248 057933050c42
child 267 2464313cbced
permissions -rw-r--r--
Introduce install/remove iterators.

These iterator constructors lets you pass in two sets and creates
an iterator for the packages to remove or the packages to install.
The iterators will step through the packages in a sequence that respects
the pre, post, preun and postun modifiers.

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