1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-12 20:58:37 +03:00

r9852: Add tridge's Samba4 tdb optimisations.

Jeremy.
This commit is contained in:
Jeremy Allison 2005-09-01 00:36:46 +00:00 committed by Gerald (Jerry) Carter
parent 9c78f3b0d6
commit cfe5a7e5f8

View File

@ -1248,6 +1248,54 @@ 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 around 80 in speed on a linux 2.6.x
system (testing using ldbtest).
*/
if (!tlock->off && tlock->hash != 0) {
u32 off;
if (tdb->map_ptr) {
for (;tlock->hash < tdb->header.hash_size;tlock->hash++) {
if (0 != *(u32 *)(TDB_HASH_TOP(tlock->hash) + (unsigned char *)tdb->map_ptr)) {
break;
}
}
if (tlock->hash == tdb->header.hash_size) {
continue;
}
} else {
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;