From 3eadc5e345fc9c6260da89e5b24d63bda5781774 Mon Sep 17 00:00:00 2001 From: Michael Schroeder Date: Mon, 9 Jul 2018 12:59:20 +0200 Subject: [PATCH] Refactor internal stringpool_resize_hash function --- src/repo_solv.c | 29 +++++----------------------- src/strpool.c | 50 +++++++++++++++++++++++++++++++------------------ src/strpool.h | 1 + 3 files changed, 38 insertions(+), 42 deletions(-) diff --git a/src/repo_solv.c b/src/repo_solv.c index 034d2fab..3509e866 100644 --- a/src/repo_solv.c +++ b/src/repo_solv.c @@ -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++) diff --git a/src/strpool.c b/src/strpool.c index af43e01d..5e879183 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 c97b8737..f96c5c18 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); -- 2.47.2