diff options
author | Jeremy Allison <jra@samba.org> | 2004-08-24 22:48:49 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:52:29 -0500 |
commit | fcbb2d3132df36057da73701f7e23f434034e6b0 (patch) | |
tree | 557cf0910ad98186f0851ce19abff8c9900e394f /source3/tdb/tdb.c | |
parent | 990d9d15db27f47d2a6cac306ab773d42427ade4 (diff) | |
download | samba-fcbb2d3132df36057da73701f7e23f434034e6b0.tar.gz samba-fcbb2d3132df36057da73701f7e23f434034e6b0.tar.bz2 samba-fcbb2d3132df36057da73701f7e23f434034e6b0.zip |
r2026: Simplify statcache to use an in-memory tdb. Modify tdb to use
a customer hash function for this tdb (yes it does make a difference
on benchmarks). Remove the no longer used hash.c code.
Jeremy.
(This used to be commit 3fbadac85b8cad89b93d295968e99c38c8677575)
Diffstat (limited to 'source3/tdb/tdb.c')
-rw-r--r-- | source3/tdb/tdb.c | 57 |
1 files changed, 31 insertions, 26 deletions
diff --git a/source3/tdb/tdb.c b/source3/tdb/tdb.c index cda9fc2475..0ebbc8b21e 100644 --- a/source3/tdb/tdb.c +++ b/source3/tdb/tdb.c @@ -329,19 +329,6 @@ static int tdb_unlock(TDB_CONTEXT *tdb, int list, int ltype) return ret; } -/* This is based on the hash algorithm from gdbm */ -static u32 tdb_hash(TDB_DATA *key) -{ - u32 value; /* Used to compute the hash value. */ - u32 i; /* Used to cycle through random values. */ - - /* Set the initial value from the key size. */ - for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) - value = (value + (key->dptr[i] << (i*5 % 24))); - - return (1103515243 * value + 12345); -} - /* check for an out of bounds access - if it is out of bounds then see if the database has been expanded by someone else and expand if necessary @@ -1121,7 +1108,7 @@ TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key) u32 hash; /* find which hash bucket it is in */ - hash = tdb_hash(&key); + hash = tdb->hash_fn(&key); if (!(rec_ptr = tdb_find_lock_hash(tdb,key,hash,F_RDLCK,&rec))) return tdb_null; @@ -1153,7 +1140,7 @@ static int tdb_exists_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) int tdb_exists(TDB_CONTEXT *tdb, TDB_DATA key) { - u32 hash = tdb_hash(&key); + u32 hash = tdb->hash_fn(&key); return tdb_exists_hash(tdb, key, hash); } @@ -1413,7 +1400,7 @@ TDB_DATA tdb_nextkey(TDB_CONTEXT *tdb, TDB_DATA oldkey) if (!tdb->travlocks.off) { /* No previous element: do normal find, and lock record */ - tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb_hash(&oldkey), F_WRLCK, &rec); + tdb->travlocks.off = tdb_find_lock_hash(tdb, oldkey, tdb->hash_fn(&oldkey), F_WRLCK, &rec); if (!tdb->travlocks.off) return tdb_null; tdb->travlocks.hash = BUCKET(rec.full_hash); @@ -1457,7 +1444,7 @@ static int tdb_delete_hash(TDB_CONTEXT *tdb, TDB_DATA key, u32 hash) int tdb_delete(TDB_CONTEXT *tdb, TDB_DATA key) { - u32 hash = tdb_hash(&key); + u32 hash = tdb->hash_fn(&key); return tdb_delete_hash(tdb, key, hash); } @@ -1475,7 +1462,7 @@ int tdb_store(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA dbuf, int flag) int ret = 0; /* find which hash bucket it is in */ - hash = tdb_hash(&key); + hash = tdb->hash_fn(&key); if (!tdb_keylocked(tdb, hash)) return -1; if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) @@ -1593,7 +1580,7 @@ int tdb_append(TDB_CONTEXT *tdb, TDB_DATA key, TDB_DATA new_dbuf) size_t new_data_size = 0; /* find which hash bucket it is in */ - hash = tdb_hash(&key); + hash = tdb->hash_fn(&key); if (!tdb_keylocked(tdb, hash)) return -1; if (tdb_lock(tdb, BUCKET(hash), F_WRLCK) == -1) @@ -1689,6 +1676,24 @@ static int tdb_already_open(dev_t device, return 0; } +/* This is based on the hash algorithm from gdbm */ +static u32 default_tdb_hash(TDB_DATA *key) +{ + u32 value; /* Used to compute the hash value. */ + u32 i; /* Used to cycle through random values. */ + + /* Set the initial value from the key size. */ + for (value = 0x238F13AF * key->dsize, i=0; i < key->dsize; i++) + value = (value + (key->dptr[i] << (i*5 % 24))); + + return (1103515243 * value + 12345); +} + +void tdb_set_hash_function(TDB_CONTEXT *tdb, tdb_hash_func fn) +{ + tdb->hash_fn = fn; +} + /* open the database, creating it if necessary The open_flags and mode are passed straight to the open call on the @@ -1728,7 +1733,8 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->flags = tdb_flags; tdb->open_flags = open_flags; tdb->log_fn = log_fn; - + tdb->hash_fn = default_tdb_hash; + if ((open_flags & O_ACCMODE) == O_WRONLY) { TDB_LOG((tdb, 0, "tdb_open_ex: can't open tdb %s write-only\n", name)); @@ -1973,7 +1979,7 @@ int tdb_lockkeys(TDB_CONTEXT *tdb, u32 number, TDB_DATA keys[]) /* Insertion sort by bucket */ for (i = 0; i < number; i++) { - hash = tdb_hash(&keys[i]); + hash = tdb->hash_fn(&keys[i]); for (j = 0; j < i && BUCKET(tdb->lockedkeys[j+1]) < BUCKET(hash); j++); memmove(&tdb->lockedkeys[j+2], &tdb->lockedkeys[j+1], sizeof(u32) * (i-j)); tdb->lockedkeys[j+1] = hash; @@ -2008,22 +2014,22 @@ void tdb_unlockkeys(TDB_CONTEXT *tdb) contention - it cannot guarantee how many records will be locked */ int tdb_chainlock(TDB_CONTEXT *tdb, TDB_DATA key) { - return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } int tdb_chainunlock(TDB_CONTEXT *tdb, TDB_DATA key) { - return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_WRLCK); + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_WRLCK); } int tdb_chainlock_read(TDB_CONTEXT *tdb, TDB_DATA key) { - return tdb_lock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); + return tdb_lock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } int tdb_chainunlock_read(TDB_CONTEXT *tdb, TDB_DATA key) { - return tdb_unlock(tdb, BUCKET(tdb_hash(&key)), F_RDLCK); + return tdb_unlock(tdb, BUCKET(tdb->hash_fn(&key)), F_RDLCK); } @@ -2033,7 +2039,6 @@ void tdb_logging_function(TDB_CONTEXT *tdb, void (*fn)(TDB_CONTEXT *, int , cons tdb->log_fn = fn; } - /* reopen a tdb - this can be used after a fork to ensure that we have an independent seek pointer from our parent and to re-establish locks */ int tdb_reopen(TDB_CONTEXT *tdb) |