]> git.ozlabs.org Git - ccan/blob - ccan/ntdb/test/run-25-hashoverload.c
ntdb: next-generation trivial key-value database
[ccan] / ccan / ntdb / test / run-25-hashoverload.c
1 #include "ntdb-source.h"
2 #include "tap-interface.h"
3 #include "logging.h"
4
5 #define OVERLOAD 100
6
7 static uint32_t badhash(const void *key, size_t len, uint32_t seed, void *priv)
8 {
9         return 0;
10 }
11
12 static int trav(struct ntdb_context *ntdb, NTDB_DATA key, NTDB_DATA dbuf, void *p)
13 {
14         if (p)
15                 return ntdb_delete(ntdb, key);
16         return 0;
17 }
18
19 int main(int argc, char *argv[])
20 {
21         unsigned int i, j;
22         struct ntdb_context *ntdb;
23         NTDB_DATA key = { (unsigned char *)&j, sizeof(j) };
24         NTDB_DATA dbuf = { (unsigned char *)&j, sizeof(j) };
25         union ntdb_attribute hattr = { .hash = { .base = { NTDB_ATTRIBUTE_HASH },
26                                                 .fn = badhash } };
27         int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
28                         NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
29                         NTDB_NOMMAP|NTDB_CONVERT,
30         };
31
32         hattr.base.next = &tap_log_attr;
33
34         plan_tests(sizeof(flags) / sizeof(flags[0]) * (7 * OVERLOAD + 11) + 1);
35         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
36                 NTDB_DATA d = { NULL, 0 }; /* Bogus GCC warning */
37
38                 ntdb = ntdb_open("run-25-hashoverload.ntdb",
39                                  flags[i]|MAYBE_NOSYNC,
40                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr);
41                 ok1(ntdb);
42                 if (!ntdb)
43                         continue;
44
45                 /* Overload a bucket. */
46                 for (j = 0; j < OVERLOAD; j++) {
47                         ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
48                 }
49                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
50
51                 /* Check we can find them all. */
52                 for (j = 0; j < OVERLOAD; j++) {
53                         ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
54                         ok1(d.dsize == sizeof(j));
55                         ok1(d.dptr != NULL);
56                         ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
57                         free(d.dptr);
58                 }
59
60                 /* Traverse through them. */
61                 ok1(ntdb_traverse(ntdb, trav, NULL) == OVERLOAD);
62
63                 /* Delete the first 99. */
64                 for (j = 0; j < OVERLOAD-1; j++)
65                         ok1(ntdb_delete(ntdb, key) == 0);
66
67                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
68
69                 ok1(ntdb_fetch(ntdb, key, &d) == NTDB_SUCCESS);
70                 ok1(d.dsize == sizeof(j));
71                 ok1(d.dptr != NULL);
72                 ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
73                 free(d.dptr);
74
75                 /* Traverse through them. */
76                 ok1(ntdb_traverse(ntdb, trav, NULL) == 1);
77
78                 /* Re-add */
79                 for (j = 0; j < OVERLOAD-1; j++) {
80                         ok1(ntdb_store(ntdb, key, dbuf, NTDB_INSERT) == 0);
81                 }
82                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
83
84                 /* Now try deleting as we go. */
85                 ok1(ntdb_traverse(ntdb, trav, trav) == OVERLOAD);
86                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
87                 ok1(ntdb_traverse(ntdb, trav, NULL) == 0);
88                 ntdb_close(ntdb);
89         }
90
91         ok1(tap_log_messages == 0);
92         return exit_status();
93 }