2 * Copyright (c) 2007, Novell Inc.
4 * This program is licensed under the BSD license, read LICENSE.BSD
5 * for further information
20 #include "poolid_private.h"
24 /* intern string into pool, return id */
27 pool_str2id(Pool *pool, const char *str, int create)
29 int oldnstrings = pool->ss.nstrings;
30 Id id = stringpool_str2id(&pool->ss, str, create);
31 if (create && pool->whatprovides && oldnstrings != pool->ss.nstrings && (id & WHATPROVIDES_BLOCK) == 0)
33 /* grow whatprovides array */
34 pool->whatprovides = solv_realloc(pool->whatprovides, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
35 memset(pool->whatprovides + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
41 pool_strn2id(Pool *pool, const char *str, unsigned int len, int create)
43 int oldnstrings = pool->ss.nstrings;
44 Id id = stringpool_strn2id(&pool->ss, str, len, create);
45 if (create && pool->whatprovides && oldnstrings != pool->ss.nstrings && (id & WHATPROVIDES_BLOCK) == 0)
47 /* grow whatprovides array */
48 pool->whatprovides = solv_realloc(pool->whatprovides, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
49 memset(pool->whatprovides + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
55 pool_resize_rels_hash(Pool *pool, int numnew)
57 Hashval h, hh, hashmask;
64 hashmask = mkmask(pool->nrels + numnew);
65 if (hashmask <= pool->relhashmask)
66 return; /* same as before */
68 /* realloc hash table */
69 pool->relhashmask = hashmask;
70 solv_free(pool->relhashtbl);
71 pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
73 /* rehash all rels into new hashtable */
74 for (i = 1, rd = pool->rels + i; i < pool->nrels; i++, rd++)
76 h = relhash(rd->name, rd->evr, rd->flags) & hashmask;
79 h = HASHCHAIN_NEXT(h, hh, hashmask);
85 pool_rel2id(Pool *pool, Id name, Id evr, int flags, int create)
87 Hashval h, hh, hashmask;
93 /* extend hashtable if needed */
94 hashmask = pool->relhashmask;
95 if ((Hashval)pool->nrels * 2 > hashmask)
97 pool_resize_rels_hash(pool, REL_BLOCK);
98 hashmask = pool->relhashmask;
100 hashtbl = pool->relhashtbl;
102 /* compute hash and check for match */
103 h = relhash(name, evr, flags) & hashmask;
104 hh = HASHCHAIN_START;
106 while ((id = hashtbl[h]) != 0)
108 if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
110 h = HASHCHAIN_NEXT(h, hh, hashmask);
113 return MAKERELDEP(id);
119 /* extend rel space if needed */
120 pool->rels = solv_extend(pool->rels, id, 1, sizeof(Reldep), REL_BLOCK);
122 ran = pool->rels + id;
127 /* extend whatprovides_rel if needed */
128 if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
130 pool->whatprovides_rel = solv_realloc2(pool->whatprovides_rel, id + (WHATPROVIDES_BLOCK + 1), sizeof(Offset));
131 memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
133 return MAKERELDEP(id);
138 * for rels (returns name only) and strings
141 pool_id2str(const Pool *pool, Id id)
145 Reldep *rd = GETRELDEP(pool, id);
148 return pool->ss.stringspace + pool->ss.strings[id];
151 static const char *rels[] = {
163 /* get operator for RelId */
165 pool_id2rel(const Pool *pool, Id id)
170 rd = GETRELDEP(pool, id);
173 /* debian special cases < and > */
174 /* haiku special cases <> (maybe we should use != for the others as well */
175 case 0: case REL_EQ: case REL_GT | REL_EQ:
176 case REL_LT | REL_EQ: case REL_LT | REL_EQ | REL_GT:
177 #if !defined(DEBIAN) && !defined(MULTI_SEMANTICS)
178 case REL_LT: case REL_GT:
180 #if !defined(HAIKU) && !defined(MULTI_SEMANTICS)
181 case REL_LT | REL_GT:
183 return rels[rd->flags];
184 #if defined(DEBIAN) || defined(MULTI_SEMANTICS)
186 return pool->disttype == DISTTYPE_DEB ? " >> " : rels[rd->flags];
188 return pool->disttype == DISTTYPE_DEB ? " << " : rels[rd->flags];
190 #if defined(HAIKU) || defined(MULTI_SEMANTICS)
191 case REL_LT | REL_GT:
192 return pool->disttype == DISTTYPE_HAIKU ? " != " : rels[rd->flags];
195 return pool->disttype == DISTTYPE_RPM ? " and " : " & ";
197 return pool->disttype == DISTTYPE_RPM ? " or " : " | ";
199 return pool->disttype == DISTTYPE_RPM ? " with " : " + ";
201 return pool->disttype == DISTTYPE_RPM ? " without " : " - ";
203 return " NAMESPACE "; /* actually not used in dep2str */
208 case REL_FILECONFLICT:
209 return " FILECONFLICT ";
211 return pool->disttype == DISTTYPE_RPM ? " if " : " IF ";
213 return pool->disttype == DISTTYPE_RPM ? " unless " : " UNLESS ";
215 return " compat >= ";
219 return pool->disttype == DISTTYPE_RPM ? " else " : " ELSE ";
229 /* get e:v.r for Id */
231 pool_id2evr(const Pool *pool, Id id)
236 rd = GETRELDEP(pool, id);
237 if (ISRELDEP(rd->evr))
239 return pool->ss.stringspace + pool->ss.strings[rd->evr];
243 dep2strlen(const Pool *pool, Id id)
249 Reldep *rd = GETRELDEP(pool, id);
250 /* add 2 for parens */
251 l += 2 + dep2strlen(pool, rd->name) + strlen(pool_id2rel(pool, id));
254 return l + strlen(pool->ss.stringspace + pool->ss.strings[id]);
258 dep2strcpy(const Pool *pool, char *p, Id id, int oldrel)
262 Reldep *rd = GETRELDEP(pool, id);
264 if (oldrel == REL_AND || oldrel == REL_OR || oldrel == REL_WITH || oldrel == REL_WITHOUT || oldrel == REL_COND || oldrel == REL_UNLESS || oldrel == REL_ELSE || oldrel == -1)
265 if (rel == REL_AND || rel == REL_OR || rel == REL_WITH || rel == REL_WITHOUT || rel == REL_COND || rel == REL_UNLESS || rel == REL_ELSE)
266 if ((oldrel != rel || rel == REL_COND || rel == REL_UNLESS || rel == REL_ELSE) && !((oldrel == REL_COND || oldrel == REL_UNLESS) && rel == REL_ELSE))
269 dep2strcpy(pool, p, rd->name, rd->flags);
271 strcpy(p, pool_id2rel(pool, id));
273 dep2strcpy(pool, p, rd->evr, rd->flags);
277 if (rd->flags == REL_KIND)
279 dep2strcpy(pool, p, rd->evr, rd->flags);
286 dep2strcpy(pool, p, rd->name, rd->flags);
288 if (rd->flags == REL_NAMESPACE)
291 dep2strcpy(pool, p, rd->evr, rd->flags);
295 if (rd->flags == REL_FILECONFLICT)
300 strcpy(p, pool_id2rel(pool, id));
305 strcpy(p, pool->ss.stringspace + pool->ss.strings[id]);
309 pool_dep2str(Pool *pool, Id id)
313 return pool->ss.stringspace + pool->ss.strings[id];
314 p = pool_alloctmpspace(pool, dep2strlen(pool, id) + 1);
315 dep2strcpy(pool, p, id, pool->disttype == DISTTYPE_RPM ? -1 : 0);
320 pool_free_rels_hash(Pool *pool)
322 pool->relhashtbl = solv_free(pool->relhashtbl);
323 pool->relhashmask = 0;
327 pool_shrink_strings(Pool *pool)
329 /* free excessive big hashes */
330 if (pool->ss.stringhashmask && pool->ss.stringhashmask > mkmask(pool->ss.nstrings + 8192))
331 stringpool_freehash(&pool->ss);
332 stringpool_shrink(&pool->ss);
336 pool_shrink_rels(Pool *pool)
338 /* free excessive big hashes */
339 if (pool->relhashmask && pool->relhashmask > mkmask(pool->nrels + 4096))
340 pool_free_rels_hash(pool);
341 pool->rels = solv_extend_resize(pool->rels, pool->nrels, sizeof(Reldep), REL_BLOCK);
344 /* free all hash tables */
346 pool_freeidhashes(Pool *pool)
348 stringpool_freehash(&pool->ss);
349 pool_free_rels_hash(pool);