tdb2: get rid of zones
[ccan] / ccan / tdb2 / test / run-30-exhaust-before-expand.c
1 #include <ccan/tdb2/tdb.c>
2 #include <ccan/tdb2/free.c>
3 #include <ccan/tdb2/lock.c>
4 #include <ccan/tdb2/io.c>
5 #include <ccan/tdb2/check.c>
6 #include <ccan/tdb2/hash.c>
7 #include <ccan/tap/tap.h>
8 #include <err.h>
9 #include "logging.h"
10
11 static bool empty_freelist(struct tdb_context *tdb)
12 {
13         struct tdb_freelist free;
14         unsigned int i;
15
16         /* Now, free list should be completely exhausted in zone 0 */
17         if (tdb_read_convert(tdb, tdb->flist_off, &free, sizeof(free)) != 0)
18                 abort();
19
20         for (i = 0; i < sizeof(free.buckets)/sizeof(free.buckets[0]); i++) {
21                 if (free.buckets[i])
22                         return false;
23         }
24         return true;
25 }
26
27
28 int main(int argc, char *argv[])
29 {
30         unsigned int i, j;
31         struct tdb_context *tdb;
32         int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
33                         TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
34                         TDB_NOMMAP|TDB_CONVERT };
35
36         plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1);
37
38         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
39                 TDB_DATA k;
40                 uint64_t size;
41                 bool was_empty = false;
42
43                 k.dptr = (void *)&j;
44                 k.dsize = sizeof(j);
45
46                 tdb = tdb_open("run-30-exhaust-before-expand.tdb", flags[i],
47                                O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
48                 ok1(tdb);
49                 if (!tdb)
50                         continue;
51
52                 ok1(empty_freelist(tdb));
53                 /* Create some free space. */
54                 ok1(tdb_expand(tdb, 1) == 0);
55                 ok1(tdb_check(tdb, NULL, NULL) == 0);
56                 ok1(!empty_freelist(tdb));
57
58                 size = tdb->map_size;
59                 /* Insert minimal-length records until we expand. */
60                 for (j = 0; tdb->map_size == size; j++) {
61                         was_empty = empty_freelist(tdb);
62                         if (tdb_store(tdb, k, k, TDB_INSERT) != 0)
63                                 err(1, "Failed to store record %i", j);
64                 }
65
66                 /* Would have been empty before expansion, but no longer. */
67                 ok1(was_empty);
68                 ok1(!empty_freelist(tdb));
69                 tdb_close(tdb);
70         }
71
72         ok1(tap_log_messages == 0);
73         return exit_status();
74 }