- /*
+ /*
Trivial Database 2: hash handling
Copyright (C) Rusty Russell 2010
-
+
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
}
/* Get bits from a value. */
-static uint32_t bits(uint64_t val, unsigned start, unsigned num)
+static uint32_t bits_from(uint64_t val, unsigned start, unsigned num)
{
assert(num <= 32);
return (val >> start) & ((1U << num) - 1);
static uint32_t use_bits(struct hash_info *h, unsigned num)
{
h->hash_used += num;
- return bits(h->h, 64 - h->hash_used, num);
+ return bits_from(h->h, 64 - h->hash_used, num);
}
static bool key_matches(struct tdb_context *tdb,
}
/* Top bits of offset == next bits of hash. */
- if (bits(val, TDB_OFF_HASH_EXTRA_BIT, TDB_OFF_UPPER_STEAL_EXTRA)
- != bits(h->h, 64 - h->hash_used - TDB_OFF_UPPER_STEAL_EXTRA,
+ if (bits_from(val, TDB_OFF_HASH_EXTRA_BIT, TDB_OFF_UPPER_STEAL_EXTRA)
+ != bits_from(h->h, 64 - h->hash_used - TDB_OFF_UPPER_STEAL_EXTRA,
TDB_OFF_UPPER_STEAL_EXTRA)) {
add_stat(tdb, compare_wrong_offsetbits, 1);
return false;
tinfo->toplevel_group = group;
tinfo->num_levels = 1;
tinfo->levels[0].entry = 0;
- tinfo->levels[0].hashtable = hashtable
+ tinfo->levels[0].hashtable = hashtable
+ (group << TDB_HASH_GROUP_BITS) * sizeof(tdb_off_t);
tinfo->levels[0].total_buckets = 1 << TDB_HASH_GROUP_BITS;
}
{
return h->home_bucket
| new_off
- | ((uint64_t)bits(h->h,
+ | ((uint64_t)bits_from(h->h,
64 - h->hash_used - TDB_OFF_UPPER_STEAL_EXTRA,
TDB_OFF_UPPER_STEAL_EXTRA)
<< TDB_OFF_HASH_EXTRA_BIT);
}
-/* Simply overwrite the hash entry we found before. */
+/* Simply overwrite the hash entry we found before. */
int replace_in_hash(struct tdb_context *tdb,
struct hash_info *h,
tdb_off_t new_off)
return -1;
if (!next) {
- next = alloc(tdb, 0, sizeof(struct tdb_chain), 2,
- false);
+ next = alloc(tdb, 0, sizeof(struct tdb_chain), 0,
+ TDB_CHAIN_MAGIC, false);
if (next == TDB_OFF_ERR)
return -1;
if (zero_out(tdb, next+sizeof(struct tdb_used_record),
static int expand_group(struct tdb_context *tdb, struct hash_info *h)
{
- unsigned bucket, num_vals, i, hash;
+ unsigned bucket, num_vals, i, magic;
size_t subsize;
tdb_off_t subhash;
tdb_off_t vals[1 << TDB_HASH_GROUP_BITS];
if (h->hash_used == 64) {
add_stat(tdb, alloc_chain, 1);
subsize = sizeof(struct tdb_chain);
- hash = 2;
+ magic = TDB_CHAIN_MAGIC;
} else {
add_stat(tdb, alloc_subhash, 1);
subsize = (sizeof(tdb_off_t) << TDB_SUBLEVEL_HASH_BITS);
- hash = 0;
+ magic = TDB_HTABLE_MAGIC;
}
- subhash = alloc(tdb, 0, subsize, hash, false);
+ subhash = alloc(tdb, 0, subsize, 0, magic, false);
if (subhash == TDB_OFF_ERR)
return -1;
TDB_DATA *kbuf, size_t *dlen)
{
const unsigned group_bits = TDB_TOPLEVEL_HASH_BITS-TDB_HASH_GROUP_BITS;
- tdb_off_t hlock_start, hlock_range, off;
+ tdb_off_t hl_start, hl_range, off;
while (tinfo->toplevel_group < (1 << group_bits)) {
- hlock_start = (tdb_off_t)tinfo->toplevel_group
+ hl_start = (tdb_off_t)tinfo->toplevel_group
<< (64 - group_bits);
- hlock_range = 1ULL << group_bits;
- if (tdb_lock_hashes(tdb, hlock_start, hlock_range, ltype,
+ hl_range = 1ULL << group_bits;
+ if (tdb_lock_hashes(tdb, hl_start, hl_range, ltype,
TDB_LOCK_WAIT) != 0)
return -1;
if (tdb_read_convert(tdb, off, &rec, sizeof(rec))) {
tdb_unlock_hashes(tdb,
- hlock_start, hlock_range,
- ltype);
+ hl_start, hl_range, ltype);
return -1;
}
- if (rec_magic(&rec) != TDB_MAGIC) {
+ if (rec_magic(&rec) != TDB_USED_MAGIC) {
tdb_logerr(tdb, TDB_ERR_CORRUPT,
- TDB_DEBUG_FATAL,
+ TDB_LOG_ERROR,
"next_in_hash:"
" corrupt record at %llu",
(long long)off);
/* They want data as well? */
if (dlen) {
*dlen = rec_data_length(&rec);
- kbuf->dptr = tdb_alloc_read(tdb,
+ kbuf->dptr = tdb_alloc_read(tdb,
off + sizeof(rec),
kbuf->dsize
+ *dlen);
} else {
- kbuf->dptr = tdb_alloc_read(tdb,
+ kbuf->dptr = tdb_alloc_read(tdb,
off + sizeof(rec),
kbuf->dsize);
}
- tdb_unlock_hashes(tdb, hlock_start, hlock_range, ltype);
+ tdb_unlock_hashes(tdb, hl_start, hl_range, ltype);
return kbuf->dptr ? 1 : -1;
}
- tdb_unlock_hashes(tdb, hlock_start, hlock_range, ltype);
+ tdb_unlock_hashes(tdb, hl_start, hl_range, ltype);
tinfo->toplevel_group++;
tinfo->levels[0].hashtable
unsigned int group, gbits;
gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS;
- group = bits(h, 64 - gbits, gbits);
+ group = bits_from(h, 64 - gbits, gbits);
lockstart = hlock_range(group, &locksize);
unsigned int group, gbits;
gbits = TDB_TOPLEVEL_HASH_BITS - TDB_HASH_GROUP_BITS;
- group = bits(h, 64 - gbits, gbits);
+ group = bits_from(h, 64 - gbits, gbits);
lockstart = hlock_range(group, &locksize);