summaryrefslogtreecommitdiff
path: root/lib/ntdb/private.h
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ntdb/private.h')
-rw-r--r--lib/ntdb/private.h139
1 files changed, 56 insertions, 83 deletions
diff --git a/lib/ntdb/private.h b/lib/ntdb/private.h
index 488e99a0f9..957d85e494 100644
--- a/lib/ntdb/private.h
+++ b/lib/ntdb/private.h
@@ -48,6 +48,7 @@
#include <utime.h>
#include <unistd.h>
#endif
+#include <assert.h>
#ifndef TEST_IT
#define TEST_IT(cond)
@@ -114,30 +115,17 @@ typedef int ntdb_bool_err;
/* Hash chain locks. */
#define NTDB_HASH_LOCK_START 64
-/* Range for hash locks. */
-#define NTDB_HASH_LOCK_RANGE_BITS 30
-#define NTDB_HASH_LOCK_RANGE (1 << NTDB_HASH_LOCK_RANGE_BITS)
-
-/* We have 1024 entries in the top level. */
-#define NTDB_TOPLEVEL_HASH_BITS 10
-/* And 64 entries in each sub-level: thus 64 bits exactly after 9 levels. */
-#define NTDB_SUBLEVEL_HASH_BITS 6
-/* And 8 entries in each group, ie 8 groups per sublevel. */
-#define NTDB_HASH_GROUP_BITS 3
-/* This is currently 10: beyond this we chain. */
-#define NTDB_MAX_LEVELS (1+(64-NTDB_TOPLEVEL_HASH_BITS) / NTDB_SUBLEVEL_HASH_BITS)
-
/* Extend file by least 100 times larger than needed. */
#define NTDB_EXTENSION_FACTOR 100
-/* We steal bits from the offsets to store hash info. */
-#define NTDB_OFF_HASH_GROUP_MASK ((1ULL << NTDB_HASH_GROUP_BITS) - 1)
/* We steal this many upper bits, giving a maximum offset of 64 exabytes. */
#define NTDB_OFF_UPPER_STEAL 8
-#define NTDB_OFF_UPPER_STEAL_EXTRA 7
-/* The bit number where we store extra hash bits. */
-#define NTDB_OFF_HASH_EXTRA_BIT 57
-#define NTDB_OFF_UPPER_STEAL_SUBHASH_BIT 56
+
+/* And we use the lower bit, too. */
+#define NTDB_OFF_CHAIN_BIT 0
+
+/* Hash table sits just after the header. */
+#define NTDB_HASH_OFFSET (sizeof(struct ntdb_header))
/* Additional features we understand. Currently: none. */
#define NTDB_FEATURE_MASK ((uint64_t)0)
@@ -145,7 +133,7 @@ typedef int ntdb_bool_err;
/* The bit number where we store the extra hash bits. */
/* Convenience mask to get actual offset. */
#define NTDB_OFF_MASK \
- (((1ULL << (64 - NTDB_OFF_UPPER_STEAL)) - 1) - NTDB_OFF_HASH_GROUP_MASK)
+ (((1ULL << (64 - NTDB_OFF_UPPER_STEAL)) - 1) - (1<<NTDB_OFF_CHAIN_BIT))
/* How many buckets in a free list: see size_to_bucket(). */
#define NTDB_FREE_BUCKETS (64 - NTDB_OFF_UPPER_STEAL)
@@ -157,12 +145,14 @@ typedef int ntdb_bool_err;
/* Indicates this entry is not on an flist (can happen during coalescing) */
#define NTDB_FTABLE_NONE ((1ULL << NTDB_OFF_UPPER_STEAL) - 1)
+/* By default, hash is 64k bytes */
+#define NTDB_DEFAULT_HBITS 13
+
struct ntdb_used_record {
/* For on-disk compatibility, we avoid bitfields:
magic: 16, (highest)
key_len_bits: 5,
extra_padding: 32
- hash_bits: 11
*/
uint64_t magic_and_meta;
/* The bottom key_len_bits*2 are key length, rest is data length. */
@@ -189,11 +179,6 @@ static inline uint64_t rec_extra_padding(const struct ntdb_used_record *r)
return (r->magic_and_meta >> 11) & 0xFFFFFFFF;
}
-static inline uint32_t rec_hash(const struct ntdb_used_record *r)
-{
- return r->magic_and_meta & ((1 << 11) - 1);
-}
-
static inline uint16_t rec_magic(const struct ntdb_used_record *r)
{
return (r->magic_and_meta >> 48);
@@ -236,17 +221,12 @@ struct ntdb_recovery_record {
uint64_t eof;
};
-/* If we bottom out of the subhashes, we chain. */
-struct ntdb_chain {
- ntdb_off_t rec[1 << NTDB_HASH_GROUP_BITS];
- ntdb_off_t next;
-};
-
/* this is stored at the front of every database */
struct ntdb_header {
char magic_food[64]; /* for /etc/magic */
/* FIXME: Make me 32 bit? */
uint64_t version; /* version of the code */
+ uint64_t hash_bits; /* bits for toplevel hash table. */
uint64_t hash_test; /* result of hashing HASH_MAGIC. */
uint64_t hash_seed; /* "random" seed written at creation time. */
ntdb_off_t free_table; /* (First) free table. */
@@ -260,8 +240,12 @@ struct ntdb_header {
ntdb_off_t capabilities; /* Optional linked list of capabilities. */
ntdb_off_t reserved[22];
- /* Top level hash table. */
- ntdb_off_t hashtable[1ULL << NTDB_TOPLEVEL_HASH_BITS];
+ /*
+ * Hash table is next:
+ *
+ * struct ntdb_used_record htable_hdr;
+ * ntdb_off_t htable[1 << hash_bits];
+ */
};
struct ntdb_freetable {
@@ -280,33 +264,15 @@ struct ntdb_capability {
/* Information about a particular (locked) hash entry. */
struct hash_info {
/* Full hash value of entry. */
- uint64_t h;
- /* Start and length of lock acquired. */
- ntdb_off_t hlock_start;
- ntdb_len_t hlock_range;
- /* Start of hash group. */
- ntdb_off_t group_start;
- /* Bucket we belong in. */
- unsigned int home_bucket;
+ uint32_t h;
+ /* Start of hash table / chain. */
+ ntdb_off_t table;
+ /* Number of entries in this table/chain. */
+ ntdb_off_t table_size;
/* Bucket we (or an empty space) were found in. */
- unsigned int found_bucket;
- /* How many bits of the hash are already used. */
- unsigned int hash_used;
- /* Current working group. */
- ntdb_off_t group[1 << NTDB_HASH_GROUP_BITS];
-};
-
-struct traverse_info {
- struct traverse_level {
- ntdb_off_t hashtable;
- /* We ignore groups here, and treat it as a big array. */
- unsigned entry;
- unsigned int total_buckets;
- } levels[NTDB_MAX_LEVELS + 1];
- unsigned int num_levels;
- unsigned int toplevel_group;
- /* This makes delete-everything-inside-traverse work as expected. */
- ntdb_off_t prev;
+ ntdb_off_t bucket;
+ /* Old value that was in that entry (if not found) */
+ ntdb_off_t old_val;
};
enum ntdb_lock_flags {
@@ -375,40 +341,46 @@ struct ntdb_methods {
/*
internal prototypes
*/
+/* Get bits from a value. */
+static inline uint32_t bits_from(uint64_t val, unsigned start, unsigned num)
+{
+ assert(num <= 32);
+ return (val >> start) & ((1U << num) - 1);
+}
+
+
/* hash.c: */
-uint64_t ntdb_jenkins_hash(const void *key, size_t length, uint64_t seed,
+uint32_t ntdb_jenkins_hash(const void *key, size_t length, uint32_t seed,
void *unused);
enum NTDB_ERROR first_in_hash(struct ntdb_context *ntdb,
- struct traverse_info *tinfo,
+ struct hash_info *h,
NTDB_DATA *kbuf, size_t *dlen);
enum NTDB_ERROR next_in_hash(struct ntdb_context *ntdb,
- struct traverse_info *tinfo,
+ struct hash_info *h,
NTDB_DATA *kbuf, size_t *dlen);
/* Hash random memory. */
-uint64_t ntdb_hash(struct ntdb_context *ntdb, const void *ptr, size_t len);
-
-/* Hash on disk. */
-uint64_t hash_record(struct ntdb_context *ntdb, ntdb_off_t off);
+uint32_t ntdb_hash(struct ntdb_context *ntdb, const void *ptr, size_t len);
/* Find and lock a hash entry (or where it would be). */
ntdb_off_t find_and_lock(struct ntdb_context *ntdb,
NTDB_DATA key,
int ltype,
struct hash_info *h,
- struct ntdb_used_record *rec,
- struct traverse_info *tinfo);
+ struct ntdb_used_record *rec);
enum NTDB_ERROR replace_in_hash(struct ntdb_context *ntdb,
- struct hash_info *h,
+ const struct hash_info *h,
ntdb_off_t new_off);
-enum NTDB_ERROR add_to_hash(struct ntdb_context *ntdb, struct hash_info *h,
+enum NTDB_ERROR add_to_hash(struct ntdb_context *ntdb,
+ const struct hash_info *h,
ntdb_off_t new_off);
-enum NTDB_ERROR delete_from_hash(struct ntdb_context *ntdb, struct hash_info *h);
+enum NTDB_ERROR delete_from_hash(struct ntdb_context *ntdb,
+ const struct hash_info *h);
/* For ntdb_check */
bool is_subhash(ntdb_off_t val);
@@ -424,7 +396,7 @@ ntdb_off_t next_ftable(struct ntdb_context *ntdb, ntdb_off_t ftable);
/* This returns space or -ve error number. */
ntdb_off_t alloc(struct ntdb_context *ntdb, size_t keylen, size_t datalen,
- uint64_t hash, unsigned magic, bool growing);
+ unsigned magic, bool growing);
/* Put this record in a free list. */
enum NTDB_ERROR add_free_record(struct ntdb_context *ntdb,
@@ -436,7 +408,7 @@ enum NTDB_ERROR add_free_record(struct ntdb_context *ntdb,
enum NTDB_ERROR set_header(struct ntdb_context *ntdb,
struct ntdb_used_record *rec,
unsigned magic, uint64_t keylen, uint64_t datalen,
- uint64_t actuallen, unsigned hashlow);
+ uint64_t actuallen);
/* Used by ntdb_check to verify. */
unsigned int size_to_bucket(ntdb_len_t data_len);
@@ -504,13 +476,12 @@ enum NTDB_ERROR owner_conflict(struct ntdb_context *ntdb, const char *call);
/* If we fork, we no longer really own locks. */
bool check_lock_pid(struct ntdb_context *ntdb, const char *call, bool log);
-/* Lock/unlock a range of hashes. */
-enum NTDB_ERROR ntdb_lock_hashes(struct ntdb_context *ntdb,
- ntdb_off_t hash_lock, ntdb_len_t hash_range,
- int ltype, enum ntdb_lock_flags waitflag);
-enum NTDB_ERROR ntdb_unlock_hashes(struct ntdb_context *ntdb,
- ntdb_off_t hash_lock,
- ntdb_len_t hash_range, int ltype);
+/* Lock/unlock a hash bucket. */
+enum NTDB_ERROR ntdb_lock_hash(struct ntdb_context *ntdb,
+ unsigned int hbucket,
+ int ltype);
+enum NTDB_ERROR ntdb_unlock_hash(struct ntdb_context *ntdb,
+ unsigned int hash, int ltype);
/* For closing the file. */
void ntdb_lock_cleanup(struct ntdb_context *ntdb);
@@ -588,9 +559,11 @@ struct ntdb_context {
struct ntdb_file *file;
/* Hash function. */
- uint64_t (*hash_fn)(const void *key, size_t len, uint64_t seed, void *);
+ uint32_t (*hash_fn)(const void *key, size_t len, uint32_t seed, void *);
void *hash_data;
- uint64_t hash_seed;
+ uint32_t hash_seed;
+ /* Bits in toplevel hash table. */
+ unsigned int hash_bits;
/* Allocate and free functions. */
void *(*alloc_fn)(const void *owner, size_t len, void *priv_data);