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:
parent
9c78f3b0d6
commit
cfe5a7e5f8
@ -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;
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user