1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
|
/*
* Copyright (c) 2007, Novell Inc.
*
* This program is licensed under the BSD license, read LICENSE.BSD
* for further information
*/
/*
* repo.h
*
*/
#ifndef SATSOLVER_REPO_H
#define SATSOLVER_REPO_H
#include <regex.h>
#include "pooltypes.h"
#include "pool.h"
#include "repodata.h"
typedef struct _Repokey {
Id name;
Id type; /* REPOKEY_TYPE_xxx */
unsigned int size;
unsigned int storage; /* KEY_STORAGE_xxx */
} Repokey;
#define KEY_STORAGE_DROPPED 0
#define KEY_STORAGE_SOLVABLE 1
#define KEY_STORAGE_INCORE 2
#define KEY_STORAGE_VERTICAL_OFFSET 3
typedef struct _Repo {
const char *name;
struct _Pool *pool; /* pool containing repo data */
int start; /* start of this repo solvables within pool->solvables */
int end; /* last solvable + 1 of this repo */
int nsolvables; /* number of solvables repo is contributing to pool */
int nextra; /* number of extra objects (non-solvables) */
int priority; /* priority of this repo */
Id *idarraydata; /* array of metadata Ids, solvable dependencies are offsets into this array */
int idarraysize;
Offset lastoff;
Id *rpmdbid; /* hmm, go to repodata? */
unsigned char rpmdbcookie[32];
Repodata *repodata; /* our stores for non-solvable related data */
unsigned nrepodata; /* number of our stores.. */
} Repo;
extern Repo *repo_create(Pool *pool, const char *name);
extern void repo_free(Repo *repo, int reuseids);
extern void repo_freeallrepos(Pool *pool, int reuseids);
extern void *repo_sidedata_create(Repo *repo, size_t size);
extern void *repo_sidedata_extend(Repo *repo, void *b, size_t size, Id p, int count);
extern Offset repo_addid(Repo *repo, Offset olddeps, Id id);
extern Offset repo_addid_dep(Repo *repo, Offset olddeps, Id id, Id marker);
extern Offset repo_reserve_ids(Repo *repo, Offset olddeps, int num);
extern Offset repo_fix_supplements(Repo *repo, Offset provides, Offset supplements, Offset freshens);
extern Offset repo_fix_conflicts(Repo *repo, Offset conflicts);
static inline const char *repo_name(const Repo *repo)
{
return repo->name;
}
static inline Id repo_add_solvable(Repo *repo)
{
extern Id pool_add_solvable(Pool *pool);
Id p = pool_add_solvable(repo->pool);
if (!repo->start || repo->start == repo->end)
{
repo->start = p;
repo->end = p + 1;
}
else
{
if (repo->rpmdbid)
repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, 1);
if (p < repo->start)
repo->start = p;
if (p + 1 > repo->end)
repo->end = p + 1;
}
repo->nsolvables++;
repo->pool->solvables[p].repo = repo;
return p;
}
static inline Id repo_add_solvable_block(Repo *repo, int count)
{
extern Id pool_add_solvable_block(Pool *pool, int count);
Id p;
Solvable *s;
if (!count)
return 0;
p = pool_add_solvable_block(repo->pool, count);
if (!repo->start || repo->start == repo->end)
{
repo->start = p;
repo->end = p + count;
}
else
{
if (repo->rpmdbid)
repo->rpmdbid = (Id *)repo_sidedata_extend(repo, repo->rpmdbid, sizeof(Id), p, count);
if (p < repo->start)
repo->start = p;
if (p + count > repo->end)
repo->end = p + count;
}
repo->nsolvables += count;
for (s = repo->pool->solvables + p; count--; s++)
s->repo = repo;
return p;
}
static inline void repo_free_solvable_block(Repo *repo, Id start, int count, int reuseids)
{
extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
Solvable *s;
int i;
if (start + count == repo->end)
repo->end -= count;
repo->nsolvables -= count;
for (s = repo->pool->solvables + start, i = count; i--; s++)
s->repo = 0;
pool_free_solvable_block(repo->pool, start, count, reuseids);
}
#define FOR_REPO_SOLVABLES(r, p, s) \
for (p = (r)->start, s = (r)->pool->solvables + p; p < (r)->end; p++, s = (r)->pool->solvables + p) \
if (s->repo == (r))
/* search callback values */
#define SEARCH_NEXT_KEY 1
#define SEARCH_NEXT_SOLVABLE 2
#define SEARCH_STOP 3
typedef struct _KeyValue {
Id id;
const char *str;
int num;
int num2;
int eof;
} KeyValue;
/* search flags */
#define SEARCH_STRINGMASK 15
#define SEARCH_STRING 1
#define SEARCH_SUBSTRING 2
#define SEARCH_GLOB 3
#define SEARCH_REGEX 4
#define SEARCH_NOCASE (1<<8)
#define SEARCH_NO_STORAGE_SOLVABLE (1<<9)
#define SEARCH_EXTRA (1<<10)
#define SEARCH_ALL_REPOS (1<<11)
#define SEARCH_SKIP_KIND (1<<12)
/* By default we don't match in attributes representing filelists
because the construction of those strings is costly. Specify this
flag if you want this. In that case kv->str will contain the full
filename (if matched of course). */
#define SEARCH_FILES (1<<13)
/* Internal */
#define __SEARCH_ONESOLVABLE (1 << 31)
Repodata *repo_add_repodata(Repo *repo, int localpool);
void repo_search(Repo *repo, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
/* returns the string value of the attribute, or NULL if not found */
const char * repo_lookup_str(Solvable *s, Id key);
/* returns the integer value of the attribute, or 0 if not found */
unsigned int repo_lookup_num(Solvable *s, Id key);
/* generic attribute lookup */
int repo_lookup(Solvable *s, Id key, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, KeyValue *kv), void *cbdata);
typedef struct _Dataiterator
{
Repodata *data;
Id *keyp;
unsigned char *nextkeydp;
unsigned char *dp;
Repokey *key;
Repo *repo;
Id *idp;
const char *match;
Id solvid;
Id keyname;
unsigned flags;
unsigned state;
KeyValue kv;
regex_t regex;
int regex_err;
Id *subkeyp;
int subnum;
Id subschema;
} Dataiterator;
/* Use these like:
Dataiterator di;
dataiterator_init(&di, repo, 0, 0, "bla", SEARCH_SUBSTRING);
while (dataiterator_step(&di))
dosomething(di.solvid, di.key, di.kv); */
void dataiterator_init(Dataiterator *di, Repo *repo, Id p, Id keyname,
const char *match, int flags);
int dataiterator_step(Dataiterator *di);
int dataiterator_match(Dataiterator *di, int flags, const void *match);
void dataiterator_skip_attribute(Dataiterator *di);
void dataiterator_skip_solvable(Dataiterator *di);
void dataiterator_skip_repo(Dataiterator *di);
void dataiterator_jump_to_solvable(Dataiterator *di, Solvable *s);
void dataiterator_jump_to_repo(Dataiterator *di, Repo *repo);
void repo_set_id(Repo *repo, Id p, Id keyname, Id id);
void repo_set_num(Repo *repo, Id p, Id keyname, Id num);
void repo_set_str(Repo *repo, Id p, Id keyname, const char *str);
void repo_set_poolstr(Repo *repo, Id p, Id keyname, const char *str);
void repo_add_poolstr_array(Repo *repo, Id p, Id keyname, const char *str);
void repo_internalize(Repo *repo);
void repo_disable_paging(Repo *repo);
#endif /* SATSOLVER_REPO_H */
|