summaryrefslogtreecommitdiff
path: root/lib/tdb/common/io.c
diff options
context:
space:
mode:
authorRusty Russell <rusty@rustcorp.com.au>2011-12-21 14:17:16 +1030
committerRusty Russell <rusty@rustcorp.com.au>2011-12-21 14:17:16 +1030
commit3a2a755e3380a8f81374009d463cd06161352507 (patch)
treea1394ae9bbb3732dc709562b47b36368c2a1439b /lib/tdb/common/io.c
parentc23f1ee0c9342c6562166331c1b8bf9a2601a77c (diff)
downloadsamba-3a2a755e3380a8f81374009d463cd06161352507.tar.gz
samba-3a2a755e3380a8f81374009d463cd06161352507.tar.bz2
samba-3a2a755e3380a8f81374009d463cd06161352507.zip
tdb: use same expansion factor logic when expanding for new recovery area.
If we're expanding because the current recovery area is too small, we expand only the amount we need. This can quickly lead to exponential growth when we have a slowly-expanding record (hence a slowly-expanding transaction size). Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Diffstat (limited to 'lib/tdb/common/io.c')
-rw-r--r--lib/tdb/common/io.c48
1 files changed, 28 insertions, 20 deletions
diff --git a/lib/tdb/common/io.c b/lib/tdb/common/io.c
index a2db3bf4bd..ac21e3f67a 100644
--- a/lib/tdb/common/io.c
+++ b/lib/tdb/common/io.c
@@ -313,41 +313,49 @@ static int tdb_expand_file(struct tdb_context *tdb, tdb_off_t size, tdb_off_t ad
}
-/* expand the database at least size bytes by expanding the underlying
- file and doing the mmap again if necessary */
-int tdb_expand(struct tdb_context *tdb, tdb_off_t size)
+/* You need 'size', this tells you how much you should expand by. */
+tdb_off_t tdb_expand_adjust(tdb_off_t map_size, tdb_off_t size, int page_size)
{
- struct tdb_record rec;
- tdb_off_t offset, new_size, top_size, map_size;
-
- if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
- TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n"));
- return -1;
- }
-
- /* must know about any previous expansions by another process */
- tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1);
+ tdb_off_t new_size, top_size;
/* limit size in order to avoid using up huge amounts of memory for
* in memory tdbs if an oddball huge record creeps in */
if (size > 100 * 1024) {
- top_size = tdb->map_size + size * 2;
+ top_size = map_size + size * 2;
} else {
- top_size = tdb->map_size + size * 100;
+ top_size = map_size + size * 100;
}
/* always make room for at least top_size more records, and at
least 25% more space. if the DB is smaller than 100MiB,
otherwise grow it by 10% only. */
- if (tdb->map_size > 100 * 1024 * 1024) {
- map_size = tdb->map_size * 1.10;
+ if (map_size > 100 * 1024 * 1024) {
+ new_size = map_size * 1.10;
} else {
- map_size = tdb->map_size * 1.25;
+ new_size = map_size * 1.25;
}
/* Round the database up to a multiple of the page size */
- new_size = MAX(top_size, map_size);
- size = TDB_ALIGN(new_size, tdb->page_size) - tdb->map_size;
+ new_size = MAX(top_size, new_size);
+ return TDB_ALIGN(new_size, page_size) - map_size;
+}
+
+/* expand the database at least size bytes by expanding the underlying
+ file and doing the mmap again if necessary */
+int tdb_expand(struct tdb_context *tdb, tdb_off_t size)
+{
+ struct tdb_record rec;
+ tdb_off_t offset;
+
+ if (tdb_lock(tdb, -1, F_WRLCK) == -1) {
+ TDB_LOG((tdb, TDB_DEBUG_ERROR, "lock failed in tdb_expand\n"));
+ return -1;
+ }
+
+ /* must know about any previous expansions by another process */
+ tdb->methods->tdb_oob(tdb, tdb->map_size, 1, 1);
+
+ size = tdb_expand_adjust(tdb->map_size, size, tdb->page_size);
if (!(tdb->flags & TDB_INTERNAL))
tdb_munmap(tdb);