diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2012-09-12 16:47:43 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2012-09-12 19:17:20 +0300 |
commit | 06546854933d0d7682bffbdf11c50c1efde17045 (patch) | |
tree | b20ade2fd5d4e73ac875aee9a2c45aed250381ed | |
parent | 86dbb8844807b077f27255cccc9c0714a0005d02 (diff) | |
download | librpm-tizen-06546854933d0d7682bffbdf11c50c1efde17045.tar.gz librpm-tizen-06546854933d0d7682bffbdf11c50c1efde17045.tar.bz2 librpm-tizen-06546854933d0d7682bffbdf11c50c1efde17045.zip |
Allow keeping hash table around on pool freeze, adjust callers
- Pool id -> string always works with a frozen pool, but in some cases
we'll need to go the other way, allow caller to specify whether
string -> id lookups should be possible on frozen pool.
- On glibc, realloc() to smaller size doesn't move the data but on
other platforms (including valgrind) it can and does move, which
would require a full rehash. For now, just leave all the data
alone unless we're also freeing the hash, the memory savings
isn't much for a global pool (which is where this matters)
-rw-r--r-- | lib/depends.c | 2 | ||||
-rw-r--r-- | lib/rpmds.c | 6 | ||||
-rw-r--r-- | lib/rpmfi.c | 2 | ||||
-rw-r--r-- | rpmio/rpmstrpool.c | 43 | ||||
-rw-r--r-- | rpmio/rpmstrpool.h | 4 |
5 files changed, 34 insertions, 23 deletions
diff --git a/lib/depends.c b/lib/depends.c index 79d86d8db..b9d87d94e 100644 --- a/lib/depends.c +++ b/lib/depends.c @@ -330,7 +330,7 @@ rpmal rpmtsCreateAl(rpmts ts, rpmElementTypes types) rpmstrPool tspool = rpmtsPool(ts); /* Required for now to lock string pointers in memory */ - rpmstrPoolFreeze(tspool); + rpmstrPoolFreeze(tspool, 1); al = rpmalCreate(tspool, (rpmtsNElements(ts) / 4) + 1, rpmtsFlags(ts), rpmtsColor(ts), rpmtsPrefColor(ts)); diff --git a/lib/rpmds.c b/lib/rpmds.c index dcf2c39ab..3b7a836f8 100644 --- a/lib/rpmds.c +++ b/lib/rpmds.c @@ -212,7 +212,7 @@ rpmds rpmdsNewPool(rpmstrPool pool, Header h, rpmTagVal tagN, int flags) /* freeze the pool to save memory, but only if private pool */ if (ds->pool != pool) - rpmstrPoolFreeze(ds->pool); + rpmstrPoolFreeze(ds->pool, 0); } exit: @@ -310,7 +310,7 @@ static rpmds singleDS(rpmTagVal tagN, const char * N, const char * EVR, /* freeze the pool on success to save memory */ if (ds != NULL) - rpmstrPoolFreeze(ds->pool); + rpmstrPoolFreeze(ds->pool, 0); /* free or unlink: ds now owns the reference */ rpmstrPoolFree(pool); @@ -989,7 +989,7 @@ int rpmdsRpmlib(rpmds * dsp, const void * tblp) rpmdsFree(ds); } if (*dsp) - rpmstrPoolFreeze((*dsp)->pool); + rpmstrPoolFreeze((*dsp)->pool, 0); return rc; } diff --git a/lib/rpmfi.c b/lib/rpmfi.c index 6f61b70bb..826b0d2b1 100644 --- a/lib/rpmfi.c +++ b/lib/rpmfi.c @@ -1253,7 +1253,7 @@ rpmfi rpmfiNewPool(rpmstrPool pool, Header h, rpmTagVal tagN, rpmfiFlags flags) /* freeze the pool to save memory, but only if private pool */ if (fi->pool != pool) - rpmstrPoolFreeze(fi->pool); + rpmstrPoolFreeze(fi->pool, 0); fi->h = (fi->fiflags & RPMFI_KEEPHEADER) ? headerLink(h) : NULL; } else { diff --git a/rpmio/rpmstrpool.c b/rpmio/rpmstrpool.c index 38b676c03..5792471d8 100644 --- a/rpmio/rpmstrpool.c +++ b/rpmio/rpmstrpool.c @@ -25,6 +25,7 @@ struct rpmstrPool_s { size_t data_size; /* string data area size */ size_t data_alloced; /* string data area allocation size */ strHash hash; /* string -> sid hash table */ + int frozen; /* are new id additions allowed? */ int nrefs; /* refcount */ }; @@ -58,28 +59,38 @@ rpmstrPool rpmstrPoolLink(rpmstrPool pool) return pool; } -void rpmstrPoolFreeze(rpmstrPool pool) +void rpmstrPoolFreeze(rpmstrPool pool, int keephash) { - if (pool && pool->hash) { - pool->hash = strHashFree(pool->hash); - pool->data_alloced = pool->data_size; - pool->data = xrealloc(pool->data, pool->data_alloced); - pool->offs_alloced = pool->offs_size + 1; - pool->offs = xrealloc(pool->offs, - pool->offs_alloced * sizeof(*pool->offs)); + if (pool && !pool->frozen) { + /* + * realloc() might require rehashing even when downsizing, + * dont bother unless we're also discarding the hash. + */ + if (!keephash) { + pool->hash = strHashFree(pool->hash); + pool->data_alloced = pool->data_size; + pool->data = xrealloc(pool->data, pool->data_alloced); + pool->offs_alloced = pool->offs_size + 1; + pool->offs = xrealloc(pool->offs, + pool->offs_alloced * sizeof(*pool->offs)); + } + pool->frozen = 1; } } void rpmstrPoolUnfreeze(rpmstrPool pool) { - if (pool && pool->hash == NULL) { - int sizehint = (pool->offs_size / 2) - 1; - if (sizehint < STRHASH_INITSIZE) - sizehint = STRHASH_INITSIZE; - pool->hash = strHashCreate(sizehint, rstrhash, strcmp, NULL, NULL); - for (int i = 1; i < pool->offs_size; i++) { - strHashAddEntry(pool->hash, rpmstrPoolStr(pool, i), i); + if (pool) { + if (pool->hash == NULL) { + int sizehint = (pool->offs_size / 2) - 1; + if (sizehint < STRHASH_INITSIZE) + sizehint = STRHASH_INITSIZE; + pool->hash = strHashCreate(sizehint, rstrhash, strcmp, NULL, NULL); + for (int i = 1; i < pool->offs_size; i++) { + strHashAddEntry(pool->hash, rpmstrPoolStr(pool, i), i); + } } + pool->frozen = 0; } } @@ -130,7 +141,7 @@ rpmsid rpmstrPoolIdn(rpmstrPool pool, const char *s, size_t slen, int create) rpmsid *sids; if (strHashGetHEntry(pool->hash, s, hash, &sids, NULL, NULL)) { sid = sids[0]; - } else if (create) { + } else if (create && !pool->frozen) { sid = rpmstrPoolPut(pool, s, slen, hash); } } diff --git a/rpmio/rpmstrpool.h b/rpmio/rpmstrpool.h index 958a47033..67e162056 100644 --- a/rpmio/rpmstrpool.h +++ b/rpmio/rpmstrpool.h @@ -18,8 +18,8 @@ rpmstrPool rpmstrPoolFree(rpmstrPool sidpool); /* reference a string pool */ rpmstrPool rpmstrPoolLink(rpmstrPool sidpool); -/* freeze pool to free memory */ -void rpmstrPoolFreeze(rpmstrPool sidpool); +/* freeze pool to free memory (keephash required for string -> id lookups) */ +void rpmstrPoolFreeze(rpmstrPool sidpool, int keephash); /* unfreeze pool (ie recreate hash table) */ void rpmstrPoolUnfreeze(rpmstrPool sidpool); |