summaryrefslogtreecommitdiff
path: root/src/repodata.h
blob: d72c60f19718401727ef0acf4e3cb4c2a90e2241 (plain)
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
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
/*
 * Copyright (c) 2007, Novell Inc.
 *
 * This program is licensed under the BSD license, read LICENSE.BSD
 * for further information
 */

/*
 * repodata.h
 *
 */

#ifndef LIBSOLV_REPODATA_H
#define LIBSOLV_REPODATA_H

#include <stdio.h>

#include "pooltypes.h"
#include "pool.h"
#include "dirpool.h"

#ifdef LIBSOLV_INTERNAL
#include "repopage.h"
#endif

#ifdef __cplusplus
extern "C" {
#endif

#define SIZEOF_MD5	16
#define SIZEOF_SHA1	20
#define SIZEOF_SHA224	28
#define SIZEOF_SHA256	32
#define SIZEOF_SHA384	48
#define SIZEOF_SHA512	64

struct _Repo;
struct _KeyValue;

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

#ifdef LIBSOLV_INTERNAL
struct dircache;
#endif

typedef struct _Repodata {
  Id repodataid;		/* our id */
  struct _Repo *repo;		/* back pointer to repo */

#define REPODATA_AVAILABLE	0
#define REPODATA_STUB		1
#define REPODATA_ERROR		2
#define REPODATA_STORE		3
#define REPODATA_LOADING	4

  int state;			/* available, stub or error */

  void (*loadcallback)(struct _Repodata *);

  int start;			/* start of solvables this repodata is valid for */
  int end;			/* last solvable + 1 of this repodata */

  Repokey *keys;		/* keys, first entry is always zero */
  int nkeys;			/* length of keys array */
  unsigned char keybits[32];	/* keyname hash */

  Id *schemata;			/* schema -> offset into schemadata */
  int nschemata;		/* number of schemata */
  Id *schemadata;		/* schema storage */

  Stringpool spool;		/* local string pool */
  int localpool;		/* is local string pool used */

  Dirpool dirpool;		/* local dir pool */

#ifdef LIBSOLV_INTERNAL
  FILE *fp;			/* file pointer of solv file */
  int error;			/* corrupt solv file */

  unsigned int schemadatalen;   /* schema storage size */
  Id *schematahash;		/* unification helper */

  unsigned char *incoredata;	/* in-core data */
  unsigned int incoredatalen;	/* in-core data used */
  unsigned int incoredatafree;	/* free data len */

  Id mainschema;		/* SOLVID_META schema */
  Id *mainschemaoffsets;	/* SOLVID_META offsets into incoredata */

  Id *incoreoffset;		/* offset for all entries */

  Id *verticaloffset;		/* offset for all verticals, nkeys elements */
  Id lastverticaloffset;	/* end of verticals */

  Repopagestore store;		/* our page store */
  Id storestate;		/* incremented every time the store might change */

  unsigned char *vincore;	/* internal vertical data */
  unsigned int vincorelen;	/* data size */

  Id **attrs;			/* un-internalized attributes */
  Id **xattrs;			/* anonymous handles */
  int nxattrs;			/* number of handles */

  unsigned char *attrdata;	/* their string data space */
  unsigned int attrdatalen;	/* its len */
  Id *attriddata;		/* their id space */
  unsigned int attriddatalen;	/* its len */
  unsigned long long *attrnum64data;	/* their 64bit num data space */
  unsigned int attrnum64datalen;	/* its len */

  /* array cache to speed up repodata_add functions*/
  Id lasthandle;
  Id lastkey;
  Id lastdatalen;

  /* directory cache to speed up repodata_str2dir */
  struct dircache *dircache;
#endif

} Repodata;

#define SOLVID_META		-1
#define SOLVID_POS		-2
#define SOLVID_SUBSCHEMA	-3		/* internal! */


/*-----
 * management functions
 */
void repodata_initdata(Repodata *data, struct _Repo *repo, int localpool);
void repodata_freedata(Repodata *data);

void repodata_free(Repodata *data);
void repodata_empty(Repodata *data, int localpool);


/*
 * key management functions
 */
Id repodata_key2id(Repodata *data, Repokey *key, int create);

static inline Repokey *
repodata_id2key(Repodata *data, Id keyid)
{
  return data->keys + keyid;
}

/*
 * schema management functions
 */
Id repodata_schema2id(Repodata *data, Id *schema, int create);
void repodata_free_schemahash(Repodata *data);

static inline Id *
repodata_id2schema(Repodata *data, Id schemaid)
{
  return data->schemadata + data->schemata[schemaid];
}

/*
 * data search and access
 */

/* check if there is a chance that the repodata contains data for
 * the specified keyname */
static inline int
repodata_precheck_keyname(Repodata *data, Id keyname)
{
  unsigned char x = data->keybits[(keyname >> 3) & (sizeof(data->keybits) - 1)];
  return x && (x & (1 << (keyname & 7))) ? 1 : 0;
}

/* check if the repodata contains data for the specified keyname */
static inline int
repodata_has_keyname(Repodata *data, Id keyname)
{
  int i;
  if (!repodata_precheck_keyname(data, keyname))
    return 0;
  for (i = 1; i < data->nkeys; i++)
    if (data->keys[i].name == keyname)
      return 1;
  return 0;
}

/* search key <keyname> (all keys, if keyname == 0) for Id <solvid>
 * Call <callback> for each match */
void repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback)(void *cbdata, Solvable *s, Repodata *data, Repokey *key, struct _KeyValue *kv), void *cbdata);

/* Make sure the found KeyValue has the "str" field set. Return "str"
 * if valid, NULL if not possible */
const char *repodata_stringify(Pool *pool, Repodata *data, Repokey *key, struct _KeyValue *kv, int flags);

int repodata_filelistfilter_matches(Repodata *data, const char *str);


/* lookup functions */
Id repodata_lookup_type(Repodata *data, Id solvid, Id keyname);
Id repodata_lookup_id(Repodata *data, Id solvid, Id keyname);
const char *repodata_lookup_str(Repodata *data, Id solvid, Id keyname);
int repodata_lookup_num(Repodata *data, Id solvid, Id keyname, unsigned long long *value);
int repodata_lookup_void(Repodata *data, Id solvid, Id keyname);
const unsigned char *repodata_lookup_bin_checksum(Repodata *data, Id solvid, Id keyname, Id *typep);
int repodata_lookup_idarray(Repodata *data, Id solvid, Id keyname, Queue *q);
const void *repodata_lookup_binary(Repodata *data, Id solvid, Id keyname, int *lenp);


/*-----
 * data assignment functions
 */

/*
 * extend the data so that it contains the specified solvables
 * (no longer needed, as the repodata_set functions autoextend)
 */
void repodata_extend(Repodata *data, Id p);
void repodata_extend_block(Repodata *data, Id p, int num);
void repodata_shrink(Repodata *data, int end);

/* internalize freshly set data, so that it is found by the search
 * functions and written out */
void repodata_internalize(Repodata *data);

/* create an anonymous handle. useful for substructures like
 * fixarray/flexarray  */
Id repodata_new_handle(Repodata *data);

/* basic types: void, num, string, Id */
void repodata_set_void(Repodata *data, Id solvid, Id keyname);
void repodata_set_num(Repodata *data, Id solvid, Id keyname, unsigned long long num);
void repodata_set_id(Repodata *data, Id solvid, Id keyname, Id id);
void repodata_set_str(Repodata *data, Id solvid, Id keyname, const char *str);
void repodata_set_binary(Repodata *data, Id solvid, Id keyname, void *buf, int len);
/* create id from string, then set_id */
void repodata_set_poolstr(Repodata *data, Id solvid, Id keyname, const char *str);

/* set numeric constant */
void repodata_set_constant(Repodata *data, Id solvid, Id keyname, unsigned int constant);

/* set Id constant */
void repodata_set_constantid(Repodata *data, Id solvid, Id keyname, Id id);

/* checksum */
void repodata_set_bin_checksum(Repodata *data, Id solvid, Id keyname, Id type,
			       const unsigned char *buf);
void repodata_set_checksum(Repodata *data, Id solvid, Id keyname, Id type,
			   const char *str);
void repodata_set_idarray(Repodata *data, Id solvid, Id keyname, Queue *q);


/* directory (for package file list) */
void repodata_add_dirnumnum(Repodata *data, Id solvid, Id keyname, Id dir, Id num, Id num2);
void repodata_add_dirstr(Repodata *data, Id solvid, Id keyname, Id dir, const char *str);
void repodata_free_dircache(Repodata *data);


/* Arrays */
void repodata_add_idarray(Repodata *data, Id solvid, Id keyname, Id id);
void repodata_add_poolstr_array(Repodata *data, Id solvid, Id keyname, const char *str);
void repodata_add_fixarray(Repodata *data, Id solvid, Id keyname, Id ghandle);
void repodata_add_flexarray(Repodata *data, Id solvid, Id keyname, Id ghandle);

void repodata_unset(Repodata *data, Id solvid, Id keyname);
void repodata_unset_uninternalized(Repodata *data, Id solvid, Id keyname);

/*
 merge/swap attributes from one solvable to another
 works only if the data is not yet internalized
*/
void repodata_merge_attrs(Repodata *data, Id dest, Id src);
void repodata_merge_some_attrs(Repodata *data, Id dest, Id src, Map *keyidmap, int overwrite);
void repodata_swap_attrs(Repodata *data, Id dest, Id src);

Repodata *repodata_create_stubs(Repodata *data);

/*
 * load all paged data, used to speed up copying in repo_rpmdb
 */
void repodata_disable_paging(Repodata *data);

/* helper functions */
Id repodata_globalize_id(Repodata *data, Id id, int create);
Id repodata_localize_id(Repodata *data, Id id, int create);
Id repodata_translate_id(Repodata *data, Repodata *fromdata, Id id, int create);

Id repodata_str2dir(Repodata *data, const char *dir, int create);
const char *repodata_dir2str(Repodata *data, Id did, const char *suf);
const char *repodata_chk2str(Repodata *data, Id type, const unsigned char *buf);
void repodata_set_location(Repodata *data, Id solvid, int medianr, const char *dir, const char *file);
void repodata_set_deltalocation(Repodata *data, Id handle, int medianr, const char *dir, const char *file);
void repodata_set_sourcepkg(Repodata *data, Id solvid, const char *sourcepkg);

/* uninternalized data lookup */
Id repodata_lookup_id_uninternalized(Repodata *data, Id solvid, Id keyname, Id voidid);
const char *repodata_lookup_dirstrarray_uninternalized(Repodata *data, Id solvid, Id keyname, Id *didp, Id *iterp);
const unsigned char *repodata_lookup_bin_checksum_uninternalized(Repodata *data, Id solvid, Id keyname, Id *typep);

/* stats */
unsigned int repodata_memused(Repodata *data);

#ifdef __cplusplus
}
#endif

#endif /* LIBSOLV_REPODATA_H */