0e1430265ccfe5722f5aef507822b5c5873db7e4
[kai/samba-autobuild/.git] / lib / tdb2 / test / run-25-hashoverload.c
1 #include "tdb2-source.h"
2 #include <ccan/tap/tap.h>
3 #include "logging.h"
4
5 static uint64_t badhash(const void *key, size_t len, uint64_t seed, void *priv)
6 {
7         return 0;
8 }
9
10 static int trav(struct tdb_context *tdb, TDB_DATA key, TDB_DATA dbuf, void *p)
11 {
12         if (p)
13                 return tdb_delete(tdb, key);
14         return 0;
15 }
16
17 int main(int argc, char *argv[])
18 {
19         unsigned int i, j;
20         struct tdb_context *tdb;
21         struct tdb_data key = { (unsigned char *)&j, sizeof(j) };
22         struct tdb_data dbuf = { (unsigned char *)&j, sizeof(j) };
23         union tdb_attribute hattr = { .hash = { .base = { TDB_ATTRIBUTE_HASH },
24                                                 .fn = badhash } };
25         int flags[] = { TDB_INTERNAL, TDB_DEFAULT, TDB_NOMMAP,
26                         TDB_INTERNAL|TDB_CONVERT, TDB_CONVERT,
27                         TDB_NOMMAP|TDB_CONVERT,
28         };
29
30         hattr.base.next = &tap_log_attr;
31
32         plan_tests(6883);
33         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
34                 struct tdb_data d = { NULL, 0 }; /* Bogus GCC warning */
35
36                 tdb = tdb_open("run-25-hashoverload.tdb", flags[i],
37                                O_RDWR|O_CREAT|O_TRUNC, 0600, &hattr);
38                 ok1(tdb);
39                 if (!tdb)
40                         continue;
41
42                 /* Fill a group. */
43                 for (j = 0; j < (1 << TDB_HASH_GROUP_BITS); j++) {
44                         ok1(tdb_store(tdb, key, dbuf, TDB_INSERT) == 0);
45                 }
46                 ok1(tdb_check(tdb, NULL, NULL) == 0);
47
48                 /* Now store one last value: should form chain. */
49                 ok1(tdb_store(tdb, key, dbuf, TDB_INSERT) == 0);
50                 ok1(tdb_check(tdb, NULL, NULL) == 0);
51
52                 /* Check we can find them all. */
53                 for (j = 0; j < (1 << TDB_HASH_GROUP_BITS) + 1; j++) {
54                         ok1(tdb_fetch(tdb, key, &d) == TDB_SUCCESS);
55                         ok1(d.dsize == sizeof(j));
56                         ok1(d.dptr != NULL);
57                         ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
58                         free(d.dptr);
59                 }
60
61                 /* Now add a *lot* more. */
62                 for (j = (1 << TDB_HASH_GROUP_BITS) + 1;
63                      j < (16 << TDB_HASH_GROUP_BITS);
64                      j++) {
65                         ok1(tdb_store(tdb, key, dbuf, TDB_INSERT) == 0);
66                         ok1(tdb_fetch(tdb, key, &d) == TDB_SUCCESS);
67                         ok1(d.dsize == sizeof(j));
68                         ok1(d.dptr != NULL);
69                         ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
70                         free(d.dptr);
71                 }
72                 ok1(tdb_check(tdb, NULL, NULL) == 0);
73
74                 /* Traverse through them. */
75                 ok1(tdb_traverse(tdb, trav, NULL) == j);
76
77                 /* Empty the first chain-worth. */
78                 for (j = 0; j < (1 << TDB_HASH_GROUP_BITS); j++)
79                         ok1(tdb_delete(tdb, key) == 0);
80
81                 ok1(tdb_check(tdb, NULL, NULL) == 0);
82
83                 for (j = (1 << TDB_HASH_GROUP_BITS);
84                      j < (16 << TDB_HASH_GROUP_BITS);
85                      j++) {
86                         ok1(tdb_fetch(tdb, key, &d) == TDB_SUCCESS);
87                         ok1(d.dsize == sizeof(j));
88                         ok1(d.dptr != NULL);
89                         ok1(d.dptr && memcmp(d.dptr, &j, d.dsize) == 0);
90                         free(d.dptr);
91                 }
92
93                 /* Traverse through them. */
94                 ok1(tdb_traverse(tdb, trav, NULL)
95                     == (15 << TDB_HASH_GROUP_BITS));
96
97                 /* Re-add */
98                 for (j = 0; j < (1 << TDB_HASH_GROUP_BITS); j++) {
99                         ok1(tdb_store(tdb, key, dbuf, TDB_INSERT) == 0);
100                 }
101                 ok1(tdb_check(tdb, NULL, NULL) == 0);
102
103                 /* Now try deleting as we go. */
104                 ok1(tdb_traverse(tdb, trav, trav)
105                     == (16 << TDB_HASH_GROUP_BITS));
106                 ok1(tdb_check(tdb, NULL, NULL) == 0);
107                 ok1(tdb_traverse(tdb, trav, NULL) == 0);
108                 tdb_close(tdb);
109         }
110
111         ok1(tap_log_messages == 0);
112         return exit_status();
113 }