r9769: r11592@blu: tridge | 2005-08-30 10:40:19 +1000
authorAndrew Tridgell <tridge@samba.org>
Tue, 30 Aug 2005 00:36:12 +0000 (00:36 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:34:58 +0000 (13:34 -0500)
 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)

source4/lib/tdb/common/tdb.c

index 4c2d9a1addbf83a17f74ebef0b53981b5b6a839c..8e8e3ce3b36c941623848a653d569729485e7444 100644 (file)
@@ -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;