summaryrefslogtreecommitdiff
path: root/src/pool.h
blob: 857032447d7311719f5227a7343f2fbfc5105073 (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
/*
 * Copyright (c) 2007, Novell Inc.
 *
 * This program is licensed under the BSD license, read LICENSE.BSD
 * for further information
 */

/*
 * pool.h
 * 
 */

#ifndef SATSOLVER_POOL_H
#define SATSOLVER_POOL_H

#ifdef __cplusplus
extern "C" {
#endif

#include <stdio.h>

#include "pooltypes.h"
#include "poolid.h"
#include "solvable.h"
#include "bitmap.h"
#include "queue.h"
#include "strpool.h"

/* well known ids */
#include "knownid.h"

/* well known solvable */
#define SYSTEMSOLVABLE		1


/* how many strings to maintain (round robin) */
#define POOL_TMPSPACEBUF 16

//-----------------------------------------------

struct _Repo;
struct _Repodata;
struct _Repokey;
struct _KeyValue;

typedef struct _Repopos {
  struct _Repo *repo;
  Id solvid;
  Id repodataid;
  Id schema;
  Id dp; 
} Repopos;

struct _Pool {
  struct _Stringpool ss;

  Reldep *rels;			/* table of rels: Id -> Reldep */
  int nrels;			/* number of unique rels */
  Hashtable relhashtbl;		/* hashtable: (name,evr,op)Hash -> Id */
  Hashmask relhashmask;

  struct _Repo **repos;
  int nrepos;

  struct _Repo *installed; 	/* packages considered installed */

  Solvable *solvables;
  int nsolvables;

  const char **languages;
  int nlanguages;
  Id *languagecache;
  int languagecacheother;

  int promoteepoch;             /* 0/1  */

  Id *id2arch;			/* map arch ids to scores */
  Id lastarch;			/* last valid entry in id2arch */
  Queue vendormap;		/* map vendor to vendorclasses mask */

  /* providers data, as two-step indirect list
   * whatprovides[Id] -> Offset into whatprovidesdata for name
   * whatprovidesdata[Offset] -> ID_NULL-terminated list of solvables providing Id
   */
  Offset *whatprovides;		/* Offset to providers of a specific name, Id -> Offset  */
  Offset *whatprovides_rel;	/* Offset to providers of a specific relation, Id -> Offset  */

  Id *whatprovidesdata;		/* Ids of solvable providing Id */
  Offset whatprovidesdataoff;	/* next free slot within whatprovidesdata */
  int whatprovidesdataleft;	/* number of 'free slots' within whatprovidesdata */

  /* If nonzero, then consider only the solvables with Ids set in this
     bitmap for solving.  If zero, consider all solvables.  */
  Map *considered;

  Id (*nscallback)(struct _Pool *, void *data, Id name, Id evr);
  void *nscallbackdata;

  /* our tmp space string space */
  char *tmpspacebuf[POOL_TMPSPACEBUF];
  int   tmpspacelen[POOL_TMPSPACEBUF];
  int   tmpspacen;

  /* debug mask and callback */
  int  debugmask;
  void (*debugcallback)(struct _Pool *, void *data, int type, const char *str);
  void *debugcallbackdata;

  /* load callback */
  FILE * (*loadcallback)(struct _Pool *, struct _Repodata *, void *);
  void *loadcallbackdata;

  /* search position */
  Repopos pos;
};

#define SAT_FATAL			(1<<0)
#define SAT_ERROR			(1<<1)
#define SAT_WARN			(1<<2)
#define SAT_DEBUG_STATS			(1<<3)
#define SAT_DEBUG_RULE_CREATION		(1<<4)
#define SAT_DEBUG_PROPAGATE		(1<<5)
#define SAT_DEBUG_ANALYZE		(1<<6)
#define SAT_DEBUG_UNSOLVABLE		(1<<7)
#define SAT_DEBUG_SOLUTIONS		(1<<8)
#define SAT_DEBUG_POLICY		(1<<9)
#define SAT_DEBUG_RESULT		(1<<10)
#define SAT_DEBUG_JOB			(1<<11)
#define SAT_DEBUG_SCHUBI		(1<<12)

//-----------------------------------------------


/* mark dependencies with relation by setting bit31 */

#define MAKERELDEP(id) ((id) | 0x80000000)
#define ISRELDEP(id) (((id) & 0x80000000) != 0)
#define GETRELID(id) ((id) ^ 0x80000000)				/* returns Id */
#define GETRELDEP(pool, id) ((pool)->rels + ((id) ^ 0x80000000))	/* returns Reldep* */

#define REL_GT		1
#define REL_EQ		2
#define REL_LT		4

#define REL_AND		16
#define REL_OR		17
#define REL_WITH	18
#define REL_NAMESPACE	19
#define REL_ARCH	20

#if !defined(__GNUC__) && !defined(__attribute__)
# define __attribute__(x)
#endif

/**
 * Creates a new pool
 */
extern Pool *pool_create(void);
/**
 * Delete a pool
 */
extern void pool_free(Pool *pool);

extern void pool_debug(Pool *pool, int type, const char *format, ...) __attribute__((format(printf, 3, 4)));

extern char *pool_alloctmpspace(Pool *pool, int len);

extern void pool_set_installed(Pool *pool, struct _Repo *repo);

/**
 * Solvable management
 */
extern Id pool_add_solvable(Pool *pool);
extern Id pool_add_solvable_block(Pool *pool, int count);

extern void pool_free_solvable_block(Pool *pool, Id start, int count, int reuseids);
static inline Solvable *pool_id2solvable(Pool *pool, Id p)
{
  return pool->solvables + p;
}
extern const char *solvable2str(Pool *pool, Solvable *s);

void pool_set_languages(Pool *pool, const char **languages, int nlanguages);
Id pool_id2langid(Pool *pool, Id id, const char *lang, int create);

Id solvable_lookup_id(Solvable *s, Id keyname);
unsigned int solvable_lookup_num(Solvable *s, Id keyname, unsigned int notfound);
const char *solvable_lookup_str(Solvable *s, Id keyname);
const char *solvable_lookup_str_poollang(Solvable *s, Id keyname);
const char *solvable_lookup_str_lang(Solvable *s, Id keyname, const char *lang);
int solvable_lookup_bool(Solvable *s, Id keyname);
int solvable_lookup_void(Solvable *s, Id keyname);
char * solvable_get_location(Solvable *s, unsigned int *medianrp);
const unsigned char *solvable_lookup_bin_checksum(Solvable *s, Id keyname, Id *typep);
const char *solvable_lookup_checksum(Solvable *s, Id keyname, Id *typep);
int solvable_identical(Solvable *s1, Solvable *s2);

int solvable_trivial_installable_map(Solvable *s, Map *installedmap, Map *conflictsmap);
int solvable_trivial_installable_repo(Solvable *s, struct _Repo *installed);
int solvable_trivial_installable_queue(Solvable *s, Queue *installed);

void pool_create_state_maps(Pool *pool, Queue *installed, Map *installedmap, Map *conflictsmap);

int pool_match_nevr_rel(Pool *pool, Solvable *s, Id d);

static inline int pool_match_nevr(Pool *pool, Solvable *s, Id d)
{
  if (!ISRELDEP(d))
    return d == s->name;
  else
    return pool_match_nevr_rel(pool, s, d);
}


/**
 * Prepares a pool for solving
 */
extern void pool_createwhatprovides(Pool *pool);
extern void pool_addfileprovides(Pool *pool);
extern void pool_addfileprovides_ids(Pool *pool, struct _Repo *installed, Id **idp);
extern void pool_freewhatprovides(Pool *pool);
extern Id pool_queuetowhatprovides(Pool *pool, Queue *q);

static inline int pool_installable(Pool *pool, Solvable *s)
{
  if (!s->arch || s->arch == ARCH_SRC || s->arch == ARCH_NOSRC)
    return 0;
  if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch]))
    return 0;
  if (pool->considered)
    { 
      Id id = s - pool->solvables;
      if (!MAPTST(pool->considered, id))
	return 0;
    }
  return 1;
}

extern Id pool_addrelproviders(Pool *pool, Id d);

static inline Id pool_whatprovides(Pool *pool, Id d)
{
  Id v;
  if (!ISRELDEP(d))
    return pool->whatprovides[d];
  v = GETRELID(d);
  if (pool->whatprovides_rel[v])
    return pool->whatprovides_rel[v];
  return pool_addrelproviders(pool, d);
}

static inline Id *pool_whatprovides_ptr(Pool *pool, Id d)
{
  Id off = pool_whatprovides(pool, d);
  return pool->whatprovidesdata + off;
}

extern void pool_setdebuglevel(Pool *pool, int level);

static inline void pool_setdebugcallback(Pool *pool, void (*debugcallback)(struct _Pool *, void *data, int type, const char *str), void *debugcallbackdata)
{
  pool->debugcallback = debugcallback;
  pool->debugcallbackdata = debugcallbackdata;
}

static inline void pool_setdebugmask(Pool *pool, int mask)
{
  pool->debugmask = mask;
}

static inline void pool_setloadcallback(Pool *pool, FILE *(*cb)(struct _Pool *, struct _Repodata *, void *), void *loadcbdata)
{
  pool->loadcallback = cb;
  pool->loadcallbackdata = loadcbdata;
}

/* search the pool. the following filters are available:
 *   p     - search just this solvable
 *   key   - search only this key
 *   match - key must match this string
 */
void pool_search(Pool *pool, Id p, Id key, const char *match, int flags, int (*callback)(void *cbdata, Solvable *s, struct _Repodata *data, struct _Repokey *key, struct _KeyValue *kv), void *cbdata);

void pool_clear_pos(Pool *pool);


typedef struct _duchanges {
  const char *path;
  int kbytes;
  int files;
} DUChanges;

void pool_calc_duchanges(Pool *pool, Map *installedmap, DUChanges *mps, int nmps);
int pool_calc_installsizechange(Pool *pool, Map *installedmap);
void pool_trivial_installable(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res);
void pool_trivial_installable_noobsoletesmap(Pool *pool, Map *installedmap, Queue *pkgs, Queue *res, Map *noobsoletesmap);


/* loop over all providers of d */
#define FOR_PROVIDES(v, vp, d) 						\
  for (vp = pool_whatprovides(pool, d) ; (v = pool->whatprovidesdata[vp++]) != 0; )

#define POOL_DEBUG(type, ...) do {if ((pool->debugmask & (type)) != 0) pool_debug(pool, (type), __VA_ARGS__);} while (0)
#define IF_POOLDEBUG(type) if ((pool->debugmask & (type)) != 0)

#ifdef __cplusplus
}
#endif


#endif /* SATSOLVER_POOL_H */