+static int hash_add(struct tdb_context *tdb,
+ uint64_t hash, tdb_off_t off)
+{
+ tdb_off_t i, hoff, len, num;
+
+ /* Look for next space. */
+ i = (hash & ((1ULL << tdb->header.v.hash_bits) - 1));
+ len = (1ULL << tdb->header.v.hash_bits) - i;
+ num = tdb_find_zero_off(tdb, hash_off(tdb, i), len);
+
+ if (unlikely(num == len)) {
+ /* We wrapped. Look through start of hash table. */
+ hoff = hash_off(tdb, 0);
+ len = (1ULL << tdb->header.v.hash_bits);
+ num = tdb_find_zero_off(tdb, hoff, len);
+ if (i == len) {
+ tdb->ecode = TDB_ERR_CORRUPT;
+ tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
+ "hash_add: full hash table!\n");
+ return -1;
+ }
+ }
+ /* FIXME: Encode extra hash bits! */
+ return tdb_write_off(tdb, hash_off(tdb, i + num), off);
+}
+