diff options
author | Andrew Tridgell <tridge@samba.org> | 2005-08-30 00:36:12 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 13:34:58 -0500 |
commit | 37194224416d7509a457ee4aa18991b8bab0da7d (patch) | |
tree | ecf50079f5b0ca18a1163c27367a85d841c7944f /source4/lib/tdb/common | |
parent | 584f3aeb7e4a59d9c6aa7650c196fd2c86500c16 (diff) | |
download | samba-37194224416d7509a457ee4aa18991b8bab0da7d.tar.gz samba-37194224416d7509a457ee4aa18991b8bab0da7d.tar.bz2 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/common')
-rw-r--r-- | source4/lib/tdb/common/tdb.c | 37 |
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; |