/* freeze the pool to save memory, but only if private pool */
if (ds->pool != pool)
- rpmstrPoolFreeze(ds->pool);
+ rpmstrPoolFreeze(ds->pool, 0);
}
exit:
/* 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);
rpmdsFree(ds);
}
if (*dsp)
- rpmstrPoolFreeze((*dsp)->pool);
+ rpmstrPoolFreeze((*dsp)->pool, 0);
return rc;
}
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 */
};
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;
}
}
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);
}
}