]> git.ozlabs.org Git - ccan/blob - ccan/ntdb/test/run-30-exhaust-before-expand.c
bcf1c1f665567b461edcc65ee4d4ceb71c3a7019
[ccan] / ccan / ntdb / test / run-30-exhaust-before-expand.c
1 #include "ntdb-source.h"
2 #include "tap-interface.h"
3 #include "logging.h"
4
5 static bool empty_freetable(struct ntdb_context *ntdb)
6 {
7         struct ntdb_freetable ftab;
8         unsigned int i;
9
10         /* Now, free table should be completely exhausted in zone 0 */
11         if (ntdb_read_convert(ntdb, ntdb->ftable_off, &ftab, sizeof(ftab)) != 0)
12                 abort();
13
14         for (i = 0; i < sizeof(ftab.buckets)/sizeof(ftab.buckets[0]); i++) {
15                 if (ftab.buckets[i])
16                         return false;
17         }
18         return true;
19 }
20
21
22 int main(int argc, char *argv[])
23 {
24         unsigned int i, j;
25         struct ntdb_context *ntdb;
26         int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
27                         NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
28                         NTDB_NOMMAP|NTDB_CONVERT };
29
30         plan_tests(sizeof(flags) / sizeof(flags[0]) * 7 + 1);
31
32         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
33                 NTDB_DATA k, d;
34                 uint64_t size;
35                 bool was_empty = false;
36
37                 k.dptr = (void *)&j;
38                 k.dsize = sizeof(j);
39
40                 ntdb = ntdb_open("run-30-exhaust-before-expand.ntdb",
41                                  flags[i]|MAYBE_NOSYNC,
42                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
43                 ok1(ntdb);
44                 if (!ntdb)
45                         continue;
46
47                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
48                 /* There's one empty record in initial db. */
49                 ok1(!empty_freetable(ntdb));
50
51                 size = ntdb->file->map_size;
52
53                 /* Create one record to chew up most space. */
54                 d.dsize = size - NEW_DATABASE_HDR_SIZE(ntdb->hash_bits) - 32;
55                 d.dptr = calloc(d.dsize, 1);
56                 j = 0;
57                 ok1(ntdb_store(ntdb, k, d, NTDB_INSERT) == 0);
58                 ok1(ntdb->file->map_size == size);
59                 free(d.dptr);
60
61                 /* Now insert minimal-length records until we expand. */
62                 for (j = 1; ntdb->file->map_size == size; j++) {
63                         was_empty = empty_freetable(ntdb);
64                         if (ntdb_store(ntdb, k, k, NTDB_INSERT) != 0)
65                                 err(1, "Failed to store record %i", j);
66                 }
67
68                 /* Would have been empty before expansion, but no longer. */
69                 ok1(was_empty);
70                 ok1(!empty_freetable(ntdb));
71                 ntdb_close(ntdb);
72         }
73
74         ok1(tap_log_messages == 0);
75         return exit_status();
76 }