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 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 && oldnstrings != pool->ss.nstrings && (id & WHATPROVIDES_BLOCK) == 0)
33 /* grow whatprovides array */
34 pool->whatprovides = xrealloc(pool->whatprovides, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
35 memset(pool->whatprovides + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
41 rel2id(Pool *pool, Id name, Id evr, int flags, int create)
51 hashmask = pool->relhashmask;
52 hashtbl = pool->relhashtbl;
55 /* extend hashtable if needed */
56 if (pool->nrels * 2 > hashmask)
58 xfree(pool->relhashtbl);
59 pool->relhashmask = hashmask = mkmask(pool->ss.nstrings + REL_BLOCK);
60 pool->relhashtbl = hashtbl = xcalloc(hashmask + 1, sizeof(Id));
61 // rehash all rels into new hashtable
62 for (i = 1; i < pool->nrels; i++)
64 h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
67 h = HASHCHAIN_NEXT(h, hh, hashmask);
72 /* compute hash and check for match */
73 h = relhash(name, evr, flags) & hashmask;
75 while ((id = hashtbl[h]) != 0)
77 if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
79 h = HASHCHAIN_NEXT(h, hh, hashmask);
82 return MAKERELDEP(id);
88 /* extend rel space if needed */
89 if ((id & REL_BLOCK) == 0)
90 pool->rels = xrealloc(pool->rels, ((pool->nrels + REL_BLOCK) & ~REL_BLOCK) * sizeof(Reldep));
92 ran = pool->rels + id;
97 /* extend whatprovides_rel if needed */
98 if (pool->whatprovides_rel && (id & WHATPROVIDES_BLOCK) == 0)
100 pool->whatprovides_rel = xrealloc(pool->whatprovides_rel, (id + (WHATPROVIDES_BLOCK + 1)) * sizeof(Offset));
101 memset(pool->whatprovides_rel + id, 0, (WHATPROVIDES_BLOCK + 1) * sizeof(Offset));
103 return MAKERELDEP(id);
108 // for rels (returns name only) and strings
111 id2str(Pool *pool, Id id)
115 Reldep *rd = GETRELDEP(pool, id);
116 if (ISRELDEP(rd->name))
118 return pool->ss.stringspace + pool->ss.strings[rd->name];
120 return pool->ss.stringspace + pool->ss.strings[id];
123 static const char *rels[] = {
135 // get operator for RelId
137 id2rel(Pool *pool, Id id)
142 rd = GETRELDEP(pool, id);
145 case 0: case 1: case 2: case 3:
146 case 4: case 5: case 6: case 7:
147 return rels[rd->flags & 7];
155 return " NAMESPACE ";
166 id2evr(Pool *pool, Id id)
171 rd = GETRELDEP(pool, id);
172 if (ISRELDEP(rd->evr))
174 return pool->ss.stringspace + pool->ss.strings[rd->evr];
178 dep2str(Pool *pool, Id id)
183 int n, l, ls1, ls2, lsr;
186 return pool->ss.stringspace + pool->ss.strings[id];
187 rd = GETRELDEP(pool, id);
190 sr = id2rel(pool, id);
193 s2 = (char *)dep2str(pool, rd->evr);
197 s1 = (char *)dep2str(pool, rd->name);
201 if (rd->flags == REL_NAMESPACE)
209 if (l + 1 > pool->dep2strlen[n])
211 if (s1 != pool->dep2strbuf[n])
212 pool->dep2strbuf[n] = xrealloc(pool->dep2strbuf[n], l + 32);
215 pool->dep2strbuf[n] = xrealloc(pool->dep2strbuf[n], l + 32);
216 s1 = pool->dep2strbuf[n];
218 pool->dep2strlen[n] = l + 32;
220 if (s1 != pool->dep2strbuf[n])
222 strcpy(pool->dep2strbuf[n], s1);
223 s1 = pool->dep2strbuf[n];
225 strcpy(s1 + ls1, sr);
226 pool->dep2strbuf[n] = s1 + ls1 + lsr;
227 s2 = (char *)dep2str(pool, rd->evr);
228 if (s2 != pool->dep2strbuf[n])
229 strcpy(pool->dep2strbuf[n], s2);
230 pool->dep2strbuf[n] = s1;
231 if (rd->flags == REL_NAMESPACE)
233 s1[ls1 + ls2 + lsr - 1] = ')';
234 s1[ls1 + ls2 + lsr] = 0;
236 pool->dep2strn = (n + 1) % DEP2STRBUF;
242 pool_shrink_strings(Pool *pool)
244 stringpool_shrink(&pool->ss);
248 pool_shrink_rels(Pool *pool)
250 pool->rels = (Reldep *)xrealloc(pool->rels, ((pool->nrels + REL_BLOCK) & ~REL_BLOCK) * sizeof(Reldep));
253 // reset all hash tables
256 pool_freeidhashes(Pool *pool)
258 pool->ss.stringhashtbl = xfree(pool->ss.stringhashtbl);
259 pool->ss.stringhashmask = 0;
260 pool->relhashtbl = xfree(pool->relhashtbl);
261 pool->relhashmask = 0;