From: Michael Schroeder Date: Mon, 9 Jul 2018 11:32:54 +0000 (+0200) Subject: Refactor pool_resize_rels_hash X-Git-Tag: 0.6.35~39 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=f0693b9f08b392cf2b0d63b198ddefcef3deca46;p=thirdparty%2Flibsolv.git Refactor pool_resize_rels_hash --- diff --git a/src/pool.c b/src/pool.c index ba5e799c..60cc0f49 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/poolid.c b/src/poolid.c index bb8d4f6d..3b55f764 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 23635955..79a3ccdc 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/repo_solv.c b/src/repo_solv.c index 3509e866..42c27e85 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -739,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 */ } @@ -761,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 @@ -818,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 */ }