From d117f992bde6b7157a8eecbce8a026f2aa7ab4ae Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Fri, 24 Sep 2010 13:37:04 +0930 Subject: [PATCH] tdb: add Bob Jenkins lookup3 hash as helper hash. This is a better hash than the default: shipping it with tdb makes it easy for callers to use it as the hash by passing it to tdb_open_ex(). --- ccan/tdb/_info | 1 - ccan/tdb/hash.c | 358 ++++++++++++++++++++ ccan/tdb/open.c | 16 +- ccan/tdb/tdb.h | 1 + ccan/tdb/tdb_private.h | 2 +- ccan/tdb/test/run-3G-file.c | 1 + ccan/tdb/test/run-bad-tdb-header.c | 1 + ccan/tdb/test/run-check.c | 1 + ccan/tdb/test/run-corrupt.c | 1 + ccan/tdb/test/run-die-during-transaction.c | 1 + ccan/tdb/test/run-endian.c | 1 + ccan/tdb/test/run-nested-transactions.c | 1 + ccan/tdb/test/run-nested-traverse.c | 1 + ccan/tdb/test/run-no-lock-during-traverse.c | 1 + ccan/tdb/test/run-oldhash.c | 11 +- ccan/tdb/test/run-open-during-transaction.c | 1 + ccan/tdb/test/run-readonly-check.c | 1 + ccan/tdb/test/run-rwlock-check.c | 2 +- ccan/tdb/test/run-traverse-in-transaction.c | 1 + ccan/tdb/test/run-wronghash-fail.c | 17 +- ccan/tdb/test/run-zero-append.c | 1 + ccan/tdb/test/run.c | 1 + 22 files changed, 385 insertions(+), 37 deletions(-) create mode 100644 ccan/tdb/hash.c diff --git a/ccan/tdb/_info b/ccan/tdb/_info index 7ba90f79..c2e5266b 100644 --- a/ccan/tdb/_info +++ b/ccan/tdb/_info @@ -73,7 +73,6 @@ int main(int argc, char *argv[]) return 1; if (strcmp(argv[1], "depends") == 0) { - printf("ccan/hash\n"); return 0; } diff --git a/ccan/tdb/hash.c b/ccan/tdb/hash.c new file mode 100644 index 00000000..2408f887 --- /dev/null +++ b/ccan/tdb/hash.c @@ -0,0 +1,358 @@ +#include "tdb_private.h" + +/* This is based on the hash algorithm from gdbm */ +unsigned int tdb_old_hash(TDB_DATA *key) +{ + uint32_t value; /* Used to compute the hash value. */ + uint32_t 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); +} + +#if HAVE_LITTLE_ENDIAN +# define HASH_LITTLE_ENDIAN 1 +# define HASH_BIG_ENDIAN 0 +#elif HAVE_BIG_ENDIAN +# define HASH_LITTLE_ENDIAN 0 +# define HASH_BIG_ENDIAN 1 +#else +# error Unknown endian +#endif + +/* +------------------------------------------------------------------------------- +lookup3.c, by Bob Jenkins, May 2006, Public Domain. + +These are functions for producing 32-bit hashes for hash table lookup. +hash_word(), hashlittle(), hashlittle2(), hashbig(), mix(), and final() +are externally useful functions. Routines to test the hash are included +if SELF_TEST is defined. You can use this free for any purpose. It's in +the public domain. It has no warranty. + +You probably want to use hashlittle(). hashlittle() and hashbig() +hash byte arrays. hashlittle() is is faster than hashbig() on +little-endian machines. Intel and AMD are little-endian machines. +On second thought, you probably want hashlittle2(), which is identical to +hashlittle() except it returns two 32-bit hashes for the price of one. +You could implement hashbig2() if you wanted but I haven't bothered here. + +If you want to find a hash of, say, exactly 7 integers, do + a = i1; b = i2; c = i3; + mix(a,b,c); + a += i4; b += i5; c += i6; + mix(a,b,c); + a += i7; + final(a,b,c); +then use c as the hash value. If you have a variable length array of +4-byte integers to hash, use hash_word(). If you have a byte array (like +a character string), use hashlittle(). If you have several byte arrays, or +a mix of things, see the comments above hashlittle(). + +Why is this so big? I read 12 bytes at a time into 3 4-byte integers, +then mix those integers. This is fast (you can do a lot more thorough +mixing with 12*3 instructions on 3 integers than you can with 3 instructions +on 1 byte), but shoehorning those bytes into integers efficiently is messy. +*/ + +#define hashsize(n) ((uint32_t)1<<(n)) +#define hashmask(n) (hashsize(n)-1) +#define rot(x,k) (((x)<<(k)) | ((x)>>(32-(k)))) + +/* +------------------------------------------------------------------------------- +mix -- mix 3 32-bit values reversibly. + +This is reversible, so any information in (a,b,c) before mix() is +still in (a,b,c) after mix(). + +If four pairs of (a,b,c) inputs are run through mix(), or through +mix() in reverse, there are at least 32 bits of the output that +are sometimes the same for one pair and different for another pair. +This was tested for: +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +Some k values for my "a-=c; a^=rot(c,k); c+=b;" arrangement that +satisfy this are + 4 6 8 16 19 4 + 9 15 3 18 27 15 + 14 9 3 7 17 3 +Well, "9 15 3 18 27 15" didn't quite get 32 bits diffing +for "differ" defined as + with a one-bit base and a two-bit delta. I +used http://burtleburtle.net/bob/hash/avalanche.html to choose +the operations, constants, and arrangements of the variables. + +This does not achieve avalanche. There are input bits of (a,b,c) +that fail to affect some output bits of (a,b,c), especially of a. The +most thoroughly mixed value is c, but it doesn't really even achieve +avalanche in c. + +This allows some parallelism. Read-after-writes are good at doubling +the number of bits affected, so the goal of mixing pulls in the opposite +direction as the goal of parallelism. I did what I could. Rotates +seem to cost as much as shifts on every machine I could lay my hands +on, and rotates are much kinder to the top and bottom bits, so I used +rotates. +------------------------------------------------------------------------------- +*/ +#define mix(a,b,c) \ +{ \ + a -= c; a ^= rot(c, 4); c += b; \ + b -= a; b ^= rot(a, 6); a += c; \ + c -= b; c ^= rot(b, 8); b += a; \ + a -= c; a ^= rot(c,16); c += b; \ + b -= a; b ^= rot(a,19); a += c; \ + c -= b; c ^= rot(b, 4); b += a; \ +} + +/* +------------------------------------------------------------------------------- +final -- final mixing of 3 32-bit values (a,b,c) into c + +Pairs of (a,b,c) values differing in only a few bits will usually +produce values of c that look totally different. This was tested for +* pairs that differed by one bit, by two bits, in any combination + of top bits of (a,b,c), or in any combination of bottom bits of + (a,b,c). +* "differ" is defined as +, -, ^, or ~^. For + and -, I transformed + the output delta to a Gray code (a^(a>>1)) so a string of 1's (as + is commonly produced by subtraction) look like a single 1-bit + difference. +* the base values were pseudorandom, all zero but one bit set, or + all zero plus a counter that starts at zero. + +These constants passed: + 14 11 25 16 4 14 24 + 12 14 25 16 4 14 24 +and these came close: + 4 8 15 26 3 22 24 + 10 8 15 26 3 22 24 + 11 8 15 26 3 22 24 +------------------------------------------------------------------------------- +*/ +#define final(a,b,c) \ +{ \ + c ^= b; c -= rot(b,14); \ + a ^= c; a -= rot(c,11); \ + b ^= a; b -= rot(a,25); \ + c ^= b; c -= rot(b,16); \ + a ^= c; a -= rot(c,4); \ + b ^= a; b -= rot(a,14); \ + c ^= b; c -= rot(b,24); \ +} + + +/* +------------------------------------------------------------------------------- +hashlittle() -- hash a variable-length key into a 32-bit value + k : the key (the unaligned variable-length array of bytes) + length : the length of the key, counting by bytes + val2 : IN: can be any 4-byte value OUT: second 32 bit hash. +Returns a 32-bit value. Every bit of the key affects every bit of +the return value. Two keys differing by one or two bits will have +totally different hash values. Note that the return value is better +mixed than val2, so use that first. + +The best hash table sizes are powers of 2. There is no need to do +mod a prime (mod is sooo slow!). If you need less than 32 bits, +use a bitmask. For example, if you need only 10 bits, do + h = (h & hashmask(10)); +In which case, the hash table should have hashsize(10) elements. + +If you are hashing n strings (uint8_t **)k, do it like this: + for (i=0, h=0; i 12) + { + a += k[0]; + b += k[1]; + c += k[2]; + mix(a,b,c); + length -= 12; + k += 3; + } + + /*----------------------------- handle the last (probably partial) block */ + /* + * "k[2]&0xffffff" actually reads beyond the end of the string, but + * then masks off the part it's not allowed to read. Because the + * string is aligned, the masked-off tail is in the same word as the + * rest of the string. Every machine with memory protection I've seen + * does it on word boundaries, so is OK with this. But VALGRIND will + * still catch it and complain. The masking trick does make the hash + * noticably faster for short strings (like English words). + */ +#ifndef VALGRIND + + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=k[2]&0xffffff; b+=k[1]; a+=k[0]; break; + case 10: c+=k[2]&0xffff; b+=k[1]; a+=k[0]; break; + case 9 : c+=k[2]&0xff; b+=k[1]; a+=k[0]; break; + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=k[1]&0xffffff; a+=k[0]; break; + case 6 : b+=k[1]&0xffff; a+=k[0]; break; + case 5 : b+=k[1]&0xff; a+=k[0]; break; + case 4 : a+=k[0]; break; + case 3 : a+=k[0]&0xffffff; break; + case 2 : a+=k[0]&0xffff; break; + case 1 : a+=k[0]&0xff; break; + case 0 : return c; /* zero length strings require no mixing */ + } + +#else /* make valgrind happy */ + + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[2]; b+=k[1]; a+=k[0]; break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=((uint32_t)k8[9])<<8; /* fall through */ + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[1]; a+=k[0]; break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=((uint32_t)k8[5])<<8; /* fall through */ + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]; break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=((uint32_t)k8[1])<<8; /* fall through */ + case 1 : a+=k8[0]; break; + case 0 : return c; + } + +#endif /* !valgrind */ + + } else if (HASH_LITTLE_ENDIAN && ((u.i & 0x1) == 0)) { + const uint16_t *k = (const uint16_t *)key; /* read 16-bit chunks */ + const uint8_t *k8; + + /*--------------- all but last block: aligned reads and different mixing */ + while (length > 12) + { + a += k[0] + (((uint32_t)k[1])<<16); + b += k[2] + (((uint32_t)k[3])<<16); + c += k[4] + (((uint32_t)k[5])<<16); + mix(a,b,c); + length -= 12; + k += 6; + } + + /*----------------------------- handle the last (probably partial) block */ + k8 = (const uint8_t *)k; + switch(length) + { + case 12: c+=k[4]+(((uint32_t)k[5])<<16); + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 11: c+=((uint32_t)k8[10])<<16; /* fall through */ + case 10: c+=k[4]; + b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 9 : c+=k8[8]; /* fall through */ + case 8 : b+=k[2]+(((uint32_t)k[3])<<16); + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 7 : b+=((uint32_t)k8[6])<<16; /* fall through */ + case 6 : b+=k[2]; + a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 5 : b+=k8[4]; /* fall through */ + case 4 : a+=k[0]+(((uint32_t)k[1])<<16); + break; + case 3 : a+=((uint32_t)k8[2])<<16; /* fall through */ + case 2 : a+=k[0]; + break; + case 1 : a+=k8[0]; + break; + case 0 : return c; /* zero length requires no mixing */ + } + + } else { /* need to read the key one byte at a time */ + const uint8_t *k = (const uint8_t *)key; + + /*--------------- all but the last block: affect some 32 bits of (a,b,c) */ + while (length > 12) + { + a += k[0]; + a += ((uint32_t)k[1])<<8; + a += ((uint32_t)k[2])<<16; + a += ((uint32_t)k[3])<<24; + b += k[4]; + b += ((uint32_t)k[5])<<8; + b += ((uint32_t)k[6])<<16; + b += ((uint32_t)k[7])<<24; + c += k[8]; + c += ((uint32_t)k[9])<<8; + c += ((uint32_t)k[10])<<16; + c += ((uint32_t)k[11])<<24; + mix(a,b,c); + length -= 12; + k += 12; + } + + /*-------------------------------- last block: affect all 32 bits of (c) */ + switch(length) /* all the case statements fall through */ + { + case 12: c+=((uint32_t)k[11])<<24; + case 11: c+=((uint32_t)k[10])<<16; + case 10: c+=((uint32_t)k[9])<<8; + case 9 : c+=k[8]; + case 8 : b+=((uint32_t)k[7])<<24; + case 7 : b+=((uint32_t)k[6])<<16; + case 6 : b+=((uint32_t)k[5])<<8; + case 5 : b+=k[4]; + case 4 : a+=((uint32_t)k[3])<<24; + case 3 : a+=((uint32_t)k[2])<<16; + case 2 : a+=((uint32_t)k[1])<<8; + case 1 : a+=k[0]; + break; + case 0 : return c; + } + } + + final(a,b,c); + return c; +} + +unsigned int tdb_jenkins_hash(TDB_DATA *key) +{ + return hashlittle(key->dptr, key->dsize); +} diff --git a/ccan/tdb/open.c b/ccan/tdb/open.c index aa32a45e..95f8f4c9 100644 --- a/ccan/tdb/open.c +++ b/ccan/tdb/open.c @@ -30,20 +30,6 @@ /* all contexts, to ensure no double-opens (fcntl locks don't nest!) */ static struct tdb_context *tdbs = NULL; - -/* This is based on the hash algorithm from gdbm */ -static unsigned int default_tdb_hash(TDB_DATA *key) -{ - uint32_t value; /* Used to compute the hash value. */ - uint32_t 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); -} - /* We use two hashes to double-check they're using the right hash function. */ void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash) @@ -206,7 +192,7 @@ struct tdb_context *tdb_open_ex(const char *name, int hash_size, int tdb_flags, tdb->hash_fn = hash_fn; hash_alg = "user defined"; } else { - tdb->hash_fn = default_tdb_hash; + tdb->hash_fn = tdb_old_hash; hash_alg = "default"; } diff --git a/ccan/tdb/tdb.h b/ccan/tdb/tdb.h index b84e2056..455cde43 100644 --- a/ccan/tdb/tdb.h +++ b/ccan/tdb/tdb.h @@ -149,6 +149,7 @@ void tdb_add_flags(struct tdb_context *tdb, unsigned flag); void tdb_remove_flags(struct tdb_context *tdb, unsigned flag); void tdb_enable_seqnum(struct tdb_context *tdb); void tdb_increment_seqnum_nonblock(struct tdb_context *tdb); +unsigned int tdb_jenkins_hash(TDB_DATA *key); int tdb_check(struct tdb_context *tdb, int (*check)(TDB_DATA key, TDB_DATA data, void *private), void *private); diff --git a/ccan/tdb/tdb_private.h b/ccan/tdb/tdb_private.h index 7f349797..96fdf921 100644 --- a/ccan/tdb/tdb_private.h +++ b/ccan/tdb/tdb_private.h @@ -302,5 +302,5 @@ int tdb_rec_free_read(struct tdb_context *tdb, tdb_off_t off, struct tdb_record *rec); void tdb_header_hash(struct tdb_context *tdb, uint32_t *magic1_hash, uint32_t *magic2_hash); - +unsigned int tdb_old_hash(TDB_DATA *key); #endif diff --git a/ccan/tdb/test/run-3G-file.c b/ccan/tdb/test/run-3G-file.c index 7204128f..d56aed57 100644 --- a/ccan/tdb/test/run-3G-file.c +++ b/ccan/tdb/test/run-3G-file.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-bad-tdb-header.c b/ccan/tdb/test/run-bad-tdb-header.c index 4ee225cc..330381bb 100644 --- a/ccan/tdb/test/run-bad-tdb-header.c +++ b/ccan/tdb/test/run-bad-tdb-header.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-check.c b/ccan/tdb/test/run-check.c index 4b2dcc18..f96647b9 100644 --- a/ccan/tdb/test/run-check.c +++ b/ccan/tdb/test/run-check.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-corrupt.c b/ccan/tdb/test/run-corrupt.c index bea7dbcd..2109e936 100644 --- a/ccan/tdb/test/run-corrupt.c +++ b/ccan/tdb/test/run-corrupt.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-die-during-transaction.c b/ccan/tdb/test/run-die-during-transaction.c index fb5da455..b8943602 100644 --- a/ccan/tdb/test/run-die-during-transaction.c +++ b/ccan/tdb/test/run-die-during-transaction.c @@ -20,6 +20,7 @@ static int ftruncate_check(int fd, off_t length); #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-endian.c b/ccan/tdb/test/run-endian.c index 74184a1a..0fae1621 100644 --- a/ccan/tdb/test/run-endian.c +++ b/ccan/tdb/test/run-endian.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-nested-transactions.c b/ccan/tdb/test/run-nested-transactions.c index f8fd0549..d13977ca 100644 --- a/ccan/tdb/test/run-nested-transactions.c +++ b/ccan/tdb/test/run-nested-transactions.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-nested-traverse.c b/ccan/tdb/test/run-nested-traverse.c index 7e0a71dd..c58b24c0 100644 --- a/ccan/tdb/test/run-nested-traverse.c +++ b/ccan/tdb/test/run-nested-traverse.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #undef fcntl #include diff --git a/ccan/tdb/test/run-no-lock-during-traverse.c b/ccan/tdb/test/run-no-lock-during-traverse.c index bbca2e93..df089f93 100644 --- a/ccan/tdb/test/run-no-lock-during-traverse.c +++ b/ccan/tdb/test/run-no-lock-during-traverse.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-oldhash.c b/ccan/tdb/test/run-oldhash.c index 8e5a76f8..a40600fa 100644 --- a/ccan/tdb/test/run-oldhash.c +++ b/ccan/tdb/test/run-oldhash.c @@ -9,17 +9,12 @@ #include #include #include -#include +#include #include #include #include #include "logging.h" -static unsigned int jenkins_hash(TDB_DATA *key) -{ - return hash_stable(key->dptr, key->dsize, 0); -} - int main(int argc, char *argv[]) { struct tdb_context *tdb; @@ -41,13 +36,13 @@ int main(int argc, char *argv[]) tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-le.tdb", 0, 0, O_RDWR, 0, - &taplogctx, jenkins_hash); + &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); tdb = tdb_open_ex("test/old-nohash-be.tdb", 0, 0, O_RDWR, 0, - &taplogctx, jenkins_hash); + &taplogctx, tdb_jenkins_hash); ok1(tdb); ok1(tdb_check(tdb, NULL, NULL) == 0); tdb_close(tdb); diff --git a/ccan/tdb/test/run-open-during-transaction.c b/ccan/tdb/test/run-open-during-transaction.c index 98cbac91..e7feb03f 100644 --- a/ccan/tdb/test/run-open-during-transaction.c +++ b/ccan/tdb/test/run-open-during-transaction.c @@ -21,6 +21,7 @@ static int ftruncate_check(int fd, off_t length); #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-readonly-check.c b/ccan/tdb/test/run-readonly-check.c index 87cdd643..6e92cdee 100644 --- a/ccan/tdb/test/run-readonly-check.c +++ b/ccan/tdb/test/run-readonly-check.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run-rwlock-check.c b/ccan/tdb/test/run-rwlock-check.c index 1f742f4f..aa8b4719 100644 --- a/ccan/tdb/test/run-rwlock-check.c +++ b/ccan/tdb/test/run-rwlock-check.c @@ -9,7 +9,7 @@ #include #include #include -#include +#include #include #include #include diff --git a/ccan/tdb/test/run-traverse-in-transaction.c b/ccan/tdb/test/run-traverse-in-transaction.c index a3475582..61cb1315 100644 --- a/ccan/tdb/test/run-traverse-in-transaction.c +++ b/ccan/tdb/test/run-traverse-in-transaction.c @@ -11,6 +11,7 @@ #include #include #include +#include #include #undef fcntl_with_lockcheck #include diff --git a/ccan/tdb/test/run-wronghash-fail.c b/ccan/tdb/test/run-wronghash-fail.c index 1267f22f..2f7422aa 100644 --- a/ccan/tdb/test/run-wronghash-fail.c +++ b/ccan/tdb/test/run-wronghash-fail.c @@ -9,16 +9,11 @@ #include #include #include -#include +#include #include #include #include -static unsigned int jenkins_hash(TDB_DATA *key) -{ - return hash_stable(key->dptr, key->dsize, 0); -} - static void log_fn(struct tdb_context *tdb, enum tdb_debug_level level, const char *fmt, ...) { unsigned int *count = tdb_get_logging_private(tdb); @@ -44,7 +39,7 @@ int main(int argc, char *argv[]) /* Fail to open with different hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, - &log_ctx, jenkins_hash); + &log_ctx, tdb_jenkins_hash); ok1(!tdb); ok1(log_count == 1); @@ -52,7 +47,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_CREAT|O_RDWR|O_TRUNC, - 0600, &log_ctx, jenkins_hash); + 0600, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); tdb_close(tdb); @@ -71,7 +66,7 @@ int main(int argc, char *argv[]) ok1(log_count == 1); log_count = 0; - /* Fail to open with defailt hash. */ + /* Fail to open with default hash. */ tdb = tdb_open_ex("run-wronghash-fail.tdb", 0, 0, O_RDWR, 0, &log_ctx, NULL); ok1(!tdb); @@ -79,7 +74,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb_open_ex("test/jenkins-le-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, jenkins_hash); + 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); @@ -87,7 +82,7 @@ int main(int argc, char *argv[]) log_count = 0; tdb = tdb_open_ex("test/jenkins-be-hash.tdb", 0, 0, O_RDONLY, - 0, &log_ctx, jenkins_hash); + 0, &log_ctx, tdb_jenkins_hash); ok1(tdb); ok1(log_count == 0); ok1(tdb_check(tdb, NULL, NULL) == 0); diff --git a/ccan/tdb/test/run-zero-append.c b/ccan/tdb/test/run-zero-append.c index 8cb57f40..96b0a3e0 100644 --- a/ccan/tdb/test/run-zero-append.c +++ b/ccan/tdb/test/run-zero-append.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include diff --git a/ccan/tdb/test/run.c b/ccan/tdb/test/run.c index fe09d45b..6ef3c4d6 100644 --- a/ccan/tdb/test/run.c +++ b/ccan/tdb/test/run.c @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include -- 2.39.2