summaryrefslogtreecommitdiffstats
path: root/source4/lib/tdb
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2005-08-30 00:36:12 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:34:58 -0500
commit37194224416d7509a457ee4aa18991b8bab0da7d (patch)
treeecf50079f5b0ca18a1163c27367a85d841c7944f /source4/lib/tdb
parent584f3aeb7e4a59d9c6aa7650c196fd2c86500c16 (diff)
downloadsamba-37194224416d7509a457ee4aa18991b8bab0da7d.tar.gz
samba-37194224416d7509a457ee4aa18991b8bab0da7d.tar.xz
samba-37194224416d7509a457ee4aa18991b8bab0da7d.zip
r9769: r11592@blu: tridge | 2005-08-30 10:40:19 +1000
added a tdb optimisation that speeds up non-indexed ldb by a large margin (often 10x or more). I'd be interested in any comments on the safety of this optimisation. See the comment in the code for an explanation. (This used to be commit 7f9efaceb6d6dfc0c82923344cc45ec34493f2ed)
Diffstat (limited to 'source4/lib/tdb')
-rw-r--r--source4/lib/tdb/common/tdb.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/source4/lib/tdb/common/tdb.c b/source4/lib/tdb/common/tdb.c
index 4c2d9a1add..8e8e3ce3b3 100644
--- a/source4/lib/tdb/common/tdb.c
+++ b/source4/lib/tdb/common/tdb.c
@@ -1250,6 +1250,43 @@ static int tdb_next_lock(TDB_CONTEXT *tdb, struct tdb_traverse_lock *tlock,
/* Lock each chain from the start one. */
for (; tlock->hash < tdb->header.hash_size; tlock->hash++) {
+
+ /* this is an optimisation for the common case where
+ the hash chain is empty, which is particularly
+ common for the use of tdb with ldb, where large
+ hashes are used. In that case we spend most of our
+ time in tdb_brlock(), locking empty hash chains.
+
+ To avoid this, we do an unlocked pre-check to see
+ if the hash chain is empty before starting to look
+ inside it. If it is empty then we can avoid that
+ hash chain. If it isn't empty then we can't believe
+ the value we get back, as we read it without a
+ lock, so instead we get the lock and re-fetch the
+ value below.
+
+ Notice that not doing this optimisation on the
+ first hash chain is critical. We must guarantee
+ that we have done at least one fcntl lock at the
+ start of a search to guarantee that memory is
+ coherent on SMP systems. If records are added by
+ others during the search then thats OK, and we
+ could possibly miss those with this trick, but we
+ could miss them anyway without this trick, so the
+ semantics don't change.
+
+ With a non-indexed ldb search this trick gains us a
+ factor of more than 10 in speed on a linux 2.6.x
+ system.
+ */
+ if (!tlock->off && tlock->hash != 0) {
+ u32 off;
+ if (ofs_read(tdb, TDB_HASH_TOP(tlock->hash), &off) == 0 &&
+ off == 0) {
+ continue;
+ }
+ }
+
if (tdb_lock(tdb, tlock->hash, F_WRLCK) == -1)
return -1;