summaryrefslogtreecommitdiff
path: root/source3/tdb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2004-08-24 22:48:49 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 10:52:29 -0500
commitfcbb2d3132df36057da73701f7e23f434034e6b0 (patch)
tree557cf0910ad98186f0851ce19abff8c9900e394f /source3/tdb
parent990d9d15db27f47d2a6cac306ab773d42427ade4 (diff)
downloadsamba-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')
-rw-r--r--source3/tdb/tdb.c57
-rw-r--r--source3/tdb/tdb.h3
2 files changed, 34 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)
diff --git a/source3/tdb/tdb.h b/source3/tdb/tdb.h
index eb120a8cec..8f4421d8fa 100644
--- a/source3/tdb/tdb.h
+++ b/source3/tdb/tdb.h
@@ -102,11 +102,13 @@ typedef struct tdb_context {
dev_t device; /* uniquely identifies this tdb */
ino_t inode; /* uniquely identifies this tdb */
void (*log_fn)(struct tdb_context *tdb, int level, const char *, ...); /* logging function */
+ u32 (*hash_fn)(TDB_DATA *key);
int open_flags; /* flags used in the open - needed by reopen */
} TDB_CONTEXT;
typedef int (*tdb_traverse_func)(TDB_CONTEXT *, TDB_DATA, TDB_DATA, void *);
typedef void (*tdb_log_func)(TDB_CONTEXT *, int , const char *, ...);
+typedef u32 (*tdb_hash_func)(TDB_DATA *key);
TDB_CONTEXT *tdb_open(const char *name, int hash_size, int tdb_flags,
int open_flags, mode_t mode);
@@ -117,6 +119,7 @@ TDB_CONTEXT *tdb_open_ex(const char *name, int hash_size, int tdb_flags,
int tdb_reopen(TDB_CONTEXT *tdb);
int tdb_reopen_all(void);
void tdb_logging_function(TDB_CONTEXT *tdb, tdb_log_func);
+void tdb_set_hash_function(TDB_CONTEXT *tdb, tdb_hash_func);
enum TDB_ERROR tdb_error(TDB_CONTEXT *tdb);
const char *tdb_errorstr(TDB_CONTEXT *tdb);
TDB_DATA tdb_fetch(TDB_CONTEXT *tdb, TDB_DATA key);