1 #include <ccan/tdb2/tdb.c>
2 #include <ccan/tdb2/open.c>
3 #include <ccan/tdb2/free.c>
4 #include <ccan/tdb2/lock.c>
5 #include <ccan/tdb2/io.c>
6 #include <ccan/tdb2/check.c>
7 #include <ccan/tdb2/hash.c>
8 #include <ccan/tdb2/transaction.c>
9 #include <ccan/tap/tap.h>
13 static bool empty_freetable(struct tdb_context
*tdb
)
15 struct tdb_freetable ftab
;
18 /* Now, free table should be completely exhausted in zone 0 */
19 if (tdb_read_convert(tdb
, tdb
->ftable_off
, &ftab
, sizeof(ftab
)) != 0)
22 for (i
= 0; i
< sizeof(ftab
.buckets
)/sizeof(ftab
.buckets
[0]); i
++) {
30 int main(int argc
, char *argv
[])
33 struct tdb_context
*tdb
;
34 int flags
[] = { TDB_INTERNAL
, TDB_DEFAULT
, TDB_NOMMAP
,
35 TDB_INTERNAL
|TDB_CONVERT
, TDB_CONVERT
,
36 TDB_NOMMAP
|TDB_CONVERT
};
38 plan_tests(sizeof(flags
) / sizeof(flags
[0]) * 9 + 1);
40 for (i
= 0; i
< sizeof(flags
) / sizeof(flags
[0]); i
++) {
43 bool was_empty
= false;
48 tdb
= tdb_open("run-30-exhaust-before-expand.tdb", flags
[i
],
49 O_RDWR
|O_CREAT
|O_TRUNC
, 0600, &tap_log_attr
);
54 ok1(empty_freetable(tdb
));
55 /* Need some hash lock for expand. */
56 ok1(tdb_lock_hashes(tdb
, 0, 1, F_WRLCK
, TDB_LOCK_WAIT
) == 0);
57 /* Create some free space. */
58 ok1(tdb_expand(tdb
, 1) == 0);
59 ok1(tdb_unlock_hashes(tdb
, 0, 1, F_WRLCK
) == 0);
60 ok1(tdb_check(tdb
, NULL
, NULL
) == 0);
61 ok1(!empty_freetable(tdb
));
63 size
= tdb
->file
->map_size
;
64 /* Insert minimal-length records until we expand. */
65 for (j
= 0; tdb
->file
->map_size
== size
; j
++) {
66 was_empty
= empty_freetable(tdb
);
67 if (tdb_store(tdb
, k
, k
, TDB_INSERT
) != 0)
68 err(1, "Failed to store record %i", j
);
71 /* Would have been empty before expansion, but no longer. */
73 ok1(!empty_freetable(tdb
));
77 ok1(tap_log_messages
== 0);