+/* Subtract 1-byte tailer and header. Then round up to next power of 2. */
+static unsigned max_zone_bits(struct tdb_context *tdb)
+{
+ return fls64(tdb->map_size-1-sizeof(struct tdb_header)-1) + 1;
+}
+
+/* Start by using a random zone to spread the load: returns the offset. */
+static uint64_t random_zone(struct tdb_context *tdb)
+{
+ struct free_zone_header zhdr;
+ tdb_off_t off = sizeof(struct tdb_header);
+ tdb_len_t half_bits;
+ uint64_t randbits = 0;
+ unsigned int i;
+
+ for (i = 0; i < 64; i += fls64(RAND_MAX))
+ randbits ^= ((uint64_t)random()) << i;
+
+ /* FIXME: Does this work? Test! */
+ half_bits = max_zone_bits(tdb) - 1;
+ do {
+ /* Pick left or right side (not outside file) */
+ if ((randbits & 1)
+ && !tdb->methods->oob(tdb, off + (1ULL << half_bits)
+ + sizeof(zhdr), true)) {
+ off += 1ULL << half_bits;
+ }
+ randbits >>= 1;
+
+ if (tdb_read_convert(tdb, off, &zhdr, sizeof(zhdr)) == -1)
+ return TDB_OFF_ERR;
+
+ if (zhdr.zone_bits == half_bits)
+ return off;
+
+ half_bits--;
+ } while (half_bits >= INITIAL_ZONE_BITS);
+
+ tdb->ecode = TDB_ERR_CORRUPT;
+ tdb->log(tdb, TDB_DEBUG_FATAL, tdb->log_priv,
+ "random_zone: zone at %llu smaller than %u bits?",
+ (long long)off, INITIAL_ZONE_BITS);
+ return TDB_OFF_ERR;
+}
+
+int tdb_zone_init(struct tdb_context *tdb)