summaryrefslogtreecommitdiff
path: root/lib/rpmdb.c
diff options
context:
space:
mode:
authorPanu Matilainen <pmatilai@redhat.com>2008-11-29 13:52:32 +0200
committerPanu Matilainen <pmatilai@redhat.com>2008-11-29 13:52:32 +0200
commit604a54277ed21f1fd983c205ad7d36feb3950ce1 (patch)
tree5417965701b972845487586c52694ab6bfafa903 /lib/rpmdb.c
parent881f14d277eefc70d65bf48b1837f0219572f397 (diff)
downloadrpm-604a54277ed21f1fd983c205ad7d36feb3950ce1.tar.gz
rpm-604a54277ed21f1fd983c205ad7d36feb3950ce1.tar.bz2
rpm-604a54277ed21f1fd983c205ad7d36feb3950ce1.zip
Unify dbiIndexSet allocations, allocate in power-of-two sizes
- allocating in even sized chunks helps avoiding crazy memory fragmentation when resizing a lot (rhbz#472507) - HEAD doesn't really need, rpm 4.6.x does, but doesn't hurt either...
Diffstat (limited to 'lib/rpmdb.c')
-rw-r--r--lib/rpmdb.c33
1 files changed, 23 insertions, 10 deletions
diff --git a/lib/rpmdb.c b/lib/rpmdb.c
index 6659f8d9d..bc5c9edfa 100644
--- a/lib/rpmdb.c
+++ b/lib/rpmdb.c
@@ -334,6 +334,25 @@ union _dbswap {
\
}
+/*
+ * Ensure sufficient memory for nrecs of new records in dbiIndexSet.
+ * Allocate in power of two sizes to avoid memory fragmentation, so
+ * realloc is not always needed.
+ */
+static inline void dbiGrowSet(dbiIndexSet set, unsigned int nrecs)
+{
+ size_t need = (set->count + nrecs) * sizeof(*(set->recs));
+ size_t alloced = set->alloced ? set->alloced : 1 << 4;
+
+ while (alloced < need)
+ alloced <<= 1;
+
+ if (alloced != set->alloced) {
+ set->recs = xrealloc(set->recs, alloced);
+ set->alloced = alloced;
+ }
+}
+
/**
* Convert retrieved data to index set.
* @param dbi index database handle
@@ -356,9 +375,9 @@ static int dbt2set(dbiIndex dbi, DBT * data, dbiIndexSet * setp)
return 0;
}
- set = xmalloc(sizeof(*set));
+ set = xcalloc(1, sizeof(*set));
+ dbiGrowSet(set, data->size / dbi->dbi_jlen);
set->count = data->size / dbi->dbi_jlen;
- set->recs = xmalloc(set->count * sizeof(*(set->recs)));
switch (dbi->dbi_jlen) {
default:
@@ -483,9 +502,7 @@ static int dbiAppendSet(dbiIndexSet set, const void * recs,
if (set == NULL || recs == NULL || nrecs <= 0 || recsize == 0)
return 1;
- set->recs = xrealloc(set->recs,
- (set->count + nrecs) * sizeof(*(set->recs)));
-
+ dbiGrowSet(set, nrecs);
memset(set->recs + set->count, 0, nrecs * sizeof(*(set->recs)));
while (nrecs-- > 0) {
@@ -2165,11 +2182,7 @@ static int rpmdbGrowIterator(rpmdbMatchIterator mi)
if (mi->mi_set == NULL) {
mi->mi_set = set;
} else {
-#if 0
-fprintf(stderr, "+++ %d = %d + %d\t\"%s\"\n", (mi->mi_set->count + set->count), mi->mi_set->count, set->count, ((char *)key->data));
-#endif
- mi->mi_set->recs = xrealloc(mi->mi_set->recs,
- (mi->mi_set->count + set->count) * sizeof(*(mi->mi_set->recs)));
+ dbiGrowSet(mi->mi_set, set->count);
memcpy(mi->mi_set->recs + mi->mi_set->count, set->recs,
set->count * sizeof(*(mi->mi_set->recs)));
mi->mi_set->count += set->count;