summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/bitmap.c20
-rw-r--r--src/bitmap.h8
-rw-r--r--src/cleandeps.c13
-rw-r--r--src/libsolv.ver4
-rw-r--r--src/policy.c20
-rw-r--r--src/pool.c2
-rw-r--r--src/pool.h6
-rw-r--r--src/poolarch.c7
-rw-r--r--src/poolarch.h6
-rw-r--r--src/poolid.c67
-rw-r--r--src/poolid.h1
-rw-r--r--src/problems.c2
-rw-r--r--src/queue.c22
-rw-r--r--src/queue.h4
-rw-r--r--src/repo.h5
-rw-r--r--src/repo_solv.c69
-rw-r--r--src/repo_write.c154
-rw-r--r--src/repodata.c93
-rw-r--r--src/repodata.h3
-rw-r--r--src/rules.c54
-rw-r--r--src/selection.c6
-rw-r--r--src/solvversion.h.in1
-rw-r--r--src/strpool.c50
-rw-r--r--src/strpool.h1
24 files changed, 295 insertions, 323 deletions
diff --git a/src/bitmap.c b/src/bitmap.c
index e004bf2..4e8adbd 100644
--- a/src/bitmap.c
+++ b/src/bitmap.c
@@ -32,18 +32,18 @@ map_free(Map *m)
m->size = 0;
}
-/* copy constructor t <- s */
+/* copy constructor target <- source */
void
-map_init_clone(Map *t, Map *s)
+map_init_clone(Map *target, const Map *source)
{
- t->size = s->size;
- if (s->size)
+ target->size = source->size;
+ if (source->size)
{
- t->map = solv_malloc(s->size);
- memcpy(t->map, s->map, s->size);
+ target->map = solv_malloc(source->size);
+ memcpy(target->map, source->map, source->size);
}
else
- t->map = 0;
+ target->map = 0;
}
/* grow a map */
@@ -61,7 +61,7 @@ map_grow(Map *m, int n)
/* bitwise-ands maps t and s, stores the result in t. */
void
-map_and(Map *t, Map *s)
+map_and(Map *t, const Map *s)
{
unsigned char *ti, *si, *end;
ti = t->map;
@@ -73,7 +73,7 @@ map_and(Map *t, Map *s)
/* bitwise-ors maps t and s, stores the result in t. */
void
-map_or(Map *t, Map *s)
+map_or(Map *t, const Map *s)
{
unsigned char *ti, *si, *end;
if (t->size < s->size)
@@ -87,7 +87,7 @@ map_or(Map *t, Map *s)
/* remove all set bits in s from t. */
void
-map_subtract(Map *t, Map *s)
+map_subtract(Map *t, const Map *s)
{
unsigned char *ti, *si, *end;
ti = t->map;
diff --git a/src/bitmap.h b/src/bitmap.h
index 0050a6a..1e89590 100644
--- a/src/bitmap.h
+++ b/src/bitmap.h
@@ -37,12 +37,12 @@ typedef struct _Map {
#define MAPCLR_AT(m, n) ((m)->map[(n) >> 3] = 0)
extern void map_init(Map *m, int n);
-extern void map_init_clone(Map *t, Map *s);
+extern void map_init_clone(Map *target, const Map *source);
extern void map_grow(Map *m, int n);
extern void map_free(Map *m);
-extern void map_and(Map *t, Map *s);
-extern void map_or(Map *t, Map *s);
-extern void map_subtract(Map *t, Map *s);
+extern void map_and(Map *t, const Map *s);
+extern void map_or(Map *t, const Map *s);
+extern void map_subtract(Map *t, const Map *s);
extern void map_invertall(Map *m);
static inline void map_empty(Map *m)
diff --git a/src/cleandeps.c b/src/cleandeps.c
index cbe2020..1da28f6 100644
--- a/src/cleandeps.c
+++ b/src/cleandeps.c
@@ -1122,23 +1122,22 @@ solver_createcleandepsmap(Solver *solv, Map *cleandepsmap, int unneeded)
#endif
if (s->repo == installed && pool->implicitobsoleteusescolors)
{
- Id a, bestarch = 0;
+ unsigned int a, bestscore = 0;
FOR_PROVIDES(p, pp, s->name)
{
Solvable *ps = pool->solvables + p;
if (ps->name != s->name || ps->repo == installed)
continue;
- a = ps->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
- if (a && a != 1 && (!bestarch || a < bestarch))
- bestarch = a;
+ a = pool_arch2score(pool, ps->arch);
+ if (a && a != 1 && (!bestscore || a < bestscore))
+ bestscore = a;
}
- if (bestarch && (s->arch > pool->lastarch || pool->id2arch[s->arch] != bestarch))
+ if (bestscore && pool_arch2score(pool, s->arch) != bestscore)
{
FOR_PROVIDES(p, pp, s->name)
{
Solvable *ps = pool->solvables + p;
- if (ps->repo == installed && ps->name == s->name && ps->evr == s->evr && ps->arch != s->arch && ps->arch < pool->lastarch && pool->id2arch[ps->arch] == bestarch)
+ if (ps->repo == installed && ps->name == s->name && ps->evr == s->evr && ps->arch != s->arch && pool_arch2score(pool, ps->arch) == bestscore)
if (!MAPTST(&im, p))
{
#ifdef CLEANDEPSDEBUG
diff --git a/src/libsolv.ver b/src/libsolv.ver
index 9adf60d..a3fa19a 100644
--- a/src/libsolv.ver
+++ b/src/libsolv.ver
@@ -431,3 +431,7 @@ SOLV_1.2 {
pool_set_whatprovides;
selection_subtract;
} SOLV_1.1;
+
+SOLV_1.3 {
+ repodata_set_kv;
+} SOLV_1.2;
diff --git a/src/policy.c b/src/policy.c
index 6f06101..a38dea0 100644
--- a/src/policy.c
+++ b/src/policy.c
@@ -56,11 +56,11 @@ prune_to_best_version_sortcmp(const void *ap, const void *bp, void *dp)
}
if (sa->arch != sb->arch)
{
- int aa, ab;
- aa = (sa->arch <= pool->lastarch) ? pool->id2arch[sa->arch] : 0;
- ab = (sb->arch <= pool->lastarch) ? pool->id2arch[sb->arch] : 0;
+ unsigned int aa, ab;
+ aa = pool_arch2score(pool, sa->arch);
+ ab = pool_arch2score(pool, sb->arch);
if (aa != ab && aa > 1 && ab > 1)
- return aa - ab; /* lowest score first */
+ return aa < ab ? -1 : 1; /* lowest score first */
}
/* the same name, bring installed solvables to the front */
@@ -646,8 +646,7 @@ prune_to_best_arch(const Pool *pool, Queue *plist)
for (i = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];
- a = s->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
+ a = pool_arch2score(pool, s->arch);
if (a && a != 1 && (!bestscore || a < bestscore))
bestscore = a;
}
@@ -656,10 +655,9 @@ prune_to_best_arch(const Pool *pool, Queue *plist)
for (i = j = 0; i < plist->count; i++)
{
s = pool->solvables + plist->elements[i];
- a = s->arch;
- if (a > pool->lastarch)
+ a = pool_arch2score(pool, s->arch);
+ if (!a)
continue;
- a = pool->id2arch[a];
/* a == 1 -> noarch */
if (a != 1 && ((a ^ bestscore) & 0xffff0000) != 0)
continue;
@@ -1383,8 +1381,8 @@ policy_illegal_archchange(Solver *solv, Solvable *s1, Solvable *s2)
return 0;
if (!pool->id2arch)
return 0;
- a1 = a1 <= pool->lastarch ? pool->id2arch[a1] : 0;
- a2 = a2 <= pool->lastarch ? pool->id2arch[a2] : 0;
+ a1 = pool_arch2score(pool, a1);
+ a2 = pool_arch2score(pool, a2);
if (((a1 ^ a2) & 0xffff0000) != 0)
return 1;
return 0;
diff --git a/src/pool.c b/src/pool.c
index ba5e799..60cc0f4 100644
--- a/src/pool.c
+++ b/src/pool.c
@@ -44,7 +44,7 @@ pool_create(void)
pool = (Pool *)solv_calloc(1, sizeof(*pool));
- stringpool_init (&pool->ss, initpool_data);
+ stringpool_init(&pool->ss, initpool_data);
/* alloc space for RelDep 0 */
pool->rels = solv_extend_resize(0, 1, sizeof(Reldep), REL_BLOCK);
diff --git a/src/pool.h b/src/pool.h
index f6573af..e6d1700 100644
--- a/src/pool.h
+++ b/src/pool.h
@@ -88,7 +88,7 @@ struct _Pool {
Id *id2arch; /* map arch ids to scores */
unsigned char *id2color; /* map arch ids to colors */
- Id lastarch; /* last valid entry in id2arch/id2color */
+ Id lastarch; /* size of the id2arch/id2color arrays */
Queue vendormap; /* map vendor to vendorclasses mask */
const char **vendorclasses; /* vendor equivalence classes */
@@ -282,6 +282,10 @@ static inline Solvable *pool_id2solvable(const Pool *pool, Id p)
{
return pool->solvables + p;
}
+static inline Id pool_solvable2id(const Pool *pool, Solvable *s)
+{
+ return s - pool->solvables;
+}
extern const char *pool_solvable2str(Pool *pool, Solvable *s);
static inline const char *pool_solvid2str(Pool *pool, Id p)
diff --git a/src/poolarch.c b/src/poolarch.c
index 8da16c1..4a1fa50 100644
--- a/src/poolarch.c
+++ b/src/poolarch.c
@@ -104,6 +104,9 @@ pool_setarchpolicy(Pool *pool, const char *arch)
}
id = pool->noarchid;
lastarch = id + 255;
+ /* note that we overallocate one element to be compatible with
+ * old versions that accessed id2arch[lastarch].
+ * id2arch[lastarch] will always be zero */
id2arch = solv_calloc(lastarch + 1, sizeof(Id));
id2arch[id] = 1; /* the "noarch" class */
@@ -114,7 +117,7 @@ pool_setarchpolicy(Pool *pool, const char *arch)
if (l)
{
id = pool_strn2id(pool, arch, l, 1);
- if (id > lastarch)
+ if (id >= lastarch)
{
id2arch = solv_realloc2(id2arch, (id + 255 + 1), sizeof(Id));
memset(id2arch + lastarch + 1, 0, (id + 255 - lastarch) * sizeof(Id));
@@ -143,7 +146,7 @@ pool_arch2color_slow(Pool *pool, Id arch)
const char *s;
unsigned char color;
- if (arch > pool->lastarch)
+ if ((unsigned int)arch >= (unsigned int)pool->lastarch)
return ARCHCOLOR_ALL;
if (!pool->id2color)
pool->id2color = solv_calloc(pool->lastarch + 1, 1);
diff --git a/src/poolarch.h b/src/poolarch.h
index 3fe5f02..787883b 100644
--- a/src/poolarch.h
+++ b/src/poolarch.h
@@ -24,7 +24,7 @@ extern unsigned char pool_arch2color_slow(Pool *pool, Id arch);
static inline unsigned char pool_arch2color(Pool *pool, Id arch)
{
- if (arch > pool->lastarch)
+ if ((unsigned int)arch >= (unsigned int)pool->lastarch)
return ARCHCOLOR_ALL;
if (pool->id2color && pool->id2color[arch])
return pool->id2color[arch];
@@ -40,6 +40,10 @@ static inline int pool_colormatch(Pool *pool, Solvable *s1, Solvable *s2)
return 0;
}
+static inline unsigned int pool_arch2score(const Pool *pool, Id arch) {
+ return (unsigned int)arch < (unsigned int)pool->lastarch ? (unsigned int)pool->id2arch[arch] : 0;
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/src/poolid.c b/src/poolid.c
index bb8d4f6..3b55f76 100644
--- a/src/poolid.c
+++ b/src/poolid.c
@@ -51,39 +51,58 @@ pool_strn2id(Pool *pool, const char *str, unsigned int len, int create)
return id;
}
+void
+pool_resize_rels_hash(Pool *pool, int numnew)
+{
+ Hashval h, hh, hashmask;
+ Hashtable hashtbl;
+ int i;
+ Reldep *rd;
+
+ if (numnew <= 0)
+ return;
+ hashmask = mkmask(pool->nrels + numnew);
+ if (hashmask <= pool->relhashmask)
+ return; /* same as before */
+
+ /* realloc hash table */
+ pool->relhashmask = hashmask;
+ solv_free(pool->relhashtbl);
+ pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
+
+ /* rehash all rels into new hashtable */
+ for (i = 1, rd = pool->rels + i; i < pool->nrels; i++, rd++)
+ {
+ h = relhash(rd->name, rd->evr, rd->flags) & hashmask;
+ hh = HASHCHAIN_START;
+ while (hashtbl[h])
+ h = HASHCHAIN_NEXT(h, hh, hashmask);
+ hashtbl[h] = i;
+ }
+}
+
Id
pool_rel2id(Pool *pool, Id name, Id evr, int flags, int create)
{
Hashval h, hh, hashmask;
- int i;
Id id;
Hashtable hashtbl;
Reldep *ran;
- hashmask = pool->relhashmask;
- hashtbl = pool->relhashtbl;
- ran = pool->rels;
/* extend hashtable if needed */
+ hashmask = pool->relhashmask;
if ((Hashval)pool->nrels * 2 > hashmask)
{
- solv_free(pool->relhashtbl);
- pool->relhashmask = hashmask = mkmask(pool->nrels + REL_BLOCK);
- pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
- /* rehash all rels into new hashtable */
- for (i = 1; i < pool->nrels; i++)
- {
- h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
- hh = HASHCHAIN_START;
- while (hashtbl[h])
- h = HASHCHAIN_NEXT(h, hh, hashmask);
- hashtbl[h] = i;
- }
+ pool_resize_rels_hash(pool, REL_BLOCK);
+ hashmask = pool->relhashmask;
}
+ hashtbl = pool->relhashtbl;
/* compute hash and check for match */
h = relhash(name, evr, flags) & hashmask;
hh = HASHCHAIN_START;
+ ran = pool->rels;
while ((id = hashtbl[h]) != 0)
{
if (ran[id].name == name && ran[id].evr == evr && ran[id].flags == flags)
@@ -297,15 +316,28 @@ pool_dep2str(Pool *pool, Id id)
return p;
}
+static void
+pool_free_rels_hash(Pool *pool)
+{
+ pool->relhashtbl = solv_free(pool->relhashtbl);
+ pool->relhashmask = 0;
+}
+
void
pool_shrink_strings(Pool *pool)
{
+ /* free excessive big hashes */
+ if (pool->ss.stringhashmask && pool->ss.stringhashmask > mkmask(pool->ss.nstrings + 8192))
+ stringpool_freehash(&pool->ss);
stringpool_shrink(&pool->ss);
}
void
pool_shrink_rels(Pool *pool)
{
+ /* free excessive big hashes */
+ if (pool->relhashmask && pool->relhashmask > mkmask(pool->nrels + 4096))
+ pool_free_rels_hash(pool);
pool->rels = solv_extend_resize(pool->rels, pool->nrels, sizeof(Reldep), REL_BLOCK);
}
@@ -314,8 +346,7 @@ void
pool_freeidhashes(Pool *pool)
{
stringpool_freehash(&pool->ss);
- pool->relhashtbl = solv_free(pool->relhashtbl);
- pool->relhashmask = 0;
+ pool_free_rels_hash(pool);
}
/* EOF */
diff --git a/src/poolid.h b/src/poolid.h
index 2363595..79a3ccd 100644
--- a/src/poolid.h
+++ b/src/poolid.h
@@ -41,6 +41,7 @@ extern const char *pool_dep2str(Pool *pool, Id); /* might alloc tmpspace */
extern void pool_shrink_strings(Pool *pool);
extern void pool_shrink_rels(Pool *pool);
extern void pool_freeidhashes(Pool *pool);
+extern void pool_resize_rels_hash(Pool *pool, int numnew);
#ifdef __cplusplus
}
diff --git a/src/problems.c b/src/problems.c
index 5bd2bf5..df751c4 100644
--- a/src/problems.c
+++ b/src/problems.c
@@ -1281,7 +1281,7 @@ solver_problemruleinfo2str(Solver *solv, SolverRuleinfo type, Id source, Id targ
if (pool_disabled_solvable(pool, ss))
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is disabled");
if (ss->arch && ss->arch != ARCH_SRC && ss->arch != ARCH_NOSRC &&
- pool->id2arch && (ss->arch > pool->lastarch || !pool->id2arch[ss->arch]))
+ pool->id2arch && pool_arch2score(pool, ss->arch) == 0)
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " does not have a compatible architecture");
return pool_tmpjoin(pool, "package ", pool_solvid2str(pool, source), " is not installable");
case SOLVER_RULE_PKG_NOTHING_PROVIDES_DEP:
diff --git a/src/queue.c b/src/queue.c
index ceb1062..6d5e531 100644
--- a/src/queue.c
+++ b/src/queue.c
@@ -36,21 +36,21 @@ queue_init(Queue *q)
}
void
-queue_init_clone(Queue *t, Queue *s)
+queue_init_clone(Queue *target, const Queue *source)
{
int extra_space;
- if (!s->elements)
+ if (!source->elements)
{
- t->alloc = t->elements = 0;
- t->count = t->left = 0;
+ target->alloc = target->elements = 0;
+ target->count = target->left = 0;
return;
}
- extra_space = queue_extra_space(s->count);
- t->alloc = t->elements = solv_malloc2(s->count + extra_space, sizeof(Id));
- if (s->count)
- memcpy(t->alloc, s->elements, s->count * sizeof(Id));
- t->count = s->count;
- t->left = extra_space;
+ extra_space = queue_extra_space(source->count);
+ target->alloc = target->elements = solv_malloc2(source->count + extra_space, sizeof(Id));
+ if (source->count)
+ memcpy(target->alloc, source->elements, source->count * sizeof(Id));
+ target->count = source->count;
+ target->left = extra_space;
}
void
@@ -168,7 +168,7 @@ queue_delete2(Queue *q, int pos)
}
void
-queue_insertn(Queue *q, int pos, int n, Id *elements)
+queue_insertn(Queue *q, int pos, int n, const Id *elements)
{
if (n <= 0)
return;
diff --git a/src/queue.h b/src/queue.h
index 4785e67..7e56035 100644
--- a/src/queue.h
+++ b/src/queue.h
@@ -109,12 +109,12 @@ queue_truncate(Queue *q, int n)
extern void queue_init(Queue *q);
extern void queue_init_buffer(Queue *q, Id *buf, int size);
-extern void queue_init_clone(Queue *t, Queue *s);
+extern void queue_init_clone(Queue *target, const Queue *source);
extern void queue_free(Queue *q);
extern void queue_insert(Queue *q, int pos, Id id);
extern void queue_insert2(Queue *q, int pos, Id id1, Id id2);
-extern void queue_insertn(Queue *q, int pos, int n, Id *elements);
+extern void queue_insertn(Queue *q, int pos, int n, const Id *elements);
extern void queue_delete(Queue *q, int pos);
extern void queue_delete2(Queue *q, int pos);
extern void queue_deleten(Queue *q, int pos, int n);
diff --git a/src/repo.h b/src/repo.h
index 9dcbcca..bd9c58c 100644
--- a/src/repo.h
+++ b/src/repo.h
@@ -15,6 +15,7 @@
#include "pooltypes.h"
#include "pool.h"
+#include "poolarch.h"
#include "repodata.h"
#include "dataiterator.h"
#include "hash.h"
@@ -102,7 +103,7 @@ static inline int pool_badarch_solvable(const Pool *pool, Solvable *s)
{
if (!s->arch)
return 1;
- if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch]))
+ if (pool->id2arch && pool_arch2score(pool, s->arch) == 0)
return 1;
return 0;
}
@@ -113,7 +114,7 @@ static inline int pool_installable(const Pool *pool, Solvable *s)
return 0;
if (s->repo && s->repo->disabled)
return 0;
- if (pool->id2arch && (s->arch > pool->lastarch || !pool->id2arch[s->arch]))
+ if (pool->id2arch && pool_arch2score(pool, s->arch) == 0)
return 0;
if (pool->considered)
{
diff --git a/src/repo_solv.c b/src/repo_solv.c
index 2460e30..5858d4f 100644
--- a/src/repo_solv.c
+++ b/src/repo_solv.c
@@ -223,7 +223,7 @@ data_read_idarray(unsigned char *dp, Id **storep, Id *map, int max, Repodata *da
data->error = SOLV_ERROR_ID_RANGE;
break;
}
- *store++ = x;
+ *store++ = map ? map[x] : x;
if ((c & 64) == 0)
break;
x = 0;
@@ -612,7 +612,7 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
unsigned int pfsize = read_u32(&data);
char *prefix = solv_malloc(pfsize);
char *pp = prefix;
- char *old_str = 0;
+ char *old_str = strsp;
char *dest = strsp;
int freesp = sizeid;
@@ -682,35 +682,16 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
/* alloc id map for name and rel Ids. this maps ids in the solv files
* to the ids in our pool */
idmap = solv_calloc(numid + numrel, sizeof(Id));
-
- /* grow hash if needed, otherwise reuse */
- hashmask = mkmask(spool->nstrings + numid);
+ stringpool_resize_hash(spool, numid);
+ hashtbl = spool->stringhashtbl;
+ hashmask = spool->stringhashmask;
#if 0
POOL_DEBUG(SOLV_DEBUG_STATS, "read %d strings\n", numid);
- POOL_DEBUG(SOLV_DEBUG_STATS, "string hash buckets: %d, old %d\n", hashmask + 1, spool->stringhashmask + 1);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "string hash buckets: %d\n", hashmask + 1);
#endif
- if (hashmask > spool->stringhashmask)
- {
- spool->stringhashtbl = solv_free(spool->stringhashtbl);
- spool->stringhashmask = hashmask;
- spool->stringhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
- for (i = 1; i < spool->nstrings; i++)
- {
- h = strhash(spool->stringspace + spool->strings[i]) & hashmask;
- hh = HASHCHAIN_START;
- while (hashtbl[h])
- h = HASHCHAIN_NEXT(h, hh, hashmask);
- hashtbl[h] = i;
- }
- }
- else
- {
- hashtbl = spool->stringhashtbl;
- hashmask = spool->stringhashmask;
- }
-
/*
* run over strings and merge with pool.
+ * we could use stringpool_str2id, but this is faster.
* also populate id map (maps solv Id -> pool Id)
*/
for (i = 1; i < numid; i++)
@@ -758,11 +739,6 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
idmap[i] = id; /* repo relative -> pool relative */
sp += l; /* next string */
}
- if (hashmask > mkmask(spool->nstrings + 8192))
- {
- spool->stringhashtbl = solv_free(spool->stringhashtbl);
- spool->stringhashmask = 0;
- }
stringpool_shrink(spool); /* vacuum */
}
@@ -780,31 +756,13 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
pool->rels = solv_realloc2(pool->rels, pool->nrels + numrel, sizeof(Reldep));
ran = pool->rels;
- /* grow hash if needed, otherwise reuse */
- hashmask = mkmask(pool->nrels + numrel);
+ pool_resize_rels_hash(pool, numrel);
+ hashtbl = pool->relhashtbl;
+ hashmask = pool->relhashmask;
#if 0
POOL_DEBUG(SOLV_DEBUG_STATS, "read %d rels\n", numrel);
- POOL_DEBUG(SOLV_DEBUG_STATS, "rel hash buckets: %d, old %d\n", hashmask + 1, pool->relhashmask + 1);
+ POOL_DEBUG(SOLV_DEBUG_STATS, "rel hash buckets: %d\n", hashmask + 1);
#endif
- if (hashmask > pool->relhashmask)
- {
- pool->relhashtbl = solv_free(pool->relhashtbl);
- pool->relhashmask = hashmask;
- pool->relhashtbl = hashtbl = solv_calloc(hashmask + 1, sizeof(Id));
- for (i = 1; i < pool->nrels; i++)
- {
- h = relhash(ran[i].name, ran[i].evr, ran[i].flags) & hashmask;
- hh = HASHCHAIN_START;
- while (hashtbl[h])
- h = HASHCHAIN_NEXT(h, hh, hashmask);
- hashtbl[h] = i;
- }
- }
- else
- {
- hashtbl = pool->relhashtbl;
- hashmask = pool->relhashmask;
- }
/*
* read RelDeps from repo
@@ -837,11 +795,6 @@ repo_add_solv(Repo *repo, FILE *fp, int flags)
}
idmap[i + numid] = MAKERELDEP(id); /* fill Id map */
}
- if (hashmask > mkmask(pool->nrels + 4096))
- {
- pool->relhashtbl = solv_free(pool->relhashtbl);
- pool->relhashmask = 0;
- }
pool_shrink_rels(pool); /* vacuum */
}
diff --git a/src/repo_write.c b/src/repo_write.c
index 396cd42..7e78af5 100644
--- a/src/repo_write.c
+++ b/src/repo_write.c
@@ -260,106 +260,6 @@ write_idarray(Repodata *data, Pool *pool, NeedId *needid, Id *ids)
}
}
-static int
-cmp_ids(const void *pa, const void *pb, void *dp)
-{
- Id a = *(Id *)pa;
- Id b = *(Id *)pb;
- return a - b;
-}
-
-#if 0
-static void
-write_idarray_sort(Repodata *data, Pool *pool, NeedId *needid, Id *ids, Id marker)
-{
- int len, i;
- Id lids[64], *sids;
-
- if (!ids)
- return;
- if (!*ids)
- {
- write_u8(data, 0);
- return;
- }
- for (len = 0; len < 64 && ids[len]; len++)
- {
- Id id = ids[len];
- if (needid)
- id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
- lids[len] = id;
- }
- if (ids[len])
- {
- for (i = len + 1; ids[i]; i++)
- ;
- sids = solv_malloc2(i, sizeof(Id));
- memcpy(sids, lids, 64 * sizeof(Id));
- for (; ids[len]; len++)
- {
- Id id = ids[len];
- if (needid)
- id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
- sids[len] = id;
- }
- }
- else
- sids = lids;
-
- /* That bloody solvable:prereqmarker needs to stay in position :-( */
- if (needid)
- marker = needid[marker].need;
- for (i = 0; i < len; i++)
- if (sids[i] == marker)
- break;
- if (i > 1)
- solv_sort(sids, i, sizeof(Id), cmp_ids, 0);
- if ((len - i) > 2)
- solv_sort(sids + i + 1, len - i - 1, sizeof(Id), cmp_ids, 0);
-
- Id id, old = 0;
-
- /* The differencing above produces many runs of ones and twos. I tried
- fairly elaborate schemes to RLE those, but they give only very mediocre
- improvements in compression, as coding the escapes costs quite some
- space. Even if they are coded only as bits in IDs. The best improvement
- was about 2.7% for the whole .solv file. It's probably better to
- invest some complexity into sharing idarrays, than RLEing. */
- for (i = 0; i < len - 1; i++)
- {
- id = sids[i];
- /* Ugly PREREQ handling. A "difference" of 0 is the prereq marker,
- hence all real differences are offsetted by 1. Otherwise we would
- have to handle negative differences, which would cost code space for
- the encoding of the sign. We loose the exact mapping of prereq here,
- but we know the result, so we can recover from that in the reader. */
- if (id == marker)
- id = old = 0;
- else
- {
- id = id - old + 1;
- old = sids[i];
- }
- /* XXX If difference is zero we have multiple equal elements,
- we might want to skip writing them out. */
- if (id >= 64)
- id = (id & 63) | ((id & ~63) << 1);
- write_id(data, id | 64);
- }
- id = sids[i];
- if (id == marker)
- id = 0;
- else
- id = id - old + 1;
- if (id >= 64)
- id = (id & 63) | ((id & ~63) << 1);
- write_id(data, id);
- if (sids != lids)
- solv_free(sids);
-}
-#endif
-
-
struct extdata {
unsigned char *buf;
int len;
@@ -482,8 +382,19 @@ data_addid64(struct extdata *xd, unsigned int x, unsigned int hx)
data_addid(xd, (Id)x);
}
+#define USE_REL_IDARRAY
+#ifdef USE_REL_IDARRAY
+
+static int
+cmp_ids(const void *pa, const void *pb, void *dp)
+{
+ Id a = *(Id *)pa;
+ Id b = *(Id *)pb;
+ return a - b;
+}
+
static void
-data_addidarray_sort(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marker)
+data_adddepids(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marker)
{
int len, i;
Id lids[64], *sids;
@@ -568,6 +479,27 @@ data_addidarray_sort(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id
solv_free(sids);
}
+#else
+
+static void
+data_adddepids(struct extdata *xd, Pool *pool, NeedId *needid, Id *ids, Id marker)
+{
+ Id id;
+ if (!ids || !*ids)
+ {
+ data_addid(xd, 0);
+ return;
+ }
+ while ((id = *ids++) != 0)
+ {
+ if (needid)
+ id = needid[ISRELDEP(id) ? RELOFF(id) : id].need;
+ data_addideof(xd, id, *ids ? 0 : 1);
+ }
+}
+
+#endif
+
static inline void
data_addblob(struct extdata *xd, unsigned char *blob, int len)
{
@@ -1169,7 +1101,11 @@ repo_write_filtered(Repo *repo, FILE *fp, int (*keyfilter)(Repo *repo, Repokey *
if (i < SOLVABLE_PROVIDES)
keyd.type = REPOKEY_TYPE_ID;
else if (i < RPM_RPMDBID)
+#ifdef USE_REL_IDARRAY
keyd.type = REPOKEY_TYPE_REL_IDARRAY;
+#else
+ keyd.type = REPOKEY_TYPE_IDARRAY;
+#endif
else
keyd.type = REPOKEY_TYPE_NUM;
keyd.size = 0;
@@ -1807,21 +1743,21 @@ fprintf(stderr, "dir %d used %d\n", i, cbdata.dirused ? cbdata.dirused[i] : 1);
if (s->vendor && cbdata.keymap[SOLVABLE_VENDOR])
data_addid(xd, needid[s->vendor].need);
if (s->provides && cbdata.keymap[SOLVABLE_PROVIDES])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->provides, SOLVABLE_FILEMARKER);
+ data_adddepids(xd, pool, needid, idarraydata + s->provides, SOLVABLE_FILEMARKER);
if (s->obsoletes && cbdata.keymap[SOLVABLE_OBSOLETES])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->obsoletes, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->obsoletes, 0);
if (s->conflicts && cbdata.keymap[SOLVABLE_CONFLICTS])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->conflicts, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->conflicts, 0);
if (s->requires && cbdata.keymap[SOLVABLE_REQUIRES])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->requires, SOLVABLE_PREREQMARKER);
+ data_adddepids(xd, pool, needid, idarraydata + s->requires, SOLVABLE_PREREQMARKER);
if (s->recommends && cbdata.keymap[SOLVABLE_RECOMMENDS])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->recommends, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->recommends, 0);
if (s->suggests && cbdata.keymap[SOLVABLE_SUGGESTS])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->suggests, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->suggests, 0);
if (s->supplements && cbdata.keymap[SOLVABLE_SUPPLEMENTS])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->supplements, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->supplements, 0);
if (s->enhances && cbdata.keymap[SOLVABLE_ENHANCES])
- data_addidarray_sort(xd, pool, needid, idarraydata + s->enhances, 0);
+ data_adddepids(xd, pool, needid, idarraydata + s->enhances, 0);
if (repo->rpmdbid && cbdata.keymap[RPM_RPMDBID])
data_addid(xd, repo->rpmdbid[i - repo->start]);
if (anyrepodataused)
diff --git a/src/repodata.c b/src/repodata.c
index 06b2ea3..4ab5d18 100644
--- a/src/repodata.c
+++ b/src/repodata.c
@@ -1016,7 +1016,11 @@ repodata_search(Repodata *data, Id solvid, Id keyname, int flags, int (*callback
ddp = get_data(data, key, &dp, *keyp ? 1 : 0);
if (key->type == REPOKEY_TYPE_DELETED)
- continue;
+ {
+ if (onekey)
+ return;
+ continue;
+ }
if (key->type == REPOKEY_TYPE_FLEXARRAY || key->type == REPOKEY_TYPE_FIXARRAY)
{
struct subschema_data subd;
@@ -2804,6 +2808,47 @@ repodata_add_flexarray(Repodata *data, Id solvid, Id keyname, Id ghandle)
}
void
+repodata_set_kv(Repodata *data, Id solvid, Id keyname, Id keytype, KeyValue *kv)
+{
+ switch (keytype)
+ {
+ case REPOKEY_TYPE_ID:
+ repodata_set_id(data, solvid, keyname, kv->id);
+ break;
+ case REPOKEY_TYPE_CONSTANTID:
+ repodata_set_constantid(data, solvid, keyname, kv->id);
+ break;
+ case REPOKEY_TYPE_IDARRAY:
+ repodata_add_idarray(data, solvid, keyname, kv->id);
+ break;
+ case REPOKEY_TYPE_STR:
+ repodata_set_str(data, solvid, keyname, kv->str);
+ break;
+ case REPOKEY_TYPE_VOID:
+ repodata_set_void(data, solvid, keyname);
+ break;
+ case REPOKEY_TYPE_NUM:
+ repodata_set_num(data, solvid, keyname, SOLV_KV_NUM64(kv));
+ break;
+ case REPOKEY_TYPE_CONSTANT:
+ repodata_set_constant(data, solvid, keyname, kv->num);
+ break;
+ case REPOKEY_TYPE_DIRNUMNUMARRAY:
+ if (kv->id)
+ repodata_add_dirnumnum(data, solvid, keyname, kv->id, kv->num, kv->num2);
+ break;
+ case REPOKEY_TYPE_DIRSTRARRAY:
+ repodata_add_dirstr(data, solvid, keyname, kv->id, kv->str);
+ break;
+ case_CHKSUM_TYPES:
+ repodata_set_bin_checksum(data, solvid, keyname, keytype, (const unsigned char *)kv->str);
+ break;
+ default:
+ break;
+ }
+}
+
+void
repodata_unset_uninternalized(Repodata *data, Id solvid, Id keyname)
{
Id *pp, *ap, **app;
@@ -3512,7 +3557,6 @@ entrydone:
data->incoredatalen = newincore.len;
data->incoredatafree = 0;
- solv_free(data->vincore);
data->vincore = newvincore.buf;
data->vincorelen = newvincore.len;
@@ -3639,44 +3683,19 @@ repodata_create_stubs(Repodata *data)
xkeyname = 0;
continue;
}
- switch (di.key->type)
+ repodata_set_kv(sdata, SOLVID_META, di.key->name, di.key->type, &di.kv);
+ if (di.key->name == REPOSITORY_KEYS && di.key->type == REPOKEY_TYPE_IDARRAY)
{
- case REPOKEY_TYPE_ID:
- repodata_set_id(sdata, SOLVID_META, di.key->name, di.kv.id);
- break;
- case REPOKEY_TYPE_CONSTANTID:
- repodata_set_constantid(sdata, SOLVID_META, di.key->name, di.kv.id);
- break;
- case REPOKEY_TYPE_STR:
- repodata_set_str(sdata, SOLVID_META, di.key->name, di.kv.str);
- break;
- case REPOKEY_TYPE_VOID:
- repodata_set_void(sdata, SOLVID_META, di.key->name);
- break;
- case REPOKEY_TYPE_NUM:
- repodata_set_num(sdata, SOLVID_META, di.key->name, SOLV_KV_NUM64(&di.kv));
- break;
- case_CHKSUM_TYPES:
- repodata_set_bin_checksum(sdata, SOLVID_META, di.key->name, di.key->type, (const unsigned char *)di.kv.str);
- break;
- case REPOKEY_TYPE_IDARRAY:
- repodata_add_idarray(sdata, SOLVID_META, di.key->name, di.kv.id);
- if (di.key->name == REPOSITORY_KEYS)
+ if (!xkeyname)
{
- if (!xkeyname)
- {
- if (!di.kv.eof)
- xkeyname = di.kv.id;
- }
- else
- {
- repodata_add_stubkey(sdata, xkeyname, di.kv.id);
- xkeyname = 0;
- }
+ if (!di.kv.eof)
+ xkeyname = di.kv.id;
+ }
+ else
+ {
+ repodata_add_stubkey(sdata, xkeyname, di.kv.id);
+ xkeyname = 0;
}
- break;
- default:
- break;
}
}
dataiterator_free(&di);
diff --git a/src/repodata.h b/src/repodata.h
index d72c60f..7208e95 100644
--- a/src/repodata.h
+++ b/src/repodata.h
@@ -258,7 +258,6 @@ 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);
@@ -271,6 +270,8 @@ void repodata_add_poolstr_array(Repodata *data, Id solvid, Id keyname, const cha
void repodata_add_fixarray(Repodata *data, Id solvid, Id keyname, Id ghandle);
void repodata_add_flexarray(Repodata *data, Id solvid, Id keyname, Id ghandle);
+/* generic */
+void repodata_set_kv(Repodata *data, Id solvid, Id keyname, Id keytype, struct _KeyValue *kv);
void repodata_unset(Repodata *data, Id solvid, Id keyname);
void repodata_unset_uninternalized(Repodata *data, Id solvid, Id keyname);
diff --git a/src/rules.c b/src/rules.c
index cf368e4..df32341 100644
--- a/src/rules.c
+++ b/src/rules.c
@@ -1031,16 +1031,17 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
}
}
- if (m && pool->implicitobsoleteusescolors && (s->arch > pool->lastarch || pool->id2arch[s->arch] != 1))
+ if (m && pool->implicitobsoleteusescolors && pool_arch2score(pool, s->arch) > 1)
{
- int a = pool->id2arch[s->arch];
+ unsigned int pa, a = pool_arch2score(pool, s->arch);
/* check lock-step candidates */
FOR_PROVIDES(p, pp, s->name)
{
Solvable *ps = pool->solvables + p;
if (s->name != ps->name || s->evr != ps->evr || MAPTST(m, p))
continue;
- if (ps->arch > pool->lastarch || pool->id2arch[ps->arch] == 1 || pool->id2arch[ps->arch] >= a)
+ pa = pool_arch2score(pool, ps->arch);
+ if (!pa || pa == 1 || pa >= a)
continue;
queue_push(&workq, p);
}
@@ -1058,7 +1059,7 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
if (pool_is_complex_dep(pool, rec))
{
pool_add_pos_literals_complex_dep(pool, rec, &workq, m, 0);
- continue;
+ continue;
}
#endif
FOR_PROVIDES(p, pp, rec)
@@ -1075,7 +1076,7 @@ solver_addpkgrulesforsolvable(Solver *solv, Solvable *s, Map *m)
if (pool_is_complex_dep(pool, sug))
{
pool_add_pos_literals_complex_dep(pool, sug, &workq, m, 0);
- continue;
+ continue;
}
#endif
FOR_PROVIDES(p, pp, sug)
@@ -1531,7 +1532,8 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
Pool *pool = solv->pool;
Repo *installed = pool->installed;
int first, i, j;
- Id p, pp, a, aa, bestarch;
+ Id p, pp, aa;
+ unsigned int a, bestscore;
Solvable *s, *ps, *bests;
Queue badq, allowedarchs;
Queue lsq;
@@ -1546,7 +1548,7 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
continue;
s = pool->solvables + i;
first = i;
- bestarch = 0;
+ bestscore = 0;
bests = 0;
queue_empty(&allowedarchs);
FOR_PROVIDES(p, pp, s->name)
@@ -1558,8 +1560,7 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
first = 0;
if (first)
break;
- a = ps->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
+ a = pool_arch2score(pool, ps->arch);
if (a != 1 && installed && ps->repo == installed)
{
if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))
@@ -1567,9 +1568,9 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
queue_pushunique(&allowedarchs, ps->arch); /* also ok to keep this architecture */
continue; /* but ignore installed solvables when calculating the best arch */
}
- if (a && a != 1 && (!bestarch || a < bestarch))
+ if (a && a != 1 && (!bestscore || a < bestscore))
{
- bestarch = a;
+ bestscore = a;
bests = ps;
}
}
@@ -1580,7 +1581,7 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
if (allowedarchs.count == 1 && bests && allowedarchs.elements[0] == bests->arch)
allowedarchs.count--; /* installed arch is best */
- if (allowedarchs.count && pool->implicitobsoleteusescolors && installed && bestarch)
+ if (allowedarchs.count && pool->implicitobsoleteusescolors && installed && bestscore)
{
/* need an extra pass for lockstep checking: we only allow to keep an inferior arch
* if the corresponding installed package is not lock-stepped */
@@ -1593,25 +1594,23 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
continue;
if (solv->dupinvolvedmap_all || (solv->dupinvolvedmap.size && MAPTST(&solv->dupinvolvedmap, p)))
continue;
- a = ps->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
+ a = pool_arch2score(pool, ps->arch);
if (!a)
{
queue_pushunique(&allowedarchs, ps->arch); /* strange arch, allow */
continue;
}
- if (a == 1 || ((a ^ bestarch) & 0xffff0000) == 0)
+ if (a == 1 || ((a ^ bestscore) & 0xffff0000) == 0)
continue;
/* have installed package with inferior arch, check if lock-stepped */
FOR_PROVIDES(p2, pp2, s->name)
{
Solvable *s2 = pool->solvables + p2;
- Id a2;
+ unsigned int a2;
if (p2 == p || s2->name != s->name || s2->evr != pool->solvables[p].evr || s2->arch == pool->solvables[p].arch)
continue;
- a2 = s2->arch;
- a2 = (a2 <= pool->lastarch) ? pool->id2arch[a2] : 0;
- if (a2 && (a2 == 1 || ((a2 ^ bestarch) & 0xffff0000) == 0))
+ a2 = pool_arch2score(pool, s2->arch);
+ if (a2 && (a2 == 1 || ((a2 ^ bestscore) & 0xffff0000) == 0))
break;
}
if (!p2)
@@ -1626,9 +1625,8 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
ps = pool->solvables + p;
if (ps->name != s->name || !MAPTST(addedmap, p))
continue;
- a = ps->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
- if (a != 1 && bestarch && ((a ^ bestarch) & 0xffff0000) != 0)
+ a = pool_arch2score(pool, ps->arch);
+ if (a != 1 && bestscore && ((a ^ bestscore) & 0xffff0000) != 0)
{
if (installed && ps->repo == installed)
{
@@ -1638,11 +1636,12 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
}
for (j = 0; j < allowedarchs.count; j++)
{
+ unsigned int aas;
aa = allowedarchs.elements[j];
if (ps->arch == aa)
break;
- aa = (aa <= pool->lastarch) ? pool->id2arch[aa] : 0;
- if (aa && ((a ^ aa) & 0xffff0000) == 0)
+ aas = pool_arch2score(pool, aa);
+ if (aas && ((a ^ aas) & 0xffff0000) == 0)
break; /* compatible */
}
if (j == allowedarchs.count)
@@ -1654,7 +1653,7 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
for (j = 0; j < badq.count; j++)
{
p = badq.elements[j];
- /* lock-step */
+ /* special lock-step handling */
if (pool->implicitobsoleteusescolors)
{
Id p2;
@@ -1665,9 +1664,8 @@ solver_addinfarchrules(Solver *solv, Map *addedmap)
Solvable *s2 = pool->solvables + p2;
if (p2 == p || s2->name != s->name || s2->evr != pool->solvables[p].evr || s2->arch == pool->solvables[p].arch)
continue;
- a = s2->arch;
- a = (a <= pool->lastarch) ? pool->id2arch[a] : 0;
- if (a && (a == 1 || ((a ^ bestarch) & 0xffff000) == 0))
+ a = pool_arch2score(pool, s2->arch);
+ if (a && (a == 1 || ((a ^ bestscore) & 0xffff000) == 0))
{
queue_push(&lsq, p2);
if (installed && s2->repo == installed)
diff --git a/src/selection.c b/src/selection.c
index 6ca72e5..d44c482 100644
--- a/src/selection.c
+++ b/src/selection.c
@@ -32,7 +32,7 @@ str2archid(Pool *pool, const char *arch)
id = pool_str2id(pool, arch, 0);
if (!id || id == ARCH_SRC || id == ARCH_NOSRC || id == ARCH_NOARCH)
return id;
- if (pool->id2arch && (id > pool->lastarch || !pool->id2arch[id]))
+ if (pool->id2arch && pool_arch2score(pool, id) == 0)
return 0;
return id;
}
@@ -1383,6 +1383,8 @@ setup_limiter(Pool *pool, int flags, struct limiter *limiter)
static int
matchdep_str(const char *pattern, const char *string, int flags)
{
+ if (!pattern || !string)
+ return 0;
if (flags & SELECTION_GLOB)
{
int globflags = (flags & SELECTION_NOCASE) != 0 ? FNM_CASEFOLD : 0;
@@ -1444,6 +1446,8 @@ selection_make_matchdeps_common_limited(Pool *pool, Queue *selection, const char
return 0;
if (!name && !dep)
return 0;
+ if (name && dep)
+ return 0;
if ((flags & SELECTION_MATCH_DEPSTR) != 0)
flags &= ~SELECTION_REL;
diff --git a/src/solvversion.h.in b/src/solvversion.h.in
index 7d107f9..4caba47 100644
--- a/src/solvversion.h.in
+++ b/src/solvversion.h.in
@@ -43,6 +43,7 @@ extern int solv_version_patch;
#cmakedefine LIBSOLVEXT_FEATURE_ZLIB_COMPRESSION
#cmakedefine LIBSOLVEXT_FEATURE_LZMA_COMPRESSION
#cmakedefine LIBSOLVEXT_FEATURE_BZIP2_COMPRESSION
+#cmakedefine LIBSOLVEXT_FEATURE_ZSTD_COMPRESSION
/* see tools/common_write.c for toolversion history */
#define LIBSOLV_TOOLVERSION "1.1"
diff --git a/src/strpool.c b/src/strpool.c
index af43e01..5e87918 100644
--- a/src/strpool.c
+++ b/src/strpool.c
@@ -76,11 +76,39 @@ stringpool_clone(Stringpool *ss, Stringpool *from)
ss->sstrings = from->sstrings;
}
+void
+stringpool_resize_hash(Stringpool *ss, int numnew)
+{
+ Hashval h, hh, hashmask;
+ Hashtable hashtbl;
+ int i;
+
+ if (numnew <= 0)
+ return;
+ hashmask = mkmask(ss->nstrings + numnew);
+ if (hashmask <= ss->stringhashmask)
+ return; /* same as before */
+
+ /* realloc hash table */
+ ss->stringhashmask = hashmask;
+ solv_free(ss->stringhashtbl);
+ ss->stringhashtbl = hashtbl = (Hashtable)solv_calloc(hashmask + 1, sizeof(Id));
+
+ /* rehash all strings into new hashtable */
+ for (i = 1; i < ss->nstrings; i++)
+ {
+ h = strhash(ss->stringspace + ss->strings[i]) & hashmask;
+ hh = HASHCHAIN_START;
+ while (hashtbl[h] != 0)
+ h = HASHCHAIN_NEXT(h, hh, hashmask);
+ hashtbl[h] = i;
+ }
+}
+
Id
stringpool_strn2id(Stringpool *ss, const char *str, unsigned int len, int create)
{
Hashval h, hh, hashmask, oldhashmask;
- int i;
Id id;
Hashtable hashtbl;
@@ -90,27 +118,13 @@ stringpool_strn2id(Stringpool *ss, const char *str, unsigned int len, int create
return STRID_EMPTY;
hashmask = oldhashmask = ss->stringhashmask;
- hashtbl = ss->stringhashtbl;
-
/* expand hashtable if needed */
if ((Hashval)ss->nstrings * 2 > hashmask)
{
- solv_free(hashtbl);
-
- /* realloc hash table */
- ss->stringhashmask = hashmask = mkmask(ss->nstrings + STRING_BLOCK);
- ss->stringhashtbl = hashtbl = (Hashtable)solv_calloc(hashmask + 1, sizeof(Id));
-
- /* rehash all strings into new hashtable */
- for (i = 1; i < ss->nstrings; i++)
- {
- h = strhash(ss->stringspace + ss->strings[i]) & hashmask;
- hh = HASHCHAIN_START;
- while (hashtbl[h] != 0)
- h = HASHCHAIN_NEXT(h, hh, hashmask);
- hashtbl[h] = i;
- }
+ stringpool_resize_hash(ss, STRING_BLOCK);
+ hashmask = ss->stringhashmask;
}
+ hashtbl = ss->stringhashtbl;
/* compute hash and check for match */
h = strnhash(str, len) & hashmask;
diff --git a/src/strpool.h b/src/strpool.h
index c97b873..f96c5c1 100644
--- a/src/strpool.h
+++ b/src/strpool.h
@@ -33,6 +33,7 @@ void stringpool_init_empty(Stringpool *ss);
void stringpool_clone(Stringpool *ss, Stringpool *from);
void stringpool_free(Stringpool *ss);
void stringpool_freehash(Stringpool *ss);
+void stringpool_resize_hash(Stringpool *ss, int numnew);
Id stringpool_str2id(Stringpool *ss, const char *str, int create);
Id stringpool_strn2id(Stringpool *ss, const char *str, unsigned int len, int create);