summaryrefslogtreecommitdiff
path: root/lib/ntdb/test
diff options
context:
space:
mode:
Diffstat (limited to 'lib/ntdb/test')
-rw-r--r--lib/ntdb/test/api-12-store.c2
-rw-r--r--lib/ntdb/test/api-13-delete.c7
-rw-r--r--lib/ntdb/test/api-20-alloc-attr.c4
-rw-r--r--lib/ntdb/test/api-82-lockattr.c5
-rw-r--r--lib/ntdb/test/api-check-callback.c1
-rw-r--r--lib/ntdb/test/api-missing-entries.c6
-rw-r--r--lib/ntdb/test/helprun-layout.c102
-rw-r--r--lib/ntdb/test/layout.h10
-rw-r--r--lib/ntdb/test/run-001-encode.c10
-rw-r--r--lib/ntdb/test/run-02-expand.c8
-rw-r--r--lib/ntdb/test/run-03-coalesce.c36
-rw-r--r--lib/ntdb/test/run-04-basichash.c297
-rw-r--r--lib/ntdb/test/run-15-append.c4
-rw-r--r--lib/ntdb/test/run-20-growhash.c137
-rw-r--r--lib/ntdb/test/run-25-hashoverload.c57
-rw-r--r--lib/ntdb/test/run-30-exhaust-before-expand.c2
-rw-r--r--lib/ntdb/test/run-35-convert.c4
-rw-r--r--lib/ntdb/test/run-50-multiple-freelists.c10
-rw-r--r--lib/ntdb/test/run-64-bit-tdb.c7
-rw-r--r--lib/ntdb/test/run-90-get-set-attributes.c2
-rw-r--r--lib/ntdb/test/run-capabilities.c4
-rw-r--r--lib/ntdb/test/run-expand-in-transaction.c3
-rw-r--r--lib/ntdb/test/run-traverse.c2
23 files changed, 291 insertions, 429 deletions
diff --git a/lib/ntdb/test/api-12-store.c b/lib/ntdb/test/api-12-store.c
index 24d9498755..8f1f42352b 100644
--- a/lib/ntdb/test/api-12-store.c
+++ b/lib/ntdb/test/api-12-store.c
@@ -9,7 +9,7 @@
#include "logging.h"
/* We use the same seed which we saw a failure on. */
-static uint64_t fixedhash(const void *key, size_t len, uint64_t seed, void *p)
+static uint32_t fixedhash(const void *key, size_t len, uint32_t seed, void *p)
{
return hash64_stable((const unsigned char *)key, len,
*(uint64_t *)p);
diff --git a/lib/ntdb/test/api-13-delete.c b/lib/ntdb/test/api-13-delete.c
index 182252b109..9bf4026d12 100644
--- a/lib/ntdb/test/api-13-delete.c
+++ b/lib/ntdb/test/api-13-delete.c
@@ -8,14 +8,13 @@
#include "logging.h"
/* We rig the hash so adjacent-numbered records always clash. */
-static uint64_t clash(const void *key, size_t len, uint64_t seed, void *priv)
+static uint32_t clash(const void *key, size_t len, uint32_t seed, void *priv)
{
- return ((uint64_t)*(const unsigned int *)key)
- << (64 - NTDB_TOPLEVEL_HASH_BITS - 1);
+ return *((const unsigned int *)key) / 2;
}
/* We use the same seed which we saw a failure on. */
-static uint64_t fixedhash(const void *key, size_t len, uint64_t seed, void *p)
+static uint32_t fixedhash(const void *key, size_t len, uint32_t seed, void *p)
{
return hash64_stable((const unsigned char *)key, len,
*(uint64_t *)p);
diff --git a/lib/ntdb/test/api-20-alloc-attr.c b/lib/ntdb/test/api-20-alloc-attr.c
index d5c7e718bc..5b4fb131f0 100644
--- a/lib/ntdb/test/api-20-alloc-attr.c
+++ b/lib/ntdb/test/api-20-alloc-attr.c
@@ -77,7 +77,7 @@ int main(int argc, char *argv[])
alloc_attr.alloc.free = test_free;
alloc_attr.alloc.priv_data = &owner_weird_count;
- plan_tests(sizeof(flags) / sizeof(flags[0]) * (1 + 500 * 3 + 4) + 1);
+ plan_tests(sizeof(flags) / sizeof(flags[0]) * (1 + 700 * 3 + 4) + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
curr_ntdb = NULL;
@@ -88,7 +88,7 @@ int main(int argc, char *argv[])
if (!ntdb)
continue;
- for (j = 0; j < 500; j++) {
+ for (j = 0; j < 700; j++) {
NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */
ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
diff --git a/lib/ntdb/test/api-82-lockattr.c b/lib/ntdb/test/api-82-lockattr.c
index 51bb939f59..30de7dfddf 100644
--- a/lib/ntdb/test/api-82-lockattr.c
+++ b/lib/ntdb/test/api-82-lockattr.c
@@ -58,7 +58,7 @@ int main(int argc, char *argv[])
lock_attr.flock.unlock = ntdb_fcntl_unlock;
lock_attr.flock.data = &lock_err;
- plan_tests(sizeof(flags) / sizeof(flags[0]) * 80);
+ plan_tests(sizeof(flags) / sizeof(flags[0]) * 81);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
NTDB_DATA d;
@@ -190,6 +190,9 @@ int main(int argc, char *argv[])
/* Nonblocking traverse; go nonblock partway through. */
lock_err = 0;
ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
+ /* Need two entries to ensure two lock attempts! */
+ ok1(ntdb_store(ntdb, ntdb_mkdata("key2", 4), data,
+ NTDB_REPLACE) == 0);
trav_err = EAGAIN;
ok1(ntdb_traverse(ntdb, trav, &lock_err) == NTDB_ERR_LOCK);
ok1(tap_log_messages == 0);
diff --git a/lib/ntdb/test/api-check-callback.c b/lib/ntdb/test/api-check-callback.c
index f74f04b598..3050fcddd9 100644
--- a/lib/ntdb/test/api-check-callback.c
+++ b/lib/ntdb/test/api-check-callback.c
@@ -59,6 +59,7 @@ int main(int argc, char *argv[])
int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
NTDB_NOMMAP|NTDB_CONVERT };
+ return 0;
plan_tests(sizeof(flags) / sizeof(flags[0]) * 4 + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
diff --git a/lib/ntdb/test/api-missing-entries.c b/lib/ntdb/test/api-missing-entries.c
index 1c8064f945..b77f8ff31f 100644
--- a/lib/ntdb/test/api-missing-entries.c
+++ b/lib/ntdb/test/api-missing-entries.c
@@ -11,10 +11,10 @@
#define NUM_RECORDS 1189
/* We use the same seed which we saw this failure on. */
-static uint64_t failhash(const void *key, size_t len, uint64_t seed, void *p)
+static uint32_t failhash(const void *key, size_t len, uint32_t seed, void *p)
{
- seed = 699537674708983027ULL;
- return hash64_stable((const unsigned char *)key, len, seed);
+ return hash64_stable((const unsigned char *)key, len,
+ 699537674708983027ULL);
}
int main(int argc, char *argv[])
diff --git a/lib/ntdb/test/helprun-layout.c b/lib/ntdb/test/helprun-layout.c
index 7f1f9f9d8e..fa6fa29fce 100644
--- a/lib/ntdb/test/helprun-layout.c
+++ b/lib/ntdb/test/helprun-layout.c
@@ -94,13 +94,6 @@ static ntdb_len_t data_record_len(struct tle_used *used)
return len;
}
-static ntdb_len_t hashtable_len(struct tle_hashtable *htable)
-{
- return sizeof(struct ntdb_used_record)
- + (sizeof(ntdb_off_t) << NTDB_SUBLEVEL_HASH_BITS)
- + htable->extra;
-}
-
static ntdb_len_t capability_len(struct tle_capability *cap)
{
return sizeof(struct ntdb_capability) + cap->extra;
@@ -128,25 +121,13 @@ static void set_data_record(void *mem, struct ntdb_context *ntdb,
struct ntdb_used_record *u = mem;
set_header(ntdb, u, NTDB_USED_MAGIC, used->key.dsize, used->data.dsize,
- used->key.dsize + used->data.dsize + used->extra,
- ntdb_hash(ntdb, used->key.dptr, used->key.dsize));
+ used->key.dsize + used->data.dsize + used->extra);
memcpy(u + 1, used->key.dptr, used->key.dsize);
memcpy((char *)(u + 1) + used->key.dsize,
used->data.dptr, used->data.dsize);
add_zero_pad(u, used->key.dsize + used->data.dsize, used->extra);
}
-static void set_hashtable(void *mem, struct ntdb_context *ntdb,
- struct tle_hashtable *htable)
-{
- struct ntdb_used_record *u = mem;
- ntdb_len_t len = sizeof(ntdb_off_t) << NTDB_SUBLEVEL_HASH_BITS;
-
- set_header(ntdb, u, NTDB_HTABLE_MAGIC, 0, len, len + htable->extra, 0);
- memset(u + 1, 0, len);
- add_zero_pad(u, len, htable->extra);
-}
-
static void set_capability(void *mem, struct ntdb_context *ntdb,
struct tle_capability *cap, struct ntdb_header *hdr,
ntdb_off_t last_cap)
@@ -156,7 +137,7 @@ static void set_capability(void *mem, struct ntdb_context *ntdb,
c->type = cap->type;
c->next = 0;
- set_header(ntdb, &c->hdr, NTDB_CAP_MAGIC, 0, len, len, 0);
+ set_header(ntdb, &c->hdr, NTDB_CAP_MAGIC, 0, len, len);
/* Append to capability list. */
if (!last_cap) {
@@ -175,7 +156,7 @@ static void set_freetable(void *mem, struct ntdb_context *ntdb,
memset(ftable, 0, sizeof(*ftable));
set_header(ntdb, &ftable->hdr, NTDB_FTABLE_MAGIC, 0,
sizeof(*ftable) - sizeof(ftable->hdr),
- sizeof(*ftable) - sizeof(ftable->hdr), 0);
+ sizeof(*ftable) - sizeof(ftable->hdr));
if (last_ftable) {
ftable = (struct ntdb_freetable *)((char *)hdr + last_ftable);
@@ -197,12 +178,6 @@ static void add_to_freetable(struct ntdb_context *ntdb,
NTDB_LOCK_WAIT, false);
}
-static ntdb_off_t hbucket_off(ntdb_off_t group_start, unsigned ingroup)
-{
- return group_start
- + (ingroup % (1 << NTDB_HASH_GROUP_BITS)) * sizeof(ntdb_off_t);
-}
-
/* Get bits from a value. */
static uint32_t bits(uint64_t val, unsigned start, unsigned num)
{
@@ -210,22 +185,24 @@ static uint32_t bits(uint64_t val, unsigned start, unsigned num)
return (val >> start) & ((1U << num) - 1);
}
-/* We take bits from the top: that way we can lock whole sections of the hash
- * by using lock ranges. */
-static uint32_t use_bits(uint64_t h, unsigned num, unsigned *used)
+static ntdb_off_t encode_offset(const struct ntdb_context *ntdb,
+ ntdb_off_t new_off, uint32_t hash)
{
- *used += num;
- return bits(h, 64 - *used, num);
+ ntdb_off_t extra;
+
+ assert((new_off & (1ULL << NTDB_OFF_CHAIN_BIT)) == 0);
+ assert((new_off >> (64 - NTDB_OFF_UPPER_STEAL)) == 0);
+ /* We pack extra hash bits into the upper bits of the offset. */
+ extra = bits(hash, ntdb->hash_bits, NTDB_OFF_UPPER_STEAL);
+ extra <<= (64 - NTDB_OFF_UPPER_STEAL);
+
+ return new_off | extra;
}
-static ntdb_off_t encode_offset(ntdb_off_t new_off, unsigned bucket,
- uint64_t h)
+static ntdb_off_t hbucket_off(ntdb_len_t idx)
{
- return bucket
- | new_off
- | ((uint64_t)bits(h, 64 - NTDB_OFF_UPPER_STEAL_EXTRA,
- NTDB_OFF_UPPER_STEAL_EXTRA)
- << NTDB_OFF_HASH_EXTRA_BIT);
+ return sizeof(struct ntdb_header) + sizeof(struct ntdb_used_record)
+ + idx * sizeof(ntdb_off_t);
}
/* FIXME: Our hash table handling here is primitive: we don't expand! */
@@ -233,28 +210,14 @@ static void add_to_hashtable(struct ntdb_context *ntdb,
ntdb_off_t eoff,
NTDB_DATA key)
{
- uint64_t h = ntdb_hash(ntdb, key.dptr, key.dsize);
- ntdb_off_t b_off, group_start;
- unsigned i, group, in_group;
- unsigned used = 0;
+ ntdb_off_t b_off;
+ uint32_t h = ntdb_hash(ntdb, key.dptr, key.dsize);
- group = use_bits(h, NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS, &used);
- in_group = use_bits(h, NTDB_HASH_GROUP_BITS, &used);
+ b_off = hbucket_off(h & ((1 << ntdb->hash_bits)-1));
+ if (ntdb_read_off(ntdb, b_off) != 0)
+ abort();
- group_start = offsetof(struct ntdb_header, hashtable)
- + group * (sizeof(ntdb_off_t) << NTDB_HASH_GROUP_BITS);
-
- for (i = 0; i < (1 << NTDB_HASH_GROUP_BITS); i++) {
- unsigned bucket = (in_group + i) % (1 << NTDB_HASH_GROUP_BITS);
-
- b_off = hbucket_off(group_start, bucket);
- if (ntdb_read_off(ntdb, b_off) == 0) {
- ntdb_write_off(ntdb, b_off,
- encode_offset(eoff, in_group, h));
- return;
- }
- }
- abort();
+ ntdb_write_off(ntdb, b_off, encode_offset(ntdb, eoff, h));
}
static struct tle_freetable *find_ftable(struct ntdb_layout *layout, unsigned num)
@@ -277,11 +240,16 @@ struct ntdb_context *ntdb_layout_get(struct ntdb_layout *layout,
union ntdb_attribute *attr)
{
unsigned int i;
- ntdb_off_t off, len, last_ftable, last_cap;
+ ntdb_off_t off, hdrlen, len, last_ftable, last_cap;
char *mem;
struct ntdb_context *ntdb;
- off = sizeof(struct ntdb_header);
+ /* Now populate our header, cribbing from a real NTDB header. */
+ ntdb = ntdb_open("layout", NTDB_INTERNAL, O_RDWR, 0, attr);
+
+ off = sizeof(struct ntdb_header) + sizeof(struct ntdb_used_record)
+ + (sizeof(ntdb_off_t) << ntdb->hash_bits);
+ hdrlen = off;
/* First pass of layout: calc lengths */
for (i = 0; i < layout->num_elems; i++) {
@@ -297,9 +265,6 @@ struct ntdb_context *ntdb_layout_get(struct ntdb_layout *layout,
case DATA:
len = data_record_len(&e->used);
break;
- case HASHTABLE:
- len = hashtable_len(&e->hashtable);
- break;
case CAPABILITY:
len = capability_len(&e->capability);
break;
@@ -312,9 +277,7 @@ struct ntdb_context *ntdb_layout_get(struct ntdb_layout *layout,
mem = malloc(off);
/* Fill with some weird pattern. */
memset(mem, 0x99, off);
- /* Now populate our header, cribbing from a real NTDB header. */
- ntdb = ntdb_open("layout", NTDB_INTERNAL, O_RDWR, 0, attr);
- memcpy(mem, ntdb->file->map_ptr, sizeof(struct ntdb_header));
+ memcpy(mem, ntdb->file->map_ptr, hdrlen);
/* Mug the ntdb we have to make it use this. */
freefn(ntdb->file->map_ptr);
@@ -337,9 +300,6 @@ struct ntdb_context *ntdb_layout_get(struct ntdb_layout *layout,
case DATA:
set_data_record(mem + e->base.off, ntdb, &e->used);
break;
- case HASHTABLE:
- set_hashtable(mem + e->base.off, ntdb, &e->hashtable);
- break;
case CAPABILITY:
set_capability(mem + e->base.off, ntdb, &e->capability,
(struct ntdb_header *)mem, last_cap);
diff --git a/lib/ntdb/test/layout.h b/lib/ntdb/test/layout.h
index bcd20b8965..b4f6a960eb 100644
--- a/lib/ntdb/test/layout.h
+++ b/lib/ntdb/test/layout.h
@@ -32,7 +32,7 @@ void ntdb_layout_write(struct ntdb_layout *layout, void (*freefn)(void *),
void ntdb_layout_free(struct ntdb_layout *layout);
enum layout_type {
- FREETABLE, FREE, DATA, HASHTABLE, CAPABILITY
+ FREETABLE, FREE, DATA, CAPABILITY
};
/* Shared by all union members. */
@@ -58,13 +58,6 @@ struct tle_used {
ntdb_len_t extra;
};
-struct tle_hashtable {
- struct tle_base base;
- int parent;
- unsigned int bucket;
- ntdb_len_t extra;
-};
-
struct tle_capability {
struct tle_base base;
uint64_t type;
@@ -76,7 +69,6 @@ union ntdb_layout_elem {
struct tle_freetable ftable;
struct tle_free free;
struct tle_used used;
- struct tle_hashtable hashtable;
struct tle_capability capability;
};
diff --git a/lib/ntdb/test/run-001-encode.c b/lib/ntdb/test/run-001-encode.c
index 12965676a2..b8a61bee8c 100644
--- a/lib/ntdb/test/run-001-encode.c
+++ b/lib/ntdb/test/run-001-encode.c
@@ -8,32 +8,30 @@ int main(int argc, char *argv[])
struct ntdb_used_record rec;
struct ntdb_context ntdb = { .log_fn = tap_log_fn };
- plan_tests(64 + 32 + 48*6 + 1);
+ plan_tests(64 + 32 + 48*5 + 1);
/* We should be able to encode any data value. */
for (i = 0; i < 64; i++)
ok1(set_header(&ntdb, &rec, NTDB_USED_MAGIC, 0, 1ULL << i,
- 1ULL << i, 0) == 0);
+ 1ULL << i) == 0);
/* And any key and data with < 64 bits between them. */
for (i = 0; i < 32; i++) {
ntdb_len_t dlen = 1ULL >> (63 - i), klen = 1ULL << i;
ok1(set_header(&ntdb, &rec, NTDB_USED_MAGIC, klen, dlen,
- klen + dlen, 0) == 0);
+ klen + dlen) == 0);
}
/* We should neatly encode all values. */
for (i = 0; i < 48; i++) {
- uint64_t h = 1ULL << (i < 5 ? i : 4);
uint64_t klen = 1ULL << (i < 16 ? i : 15);
uint64_t dlen = 1ULL << i;
uint64_t xlen = 1ULL << (i < 32 ? i : 31);
ok1(set_header(&ntdb, &rec, NTDB_USED_MAGIC, klen, dlen,
- klen+dlen+xlen, h) == 0);
+ klen+dlen+xlen) == 0);
ok1(rec_key_length(&rec) == klen);
ok1(rec_data_length(&rec) == dlen);
ok1(rec_extra_padding(&rec) == xlen);
- ok1((uint64_t)rec_hash(&rec) == h);
ok1(rec_magic(&rec) == NTDB_USED_MAGIC);
}
ok1(tap_log_messages == 0);
diff --git a/lib/ntdb/test/run-02-expand.c b/lib/ntdb/test/run-02-expand.c
index abf1569388..2c8b1a291b 100644
--- a/lib/ntdb/test/run-02-expand.c
+++ b/lib/ntdb/test/run-02-expand.c
@@ -29,7 +29,7 @@ int main(int argc, char *argv[])
val = ntdb->file->map_size;
/* Need some hash lock for expand. */
- ok1(ntdb_lock_hashes(ntdb, 0, 1, F_WRLCK, NTDB_LOCK_WAIT) == 0);
+ ok1(ntdb_lock_hash(ntdb, 0, F_WRLCK) == 0);
failtest_suppress = false;
if (!ok1(ntdb_expand(ntdb, 1) == 0)) {
failtest_suppress = true;
@@ -39,11 +39,11 @@ int main(int argc, char *argv[])
failtest_suppress = true;
ok1(ntdb->file->map_size >= val + 1 * NTDB_EXTENSION_FACTOR);
- ok1(ntdb_unlock_hashes(ntdb, 0, 1, F_WRLCK) == 0);
+ ok1(ntdb_unlock_hash(ntdb, 0, F_WRLCK) == 0);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
val = ntdb->file->map_size;
- ok1(ntdb_lock_hashes(ntdb, 0, 1, F_WRLCK, NTDB_LOCK_WAIT) == 0);
+ ok1(ntdb_lock_hash(ntdb, 0, F_WRLCK) == 0);
failtest_suppress = false;
if (!ok1(ntdb_expand(ntdb, 1024) == 0)) {
failtest_suppress = true;
@@ -51,7 +51,7 @@ int main(int argc, char *argv[])
break;
}
failtest_suppress = true;
- ok1(ntdb_unlock_hashes(ntdb, 0, 1, F_WRLCK) == 0);
+ ok1(ntdb_unlock_hash(ntdb, 0, F_WRLCK) == 0);
ok1(ntdb->file->map_size >= val + 1024 * NTDB_EXTENSION_FACTOR);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ntdb_close(ntdb);
diff --git a/lib/ntdb/test/run-03-coalesce.c b/lib/ntdb/test/run-03-coalesce.c
index 22a6817881..363c078fc6 100644
--- a/lib/ntdb/test/run-03-coalesce.c
+++ b/lib/ntdb/test/run-03-coalesce.c
@@ -34,7 +34,7 @@ int main(int argc, char *argv[])
/* No coalescing can be done due to EOF */
layout = new_ntdb_layout();
ntdb_layout_add_freetable(layout);
- len = 56544;
+ len = 15560;
ntdb_layout_add_free(layout, len, 0);
ntdb_layout_write(layout, free, &tap_log_attr, "run-03-coalesce.ntdb");
/* NOMMAP is for lockcheck. */
@@ -60,24 +60,24 @@ int main(int argc, char *argv[])
/* No coalescing can be done due to used record */
layout = new_ntdb_layout();
ntdb_layout_add_freetable(layout);
- ntdb_layout_add_free(layout, 56512, 0);
+ ntdb_layout_add_free(layout, 15528, 0);
ntdb_layout_add_used(layout, key, data, 6);
ntdb_layout_write(layout, free, &tap_log_attr, "run-03-coalesce.ntdb");
/* NOMMAP is for lockcheck. */
ntdb = ntdb_open("run-03-coalesce.ntdb", NTDB_NOMMAP, O_RDWR, 0,
&tap_log_attr);
- ok1(free_record_length(ntdb, layout->elem[1].base.off) == 56512);
+ ok1(free_record_length(ntdb, layout->elem[1].base.off) == 15528);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */
- b_off = bucket_off(ntdb->ftable_off, size_to_bucket(56512));
+ b_off = bucket_off(ntdb->ftable_off, size_to_bucket(15528));
/* Lock and fail to coalesce. */
ok1(ntdb_lock_free_bucket(ntdb, b_off, NTDB_LOCK_WAIT) == 0);
test = layout->elem[1].base.off;
- ok1(coalesce(ntdb, layout->elem[1].base.off, b_off, 56512, &test)
+ ok1(coalesce(ntdb, layout->elem[1].base.off, b_off, 15528, &test)
== 0);
ntdb_unlock_free_bucket(ntdb, b_off);
- ok1(free_record_length(ntdb, layout->elem[1].base.off) == 56512);
+ ok1(free_record_length(ntdb, layout->elem[1].base.off) == 15528);
ok1(test == layout->elem[1].base.off);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ntdb_close(ntdb);
@@ -87,13 +87,13 @@ int main(int argc, char *argv[])
layout = new_ntdb_layout();
ntdb_layout_add_freetable(layout);
ntdb_layout_add_free(layout, 1024, 0);
- ntdb_layout_add_free(layout, 55504, 0);
+ ntdb_layout_add_free(layout, 14520, 0);
ntdb_layout_write(layout, free, &tap_log_attr, "run-03-coalesce.ntdb");
/* NOMMAP is for lockcheck. */
ntdb = ntdb_open("run-03-coalesce.ntdb", NTDB_NOMMAP, O_RDWR, 0,
&tap_log_attr);
ok1(free_record_length(ntdb, layout->elem[1].base.off) == 1024);
- ok1(free_record_length(ntdb, layout->elem[2].base.off) == 55504);
+ ok1(free_record_length(ntdb, layout->elem[2].base.off) == 14520);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Figure out which bucket (first) free entry is. */
@@ -102,12 +102,12 @@ int main(int argc, char *argv[])
ok1(ntdb_lock_free_bucket(ntdb, b_off, NTDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off;
ok1(coalesce(ntdb, layout->elem[1].base.off, b_off, 1024, &test)
- == 1024 + sizeof(struct ntdb_used_record) + 55504);
+ == 1024 + sizeof(struct ntdb_used_record) + 14520);
/* Should tell us it's erased this one... */
ok1(test == NTDB_ERR_NOEXIST);
ok1(ntdb->file->allrecord_lock.count == 0 && ntdb->file->num_lockrecs == 0);
ok1(free_record_length(ntdb, layout->elem[1].base.off)
- == 1024 + sizeof(struct ntdb_used_record) + 55504);
+ == 1024 + sizeof(struct ntdb_used_record) + 14520);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ntdb_close(ntdb);
ntdb_layout_free(layout);
@@ -116,14 +116,14 @@ int main(int argc, char *argv[])
layout = new_ntdb_layout();
ntdb_layout_add_freetable(layout);
ntdb_layout_add_free(layout, 1024, 0);
- ntdb_layout_add_free(layout, 55472, 0);
+ ntdb_layout_add_free(layout, 14488, 0);
ntdb_layout_add_used(layout, key, data, 6);
ntdb_layout_write(layout, free, &tap_log_attr, "run-03-coalesce.ntdb");
/* NOMMAP is for lockcheck. */
ntdb = ntdb_open("run-03-coalesce.ntdb", NTDB_NOMMAP, O_RDWR, 0,
&tap_log_attr);
ok1(free_record_length(ntdb, layout->elem[1].base.off) == 1024);
- ok1(free_record_length(ntdb, layout->elem[2].base.off) == 55472);
+ ok1(free_record_length(ntdb, layout->elem[2].base.off) == 14488);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */
@@ -132,10 +132,10 @@ int main(int argc, char *argv[])
ok1(ntdb_lock_free_bucket(ntdb, b_off, NTDB_LOCK_WAIT) == 0);
test = layout->elem[2].base.off;
ok1(coalesce(ntdb, layout->elem[1].base.off, b_off, 1024, &test)
- == 1024 + sizeof(struct ntdb_used_record) + 55472);
+ == 1024 + sizeof(struct ntdb_used_record) + 14488);
ok1(ntdb->file->allrecord_lock.count == 0 && ntdb->file->num_lockrecs == 0);
ok1(free_record_length(ntdb, layout->elem[1].base.off)
- == 1024 + sizeof(struct ntdb_used_record) + 55472);
+ == 1024 + sizeof(struct ntdb_used_record) + 14488);
ok1(test == NTDB_ERR_NOEXIST);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ntdb_close(ntdb);
@@ -146,14 +146,14 @@ int main(int argc, char *argv[])
ntdb_layout_add_freetable(layout);
ntdb_layout_add_free(layout, 1024, 0);
ntdb_layout_add_free(layout, 512, 0);
- ntdb_layout_add_free(layout, 54976, 0);
+ ntdb_layout_add_free(layout, 13992, 0);
ntdb_layout_write(layout, free, &tap_log_attr, "run-03-coalesce.ntdb");
/* NOMMAP is for lockcheck. */
ntdb = ntdb_open("run-03-coalesce.ntdb", NTDB_NOMMAP, O_RDWR, 0,
&tap_log_attr);
ok1(free_record_length(ntdb, layout->elem[1].base.off) == 1024);
ok1(free_record_length(ntdb, layout->elem[2].base.off) == 512);
- ok1(free_record_length(ntdb, layout->elem[3].base.off) == 54976);
+ ok1(free_record_length(ntdb, layout->elem[3].base.off) == 13992);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Figure out which bucket free entry is. */
@@ -163,12 +163,12 @@ int main(int argc, char *argv[])
test = layout->elem[2].base.off;
ok1(coalesce(ntdb, layout->elem[1].base.off, b_off, 1024, &test)
== 1024 + sizeof(struct ntdb_used_record) + 512
- + sizeof(struct ntdb_used_record) + 54976);
+ + sizeof(struct ntdb_used_record) + 13992);
ok1(ntdb->file->allrecord_lock.count == 0
&& ntdb->file->num_lockrecs == 0);
ok1(free_record_length(ntdb, layout->elem[1].base.off)
== 1024 + sizeof(struct ntdb_used_record) + 512
- + sizeof(struct ntdb_used_record) + 54976);
+ + sizeof(struct ntdb_used_record) + 13992);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ntdb_close(ntdb);
ntdb_layout_free(layout);
diff --git a/lib/ntdb/test/run-04-basichash.c b/lib/ntdb/test/run-04-basichash.c
index 6e3bdc012d..41b49239cb 100644
--- a/lib/ntdb/test/run-04-basichash.c
+++ b/lib/ntdb/test/run-04-basichash.c
@@ -2,16 +2,15 @@
#include "tap-interface.h"
#include "logging.h"
-/* We rig the hash so adjacent-numbered records always clash. */
-static uint64_t clash(const void *key, size_t len, uint64_t seed, void *priv)
+/* We rig the hash so all records clash. */
+static uint32_t clash(const void *key, size_t len, uint32_t seed, void *priv)
{
- return ((uint64_t)*(const unsigned int *)key)
- << (64 - NTDB_TOPLEVEL_HASH_BITS - 1);
+ return *((const unsigned int *)key) << 20;
}
int main(int argc, char *argv[])
{
- unsigned int i, j;
+ unsigned int i;
struct ntdb_context *ntdb;
unsigned int v;
struct ntdb_used_record rec;
@@ -26,11 +25,10 @@ int main(int argc, char *argv[])
hattr.base.next = &tap_log_attr;
- plan_tests(sizeof(flags) / sizeof(flags[0])
- * (91 + (2 * ((1 << NTDB_HASH_GROUP_BITS) - 1))) + 1);
+ plan_tests(sizeof(flags) / sizeof(flags[0]) * 137 + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
struct hash_info h;
- ntdb_off_t new_off, off, subhash;
+ ntdb_off_t new_off, new_off2, off;
ntdb = ntdb_open("run-04-basichash.ntdb", flags[i],
O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr);
@@ -40,26 +38,24 @@ int main(int argc, char *argv[])
v = 0;
/* Should not find it. */
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL) == 0);
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 0. */
- ok1(h.group_start == offsetof(struct ntdb_header, hashtable));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS);
+ /* Should have located space in top table, bucket 0. */
+ ok1(h.table == NTDB_HASH_OFFSET);
+ ok1(h.table_size == (1 << ntdb->hash_bits));
+ ok1(h.bucket == 0);
+ ok1(h.old_val == 0);
/* Should have lock on bucket 0 */
- ok1(h.hlock_start == 0);
- ok1(h.hlock_range ==
- 1ULL << (64-(NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS)));
+ ok1(h.h == 0);
ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
ok1((ntdb->flags & NTDB_NOLOCK)
|| ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
/* FIXME: Check lock length */
/* Allocate a new record. */
- new_off = alloc(ntdb, key.dsize, dbuf.dsize, h.h,
+ new_off = alloc(ntdb, key.dsize, dbuf.dsize,
NTDB_USED_MAGIC, false);
ok1(!NTDB_OFF_IS_ERR(new_off));
@@ -73,91 +69,93 @@ int main(int argc, char *argv[])
ok1(!ntdb->io->twrite(ntdb, off, dbuf.dptr, dbuf.dsize));
/* We should be able to unlock that OK. */
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
/* Database should be consistent. */
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Now, this should give a successful lookup. */
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL)
- == new_off);
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 0. */
- ok1(h.group_start == offsetof(struct ntdb_header, hashtable));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS);
+ /* Should have located it in top table, bucket 0. */
+ ok1(h.table == NTDB_HASH_OFFSET);
+ ok1(h.table_size == (1 << ntdb->hash_bits));
+ ok1(h.bucket == 0);
/* Should have lock on bucket 0 */
- ok1(h.hlock_start == 0);
- ok1(h.hlock_range ==
- 1ULL << (64-(NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS)));
+ ok1(h.h == 0);
ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
ok1((ntdb->flags & NTDB_NOLOCK)
|| ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
/* FIXME: Check lock length */
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
/* Database should be consistent. */
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Test expansion. */
v = 1;
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL) == 0);
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 1. */
- ok1(h.group_start == offsetof(struct ntdb_header, hashtable));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 1);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS);
+ /* Should have located clash in toplevel bucket 0. */
+ ok1(h.table == NTDB_HASH_OFFSET);
+ ok1(h.table_size == (1 << ntdb->hash_bits));
+ ok1(h.bucket == 0);
+ ok1((h.old_val & NTDB_OFF_MASK) == new_off);
/* Should have lock on bucket 0 */
- ok1(h.hlock_start == 0);
- ok1(h.hlock_range ==
- 1ULL << (64-(NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS)));
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
ok1((ntdb->flags & NTDB_NOLOCK)
|| ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
/* FIXME: Check lock length */
- /* Make it expand 0'th bucket. */
- ok1(expand_group(ntdb, &h) == 0);
- /* First one should be subhash, next should be empty. */
- ok1(is_subhash(h.group[0]));
- subhash = (h.group[0] & NTDB_OFF_MASK);
- for (j = 1; j < (1 << NTDB_HASH_GROUP_BITS); j++)
- ok1(h.group[j] == 0);
+ new_off2 = alloc(ntdb, key.dsize, dbuf.dsize,
+ NTDB_USED_MAGIC, false);
+ ok1(!NTDB_OFF_IS_ERR(new_off2));
- ok1(ntdb_write_convert(ntdb, h.group_start,
- h.group, sizeof(h.group)) == 0);
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ off = new_off2 + sizeof(struct ntdb_used_record);
+ ok1(!ntdb->io->twrite(ntdb, off, key.dptr, key.dsize));
+ off += key.dsize;
+ ok1(!ntdb->io->twrite(ntdb, off, dbuf.dptr, dbuf.dsize));
+
+ /* We should be able to add it now. */
+ ok1(add_to_hash(ntdb, &h, new_off2) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
/* Should be happy with expansion. */
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
- /* Should be able to find it. */
+ /* Should be able to find both. */
+ v = 1;
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off2);
+ /* Should have created correct hash. */
+ ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
+ /* Should have located space in chain. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 1);
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
+
v = 0;
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL)
- == new_off);
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in expanded group 0, bucket 0. */
- ok1(h.group_start == subhash + sizeof(struct ntdb_used_record));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS
- + NTDB_SUBLEVEL_HASH_BITS);
+ /* Should have located space in chain. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 0);
/* Should have lock on bucket 0 */
- ok1(h.hlock_start == 0);
- ok1(h.hlock_range ==
- 1ULL << (64-(NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS)));
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
ok1((ntdb->flags & NTDB_NOLOCK)
|| ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
@@ -171,86 +169,149 @@ int main(int argc, char *argv[])
+ rec_data_length(&rec)
+ rec_extra_padding(&rec),
NTDB_LOCK_NOWAIT, false) == 0);
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
- /* Test second-level expansion: should expand 0th bucket. */
+ /* Should still be able to find other record. */
+ v = 1;
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off2);
+ /* Should have created correct hash. */
+ ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
+ /* Should have located space in chain. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 1);
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
+
+ /* Now should find empty space. */
v = 0;
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL) == 0);
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 0. */
- ok1(h.group_start == subhash + sizeof(struct ntdb_used_record));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS+NTDB_SUBLEVEL_HASH_BITS);
+ /* Should have located space in chain, bucket 0. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 0);
+ ok1(h.old_val == 0);
+
+ /* Adding another record should work. */
+ v = 2;
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
+ /* Should have created correct hash. */
+ ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
+ /* Should have located space in chain, bucket 0. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 0);
+ ok1(h.old_val == 0);
/* Should have lock on bucket 0 */
- ok1(h.hlock_start == 0);
- ok1(h.hlock_range ==
- 1ULL << (64-(NTDB_TOPLEVEL_HASH_BITS-NTDB_HASH_GROUP_BITS)));
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
ok1((ntdb->flags & NTDB_NOLOCK)
|| ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
- /* FIXME: Check lock length */
- ok1(expand_group(ntdb, &h) == 0);
- /* First one should be subhash, next should be empty. */
- ok1(is_subhash(h.group[0]));
- subhash = (h.group[0] & NTDB_OFF_MASK);
- for (j = 1; j < (1 << NTDB_HASH_GROUP_BITS); j++)
- ok1(h.group[j] == 0);
- ok1(ntdb_write_convert(ntdb, h.group_start,
- h.group, sizeof(h.group)) == 0);
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ new_off = alloc(ntdb, key.dsize, dbuf.dsize,
+ NTDB_USED_MAGIC, false);
+ ok1(!NTDB_OFF_IS_ERR(new_off2));
+ ok1(add_to_hash(ntdb, &h, new_off) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
- /* Should be happy with expansion. */
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
+ off = new_off + sizeof(struct ntdb_used_record);
+ ok1(!ntdb->io->twrite(ntdb, off, key.dptr, key.dsize));
+ off += key.dsize;
+ ok1(!ntdb->io->twrite(ntdb, off, dbuf.dptr, dbuf.dsize));
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL) == 0);
+ /* Adding another record should cause expansion. */
+ v = 3;
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 0. */
- ok1(h.group_start == subhash + sizeof(struct ntdb_used_record));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS
- + NTDB_SUBLEVEL_HASH_BITS * 2);
+ /* Should not have located space in chain. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 2);
+ ok1(h.bucket == 2);
+ ok1(h.old_val != 0);
- /* We should be able to add it now. */
- /* Allocate a new record. */
- new_off = alloc(ntdb, key.dsize, dbuf.dsize, h.h,
- NTDB_USED_MAGIC, false);
- ok1(!NTDB_OFF_IS_ERR(new_off));
- ok1(add_to_hash(ntdb, &h, new_off) == 0);
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
- /* Make sure we fill it in for later finding. */
+ new_off = alloc(ntdb, key.dsize, dbuf.dsize,
+ NTDB_USED_MAGIC, false);
+ ok1(!NTDB_OFF_IS_ERR(new_off2));
off = new_off + sizeof(struct ntdb_used_record);
ok1(!ntdb->io->twrite(ntdb, off, key.dptr, key.dsize));
off += key.dsize;
ok1(!ntdb->io->twrite(ntdb, off, dbuf.dptr, dbuf.dsize));
+ ok1(add_to_hash(ntdb, &h, new_off) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
- /* We should be able to unlock that OK. */
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_WRLCK) == 0);
+ /* Retrieve it and check. */
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off);
+ /* Should have created correct hash. */
+ ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
+ /* Should have appended to chain, bucket 2. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 3);
+ ok1(h.bucket == 2);
- /* Database should be consistent. */
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
- /* Should be able to find it. */
- v = 0;
- ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec, NULL)
- == new_off);
+ /* YA record: relocation. */
+ v = 4;
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == 0);
/* Should have created correct hash. */
ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in expanded group 0, bucket 0. */
- ok1(h.group_start == subhash + sizeof(struct ntdb_used_record));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS
- + NTDB_SUBLEVEL_HASH_BITS * 2);
+ /* Should not have located space in chain. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 3);
+ ok1(h.bucket == 3);
+ ok1(h.old_val != 0);
+
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
+
+ new_off = alloc(ntdb, key.dsize, dbuf.dsize,
+ NTDB_USED_MAGIC, false);
+ ok1(!NTDB_OFF_IS_ERR(new_off2));
+ off = new_off + sizeof(struct ntdb_used_record);
+ ok1(!ntdb->io->twrite(ntdb, off, key.dptr, key.dsize));
+ off += key.dsize;
+ ok1(!ntdb->io->twrite(ntdb, off, dbuf.dptr, dbuf.dsize));
+ ok1(add_to_hash(ntdb, &h, new_off) == 0);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
+
+ /* Retrieve it and check. */
+ ok1(find_and_lock(ntdb, key, F_WRLCK, &h, &rec) == new_off);
+ /* Should have created correct hash. */
+ ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
+ /* Should have appended to chain, bucket 2. */
+ ok1(h.table > NTDB_HASH_OFFSET);
+ ok1(h.table_size == 4);
+ ok1(h.bucket == 3);
+
+ /* Should have lock on bucket 0 */
+ ok1((h.h & ((1 << ntdb->hash_bits)-1)) == 0);
+ ok1((ntdb->flags & NTDB_NOLOCK) || ntdb->file->num_lockrecs == 1);
+ ok1((ntdb->flags & NTDB_NOLOCK)
+ || ntdb->file->lockrecs[0].off == NTDB_HASH_LOCK_START);
+ ok1(ntdb_unlock_hash(ntdb, h.h, F_WRLCK) == 0);
ntdb_close(ntdb);
}
diff --git a/lib/ntdb/test/run-15-append.c b/lib/ntdb/test/run-15-append.c
index 3c208137f2..97fd53c241 100644
--- a/lib/ntdb/test/run-15-append.c
+++ b/lib/ntdb/test/run-15-append.c
@@ -12,10 +12,10 @@ static ntdb_off_t ntdb_offset(struct ntdb_context *ntdb, NTDB_DATA key)
struct ntdb_used_record urec;
struct hash_info h;
- off = find_and_lock(ntdb, key, F_RDLCK, &h, &urec, NULL);
+ off = find_and_lock(ntdb, key, F_RDLCK, &h, &urec);
if (NTDB_OFF_IS_ERR(off))
return 0;
- ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range, F_RDLCK);
+ ntdb_unlock_hash(ntdb, h.h, F_RDLCK);
return off;
}
diff --git a/lib/ntdb/test/run-20-growhash.c b/lib/ntdb/test/run-20-growhash.c
deleted file mode 100644
index 5559370f2a..0000000000
--- a/lib/ntdb/test/run-20-growhash.c
+++ /dev/null
@@ -1,137 +0,0 @@
-#include "ntdb-source.h"
-#include "tap-interface.h"
-#include "logging.h"
-
-static uint64_t myhash(const void *key, size_t len, uint64_t seed, void *priv)
-{
- return *(const uint64_t *)key;
-}
-
-static void add_bits(uint64_t *val, unsigned new, unsigned new_bits,
- unsigned *done)
-{
- *done += new_bits;
- *val |= ((uint64_t)new << (64 - *done));
-}
-
-static uint64_t make_key(unsigned topgroup, unsigned topbucket,
- unsigned subgroup1, unsigned subbucket1,
- unsigned subgroup2, unsigned subbucket2)
-{
- uint64_t key = 0;
- unsigned done = 0;
-
- add_bits(&key, topgroup, NTDB_TOPLEVEL_HASH_BITS - NTDB_HASH_GROUP_BITS,
- &done);
- add_bits(&key, topbucket, NTDB_HASH_GROUP_BITS, &done);
- add_bits(&key, subgroup1, NTDB_SUBLEVEL_HASH_BITS - NTDB_HASH_GROUP_BITS,
- &done);
- add_bits(&key, subbucket1, NTDB_HASH_GROUP_BITS, &done);
- add_bits(&key, subgroup2, NTDB_SUBLEVEL_HASH_BITS - NTDB_HASH_GROUP_BITS,
- &done);
- add_bits(&key, subbucket2, NTDB_HASH_GROUP_BITS, &done);
- return key;
-}
-
-int main(int argc, char *argv[])
-{
- unsigned int i, j;
- struct ntdb_context *ntdb;
- uint64_t kdata;
- struct ntdb_used_record rec;
- NTDB_DATA key = { (unsigned char *)&kdata, sizeof(kdata) };
- NTDB_DATA dbuf = { (unsigned char *)&kdata, sizeof(kdata) };
- union ntdb_attribute hattr = { .hash = { .base = { NTDB_ATTRIBUTE_HASH },
- .fn = myhash } };
- int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
- NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
- NTDB_NOMMAP|NTDB_CONVERT,
- };
-
- hattr.base.next = &tap_log_attr;
-
- plan_tests(sizeof(flags) / sizeof(flags[0])
- * (9 + (20 + 2 * ((1 << NTDB_HASH_GROUP_BITS) - 2))
- * (1 << NTDB_HASH_GROUP_BITS)) + 1);
- for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
- struct hash_info h;
-
- ntdb = ntdb_open("run-20-growhash.ntdb", flags[i],
- O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr);
- ok1(ntdb);
- if (!ntdb)
- continue;
-
- /* Fill a group. */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++) {
- kdata = make_key(0, j, 0, 0, 0, 0);
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
- }
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
-
- /* Check first still exists. */
- kdata = make_key(0, 0, 0, 0, 0, 0);
- ok1(find_and_lock(ntdb, key, F_RDLCK, &h, &rec, NULL) != 0);
- /* Should have created correct hash. */
- ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have located space in group 0, bucket 0. */
- ok1(h.group_start == offsetof(struct ntdb_header, hashtable));
- ok1(h.home_bucket == 0);
- ok1(h.found_bucket == 0);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS);
- /* Entire group should be full! */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++)
- ok1(h.group[j] != 0);
-
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_RDLCK) == 0);
-
- /* Now, add one more to each should expand (that) bucket. */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++) {
- unsigned int k;
- kdata = make_key(0, j, 0, 1, 0, 0);
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
-
- ok1(find_and_lock(ntdb, key, F_RDLCK, &h, &rec, NULL));
- /* Should have created correct hash. */
- ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have moved to subhash */
- ok1(h.group_start >= sizeof(struct ntdb_header));
- ok1(h.home_bucket == 1);
- ok1(h.found_bucket == 1);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS
- + NTDB_SUBLEVEL_HASH_BITS);
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_RDLCK) == 0);
-
- /* Keep adding, make it expand again. */
- for (k = 2; k < (1 << NTDB_HASH_GROUP_BITS); k++) {
- kdata = make_key(0, j, 0, k, 0, 0);
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
- }
-
- /* This should tip it over to sub-sub-hash. */
- kdata = make_key(0, j, 0, 0, 0, 1);
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
-
- ok1(find_and_lock(ntdb, key, F_RDLCK, &h, &rec, NULL));
- /* Should have created correct hash. */
- ok1(h.h == ntdb_hash(ntdb, key.dptr, key.dsize));
- /* Should have moved to subhash */
- ok1(h.group_start >= sizeof(struct ntdb_header));
- ok1(h.home_bucket == 1);
- ok1(h.found_bucket == 1);
- ok1(h.hash_used == NTDB_TOPLEVEL_HASH_BITS
- + NTDB_SUBLEVEL_HASH_BITS + NTDB_SUBLEVEL_HASH_BITS);
- ok1(ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range,
- F_RDLCK) == 0);
- }
- ntdb_close(ntdb);
- }
-
- ok1(tap_log_messages == 0);
- return exit_status();
-}
diff --git a/lib/ntdb/test/run-25-hashoverload.c b/lib/ntdb/test/run-25-hashoverload.c
index 611eb71bf6..1b69fe9a61 100644
--- a/lib/ntdb/test/run-25-hashoverload.c
+++ b/lib/ntdb/test/run-25-hashoverload.c
@@ -2,7 +2,9 @@
#include "tap-interface.h"
#include "logging.h"
-static uint64_t badhash(const void *key, size_t len, uint64_t seed, void *priv)
+#define OVERLOAD 100
+
+static uint32_t badhash(const void *key, size_t len, uint32_t seed, void *priv)
{
return 0;
}
@@ -29,7 +31,7 @@ int main(int argc, char *argv[])
hattr.base.next = &tap_log_attr;
- plan_tests(6883);
+ plan_tests(sizeof(flags) / sizeof(flags[0]) * (7 * OVERLOAD + 11) + 1);
for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */
@@ -39,70 +41,47 @@ int main(int argc, char *argv[])
if (!ntdb)
continue;
- /* Fill a group. */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++) {
+ /* Overload a bucket. */
+ for (j = 0; j < OVERLOAD; j++) {
ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
}
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
- /* Now store one last value: should form chain. */
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
-
/* Check we can find them all. */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS) + 1; j++) {
- ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
- ok1(d.dsize == sizeof(j));
- ok1(d.dptr != NULL);
- ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
- free(d.dptr);
- }
-
- /* Now add a *lot* more. */
- for (j = (1 << NTDB_HASH_GROUP_BITS) + 1;
- j < (16 << NTDB_HASH_GROUP_BITS);
- j++) {
- ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
+ for (j = 0; j < OVERLOAD; j++) {
ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
ok1(d.dsize == sizeof(j));
ok1(d.dptr != NULL);
ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
free(d.dptr);
}
- ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Traverse through them. */
- ok1(ntdb_traverse(ntdb, trav, NULL) == j);
+ ok1(ntdb_traverse(ntdb, trav, NULL) == OVERLOAD);
- /* Empty the first chain-worth. */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++)
+ /* Delete the first 99. */
+ for (j = 0; j < OVERLOAD-1; j++)
ok1(ntdb_delete(ntdb, key) == 0);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
- for (j = (1 << NTDB_HASH_GROUP_BITS);
- j < (16 << NTDB_HASH_GROUP_BITS);
- j++) {
- ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
- ok1(d.dsize == sizeof(j));
- ok1(d.dptr != NULL);
- ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
- free(d.dptr);
- }
+ ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
+ ok1(d.dsize == sizeof(j));
+ ok1(d.dptr != NULL);
+ ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
+ free(d.dptr);
/* Traverse through them. */
- ok1(ntdb_traverse(ntdb, trav, NULL)
- == (15 << NTDB_HASH_GROUP_BITS));
+ ok1(ntdb_traverse(ntdb, trav, NULL) == 1);
/* Re-add */
- for (j = 0; j < (1 << NTDB_HASH_GROUP_BITS); j++) {
+ for (j = 0; j < OVERLOAD-1; j++) {
ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
}
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
/* Now try deleting as we go. */
- ok1(ntdb_traverse(ntdb, trav, trav)
- == (16 << NTDB_HASH_GROUP_BITS));
+ ok1(ntdb_traverse(ntdb, trav, trav) == OVERLOAD);
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
ok1(ntdb_traverse(ntdb, trav, NULL) == 0);
ntdb_close(ntdb);
diff --git a/lib/ntdb/test/run-30-exhaust-before-expand.c b/lib/ntdb/test/run-30-exhaust-before-expand.c
index 24c48b005a..cc9ea3fa3d 100644
--- a/lib/ntdb/test/run-30-exhaust-before-expand.c
+++ b/lib/ntdb/test/run-30-exhaust-before-expand.c
@@ -50,7 +50,7 @@ int main(int argc, char *argv[])
size = ntdb->file->map_size;
/* Create one record to chew up most space. */
- d.dsize = size - sizeof(struct new_database) - 32;
+ d.dsize = size - NEW_DATABASE_HDR_SIZE(ntdb->hash_bits) - 32;
d.dptr = calloc(d.dsize, 1);
j = 0;
ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
diff --git a/lib/ntdb/test/run-35-convert.c b/lib/ntdb/test/run-35-convert.c
index 6a38d425cb..5b8099c448 100644
--- a/lib/ntdb/test/run-35-convert.c
+++ b/lib/ntdb/test/run-35-convert.c
@@ -24,6 +24,10 @@ int main(int argc, char *argv[])
failtest_exit(exit_status());
ntdb_close(ntdb);
+ /* We can fail in log message formatting or open. That's OK */
+ if (failtest_has_failed()) {
+ failtest_exit(exit_status());
+ }
/* If we say NTDB_CONVERT, it must be converted */
ntdb = ntdb_open("run-35-convert.ntdb",
flags[i]|NTDB_CONVERT,
diff --git a/lib/ntdb/test/run-50-multiple-freelists.c b/lib/ntdb/test/run-50-multiple-freelists.c
index 962462e5d4..5496e3e0dd 100644
--- a/lib/ntdb/test/run-50-multiple-freelists.c
+++ b/lib/ntdb/test/run-50-multiple-freelists.c
@@ -39,27 +39,27 @@ int main(int argc, char *argv[])
ok1(ntdb_check(ntdb, NULL, NULL) == 0);
off = get_free(ntdb, 0, 80 - sizeof(struct ntdb_used_record), 0,
- NTDB_USED_MAGIC, 0);
+ NTDB_USED_MAGIC);
ok1(off == layout->elem[3].base.off);
ok1(ntdb->ftable_off == layout->elem[0].base.off);
off = get_free(ntdb, 0, 160 - sizeof(struct ntdb_used_record), 0,
- NTDB_USED_MAGIC, 0);
+ NTDB_USED_MAGIC);
ok1(off == layout->elem[5].base.off);
ok1(ntdb->ftable_off == layout->elem[1].base.off);
off = get_free(ntdb, 0, 320 - sizeof(struct ntdb_used_record), 0,
- NTDB_USED_MAGIC, 0);
+ NTDB_USED_MAGIC);
ok1(off == layout->elem[7].base.off);
ok1(ntdb->ftable_off == layout->elem[2].base.off);
off = get_free(ntdb, 0, 40 - sizeof(struct ntdb_used_record), 0,
- NTDB_USED_MAGIC, 0);
+ NTDB_USED_MAGIC);
ok1(off == layout->elem[9].base.off);
ok1(ntdb->ftable_off == layout->elem[0].base.off);
/* Now we fail. */
- off = get_free(ntdb, 0, 0, 1, NTDB_USED_MAGIC, 0);
+ off = get_free(ntdb, 0, 0, 1, NTDB_USED_MAGIC);
ok1(off == 0);
ntdb_close(ntdb);
diff --git a/lib/ntdb/test/run-64-bit-tdb.c b/lib/ntdb/test/run-64-bit-tdb.c
index a85a4af56c..5afdd8747c 100644
--- a/lib/ntdb/test/run-64-bit-tdb.c
+++ b/lib/ntdb/test/run-64-bit-tdb.c
@@ -39,7 +39,8 @@ int main(int argc, char *argv[])
/* Add a fake record to chew up the existing free space. */
k = ntdb_mkdata("fake", 4);
- d.dsize = ntdb->file->map_size - sizeof(struct new_database)- 8;
+ d.dsize = ntdb->file->map_size
+ - NEW_DATABASE_HDR_SIZE(ntdb->hash_bits) - 8;
d.dptr = malloc(d.dsize);
memset(d.dptr, 0, d.dsize);
ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
@@ -66,9 +67,9 @@ int main(int argc, char *argv[])
ok1(ntdb_check(ntdb, NULL, NULL) == NTDB_SUCCESS);
/* Make sure it put it at end as we expected. */
- off = find_and_lock(ntdb, k, F_RDLCK, &h, &rec, NULL);
+ off = find_and_lock(ntdb, k, F_RDLCK, &h, &rec);
ok1(off >= ALMOST_4G);
- ntdb_unlock_hashes(ntdb, h.hlock_start, h.hlock_range, F_RDLCK);
+ ntdb_unlock_hash(ntdb, h.h, F_RDLCK);
ok1(ntdb_fetch(ntdb, k, &d) == 0);
ok1(d.dsize == 5);
diff --git a/lib/ntdb/test/run-90-get-set-attributes.c b/lib/ntdb/test/run-90-get-set-attributes.c
index fc265b0729..4f8792569f 100644
--- a/lib/ntdb/test/run-90-get-set-attributes.c
+++ b/lib/ntdb/test/run-90-get-set-attributes.c
@@ -13,7 +13,7 @@ static int myunlock(int fd, int rw, off_t off, off_t len, void *unused)
return 0;
}
-static uint64_t hash_fn(const void *key, size_t len, uint64_t seed,
+static uint32_t hash_fn(const void *key, size_t len, uint32_t seed,
void *priv)
{
return 0;
diff --git a/lib/ntdb/test/run-capabilities.c b/lib/ntdb/test/run-capabilities.c
index 52c4fac0e6..cb03746862 100644
--- a/lib/ntdb/test/run-capabilities.c
+++ b/lib/ntdb/test/run-capabilities.c
@@ -39,7 +39,7 @@ static void create_ntdb(const char *name,
ntdb_layout_add_freetable(layout);
ntdb_layout_add_used(layout, key, data, 6);
clen = len_of(breaks_check, breaks_write, breaks_open);
- ntdb_layout_add_free(layout, 56480 - clen, 0);
+ ntdb_layout_add_free(layout, 15496 - clen, 0);
ntdb_layout_add_capability(layout, cap,
breaks_write, breaks_check, breaks_open,
clen);
@@ -53,7 +53,7 @@ static void create_ntdb(const char *name,
key.dsize--;
ntdb_layout_add_used(layout, key, data, 11 - key.dsize);
clen = len_of(breaks_check, breaks_write, breaks_open);
- ntdb_layout_add_free(layout, 65456 - clen, 0);
+ ntdb_layout_add_free(layout, 16304 - clen, 0);
ntdb_layout_add_capability(layout, cap,
breaks_write, breaks_check,
breaks_open, clen);
diff --git a/lib/ntdb/test/run-expand-in-transaction.c b/lib/ntdb/test/run-expand-in-transaction.c
index 54f9d81dec..71866a37c1 100644
--- a/lib/ntdb/test/run-expand-in-transaction.c
+++ b/lib/ntdb/test/run-expand-in-transaction.c
@@ -25,7 +25,8 @@ int main(int argc, char *argv[])
size = ntdb->file->map_size;
/* Add a fake record to chew up the existing free space. */
k = ntdb_mkdata("fake", 4);
- d.dsize = ntdb->file->map_size - sizeof(struct new_database)- 8;
+ d.dsize = ntdb->file->map_size
+ - NEW_DATABASE_HDR_SIZE(ntdb->hash_bits) - 8;
d.dptr = malloc(d.dsize);
memset(d.dptr, 0, d.dsize);
ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
diff --git a/lib/ntdb/test/run-traverse.c b/lib/ntdb/test/run-traverse.c
index 9dfc94d3b3..ed95f33604 100644
--- a/lib/ntdb/test/run-traverse.c
+++ b/lib/ntdb/test/run-traverse.c
@@ -5,7 +5,7 @@
#define NUM_RECORDS 1000
/* We use the same seed which we saw a failure on. */
-static uint64_t fixedhash(const void *key, size_t len, uint64_t seed, void *p)
+static uint32_t fixedhash(const void *key, size_t len, uint32_t seed, void *p)
{
return hash64_stable((const unsigned char *)key, len,
*(uint64_t *)p);