]> git.ozlabs.org Git - ccan/blob - ccan/ntdb/test/run-15-append.c
05fa594b6b52c97937d5f490092f2ee5d3774214
[ccan] / ccan / ntdb / test / run-15-append.c
1 #include "ntdb-source.h"
2 #include "tap-interface.h"
3 #include <ccan/ilog/ilog.h>
4 #include "logging.h"
5
6 #define MAX_SIZE 13100
7 #define SIZE_STEP 131
8
9 static ntdb_off_t ntdb_offset(struct ntdb_context *ntdb, NTDB_DATA key)
10 {
11         ntdb_off_t off;
12         struct ntdb_used_record urec;
13         struct hash_info h;
14
15         off = find_and_lock(ntdb, key, F_RDLCK, &h, &urec, NULL);
16         if (NTDB_OFF_IS_ERR(off))
17                 return 0;
18         ntdb_unlock_hash(ntdb, h.h, F_RDLCK);
19         return off;
20 }
21
22 int main(int argc, char *argv[])
23 {
24         unsigned int i, j, moves;
25         struct ntdb_context *ntdb;
26         unsigned char *buffer;
27         ntdb_off_t oldoff = 0, newoff;
28         int flags[] = { NTDB_INTERNAL, NTDB_DEFAULT, NTDB_NOMMAP,
29                         NTDB_INTERNAL|NTDB_CONVERT, NTDB_CONVERT,
30                         NTDB_NOMMAP|NTDB_CONVERT };
31         NTDB_DATA key = ntdb_mkdata("key", 3);
32         NTDB_DATA data;
33
34         buffer = malloc(MAX_SIZE);
35         for (i = 0; i < MAX_SIZE; i++)
36                 buffer[i] = i;
37
38         plan_tests(sizeof(flags) / sizeof(flags[0])
39                    * ((3 + MAX_SIZE/SIZE_STEP * 5) * 2 + 7)
40                    + 1);
41
42         /* Using ntdb_store. */
43         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
44                 ntdb = ntdb_open("run-append.ntdb", flags[i]|MAYBE_NOSYNC,
45                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
46                 ok1(ntdb);
47                 if (!ntdb)
48                         continue;
49
50                 moves = 0;
51                 for (j = 0; j < MAX_SIZE; j += SIZE_STEP) {
52                         data.dptr = buffer;
53                         data.dsize = j;
54                         ok1(ntdb_store(ntdb, key, data, NTDB_REPLACE) == 0);
55                         ok1(ntdb_check(ntdb, NULL, NULL) == 0);
56                         ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
57                         ok1(data.dsize == j);
58                         ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
59                         free(data.dptr);
60                         newoff = ntdb_offset(ntdb, key);
61                         if (newoff != oldoff)
62                                 moves++;
63                         oldoff = newoff;
64                 }
65                 ok1(!ntdb->file || (ntdb->file->allrecord_lock.count == 0
66                                    && ntdb->file->num_lockrecs == 0));
67                 /* We should increase by 50% each time... */
68                 ok(moves <= ilog64(j / SIZE_STEP)*2,
69                    "Moved %u times", moves);
70                 ntdb_close(ntdb);
71         }
72
73         /* Using ntdb_append. */
74         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
75                 size_t prev_len = 0;
76                 ntdb = ntdb_open("run-append.ntdb", flags[i]|MAYBE_NOSYNC,
77                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
78                 ok1(ntdb);
79                 if (!ntdb)
80                         continue;
81
82                 moves = 0;
83                 for (j = 0; j < MAX_SIZE; j += SIZE_STEP) {
84                         data.dptr = buffer + prev_len;
85                         data.dsize = j - prev_len;
86                         ok1(ntdb_append(ntdb, key, data) == 0);
87                         ok1(ntdb_check(ntdb, NULL, NULL) == 0);
88                         ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
89                         ok1(data.dsize == j);
90                         ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
91                         free(data.dptr);
92                         prev_len = data.dsize;
93                         newoff = ntdb_offset(ntdb, key);
94                         if (newoff != oldoff)
95                                 moves++;
96                         oldoff = newoff;
97                 }
98                 ok1(!ntdb->file || (ntdb->file->allrecord_lock.count == 0
99                                    && ntdb->file->num_lockrecs == 0));
100                 /* We should increase by 50% each time... */
101                 ok(moves <= ilog64(j / SIZE_STEP)*2,
102                    "Moved %u times", moves);
103                 ntdb_close(ntdb);
104         }
105
106         for (i = 0; i < sizeof(flags) / sizeof(flags[0]); i++) {
107                 ntdb = ntdb_open("run-append.ntdb", flags[i]|MAYBE_NOSYNC,
108                                  O_RDWR|O_CREAT|O_TRUNC, 0600, &tap_log_attr);
109                 ok1(ntdb);
110                 if (!ntdb)
111                         continue;
112
113                 /* Huge initial store. */
114                 data.dptr = buffer;
115                 data.dsize = MAX_SIZE;
116                 ok1(ntdb_append(ntdb, key, data) == 0);
117                 ok1(ntdb_check(ntdb, NULL, NULL) == 0);
118                 ok1(ntdb_fetch(ntdb, key, &data) == NTDB_SUCCESS);
119                 ok1(data.dsize == MAX_SIZE);
120                 ok1(memcmp(data.dptr, buffer, data.dsize) == 0);
121                 free(data.dptr);
122                 ok1(!ntdb->file || (ntdb->file->allrecord_lock.count == 0
123                                    && ntdb->file->num_lockrecs == 0));
124                 ntdb_close(ntdb);
125         }
126
127         ok1(tap_log_messages == 0);
128         free(buffer);
129         return exit_status();
130 }