]> git.ozlabs.org Git - ccan/blob - ccan/tdb2/test/run-03-coalesce.c
tdb2: get rid of zones
[ccan] / ccan / tdb2 / test / run-03-coalesce.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/hash.c>
6 #include <ccan/tdb2/check.c>
7 #include <ccan/tap/tap.h>
8 #include "logging.h"
9 #include "layout.h"
10
11 static tdb_len_t free_record_length(struct tdb_context *tdb, tdb_off_t off)
12 {
13         struct tdb_free_record f;
14
15         if (tdb_read_convert(tdb, off, &f, sizeof(f)) != 0)
16                 return TDB_OFF_ERR;
17         if (frec_magic(&f) != TDB_FREE_MAGIC)
18                 return TDB_OFF_ERR;
19         return f.data_len;
20 }
21
22 int main(int argc, char *argv[])
23 {
24         tdb_off_t b_off;
25         struct tdb_context *tdb;
26         struct tdb_layout *layout;
27         struct tdb_data data, key;
28         tdb_len_t len;
29
30         /* FIXME: Test TDB_CONVERT */
31
32         plan_tests(38);
33         data.dptr = (void *)"world";
34         data.dsize = 5;
35         key.dptr = (void *)"hello";
36         key.dsize = 5;
37
38         /* No coalescing can be done due to EOF */
39         layout = new_tdb_layout(NULL);
40         tdb_layout_add_freelist(layout);
41         len = 1024;
42         tdb_layout_add_free(layout, len);
43         tdb = tdb_layout_get(layout);
44         ok1(tdb_check(tdb, NULL, NULL) == 0);
45         ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
46
47         /* Figure out which bucket free entry is. */
48         b_off = bucket_off(tdb->flist_off, size_to_bucket(len));
49         /* Lock and fail to coalesce. */
50         ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
51         ok1(coalesce(tdb, layout->elem[1].base.off, b_off, len) == 0);
52         tdb_unlock_free_bucket(tdb, b_off);
53         ok1(free_record_length(tdb, layout->elem[1].base.off) == len);
54         ok1(tdb_check(tdb, NULL, NULL) == 0);
55         tdb_close(tdb);
56
57         /* No coalescing can be done due to used record */
58         layout = new_tdb_layout(NULL);
59         tdb_layout_add_freelist(layout);
60         tdb_layout_add_free(layout, 1024);
61         tdb_layout_add_used(layout, key, data, 6);
62         tdb = tdb_layout_get(layout);
63         ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
64         ok1(tdb_check(tdb, NULL, NULL) == 0);
65
66         /* Figure out which bucket free entry is. */
67         b_off = bucket_off(tdb->flist_off, size_to_bucket(1024));
68         /* Lock and fail to coalesce. */
69         ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
70         ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 0);
71         tdb_unlock_free_bucket(tdb, b_off);
72         ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
73         ok1(tdb_check(tdb, NULL, NULL) == 0);
74         tdb_close(tdb);
75
76         /* Coalescing can be done due to two free records, then EOF */
77         layout = new_tdb_layout(NULL);
78         tdb_layout_add_freelist(layout);
79         tdb_layout_add_free(layout, 1024);
80         tdb_layout_add_free(layout, 2048);
81         tdb = tdb_layout_get(layout);
82         ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
83         ok1(free_record_length(tdb, layout->elem[2].base.off) == 2048);
84         ok1(tdb_check(tdb, NULL, NULL) == 0);
85
86         /* Figure out which bucket (first) free entry is. */
87         b_off = bucket_off(tdb->flist_off, size_to_bucket(1024));
88         /* Lock and coalesce. */
89         ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
90         ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
91         ok1(!tdb_has_locks(tdb));
92         ok1(free_record_length(tdb, layout->elem[1].base.off)
93             == 1024 + sizeof(struct tdb_used_record) + 2048);
94         ok1(tdb_check(tdb, NULL, NULL) == 0);
95         tdb_close(tdb);
96
97         /* Coalescing can be done due to two free records, then data */
98         layout = new_tdb_layout(NULL);
99         tdb_layout_add_freelist(layout);
100         tdb_layout_add_free(layout, 1024);
101         tdb_layout_add_free(layout, 512);
102         tdb_layout_add_used(layout, key, data, 6);
103         tdb = tdb_layout_get(layout);
104         ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
105         ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
106         ok1(tdb_check(tdb, NULL, NULL) == 0);
107
108         /* Figure out which bucket free entry is. */
109         b_off = bucket_off(tdb->flist_off, size_to_bucket(1024));
110         /* Lock and coalesce. */
111         ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
112         ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
113         ok1(!tdb_has_locks(tdb));
114         ok1(free_record_length(tdb, layout->elem[1].base.off)
115             == 1024 + sizeof(struct tdb_used_record) + 512);
116         ok1(tdb_check(tdb, NULL, NULL) == 0);
117         tdb_close(tdb);
118
119         /* Coalescing can be done due to three free records, then EOF */
120         layout = new_tdb_layout(NULL);
121         tdb_layout_add_freelist(layout);
122         tdb_layout_add_free(layout, 1024);
123         tdb_layout_add_free(layout, 512);
124         tdb_layout_add_free(layout, 256);
125         tdb = tdb_layout_get(layout);
126         ok1(free_record_length(tdb, layout->elem[1].base.off) == 1024);
127         ok1(free_record_length(tdb, layout->elem[2].base.off) == 512);
128         ok1(free_record_length(tdb, layout->elem[3].base.off) == 256);
129         ok1(tdb_check(tdb, NULL, NULL) == 0);
130
131         /* Figure out which bucket free entry is. */
132         b_off = bucket_off(tdb->flist_off, size_to_bucket(1024));
133         /* Lock and coalesce. */
134         ok1(tdb_lock_free_bucket(tdb, b_off, TDB_LOCK_WAIT) == 0);
135         ok1(coalesce(tdb, layout->elem[1].base.off, b_off, 1024) == 1);
136         ok1(!tdb_has_locks(tdb));
137         ok1(free_record_length(tdb, layout->elem[1].base.off)
138             == 1024 + sizeof(struct tdb_used_record) + 512
139             + sizeof(struct tdb_used_record) + 256);
140         ok1(tdb_check(tdb, NULL, NULL) == 0);
141         tdb_close(tdb);
142
143         ok1(tap_log_messages == 0);
144         return exit_status();
145 }