summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2012-09-12 16:47:43 +0300
committerPanu Matilainen <pmatilai@redhat.com>2012-09-12 19:17:20 +0300
commit06546854933d0d7682bffbdf11c50c1efde17045 (patch)
treeb20ade2fd5d4e73ac875aee9a2c45aed250381ed
parent86dbb8844807b077f27255cccc9c0714a0005d02 (diff)
downloadlibrpm-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.c2
-rw-r--r--lib/rpmds.c6
-rw-r--r--lib/rpmfi.c2
-rw-r--r--rpmio/rpmstrpool.c43
-rw-r--r--rpmio/rpmstrpool.h4
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);