sophia-ruby 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (62) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +17 -0
  3. data/.gitmodules +3 -0
  4. data/Gemfile +6 -0
  5. data/LICENSE.txt +22 -0
  6. data/README.md +29 -0
  7. data/Rakefile +22 -0
  8. data/ext/extconf.rb +13 -0
  9. data/ext/sophia.c +220 -0
  10. data/lib/sophia-ruby.rb +1 -0
  11. data/lib/sophia/version.rb +3 -0
  12. data/sophia-ruby.gemspec +47 -0
  13. data/test/test_sophia.rb +33 -0
  14. data/vendor/sophia/.gitignore +18 -0
  15. data/vendor/sophia/COPYRIGHT +29 -0
  16. data/vendor/sophia/README +5 -0
  17. data/vendor/sophia/db/a.h +58 -0
  18. data/vendor/sophia/db/cat.c +195 -0
  19. data/vendor/sophia/db/cat.h +32 -0
  20. data/vendor/sophia/db/core.h +129 -0
  21. data/vendor/sophia/db/crc.c +343 -0
  22. data/vendor/sophia/db/crc.h +14 -0
  23. data/vendor/sophia/db/cursor.c +551 -0
  24. data/vendor/sophia/db/cursor.h +47 -0
  25. data/vendor/sophia/db/e.c +49 -0
  26. data/vendor/sophia/db/e.h +49 -0
  27. data/vendor/sophia/db/file.c +355 -0
  28. data/vendor/sophia/db/file.h +106 -0
  29. data/vendor/sophia/db/gc.c +71 -0
  30. data/vendor/sophia/db/gc.h +14 -0
  31. data/vendor/sophia/db/i.c +368 -0
  32. data/vendor/sophia/db/i.h +155 -0
  33. data/vendor/sophia/db/list.h +91 -0
  34. data/vendor/sophia/db/lock.h +77 -0
  35. data/vendor/sophia/db/macro.h +20 -0
  36. data/vendor/sophia/db/makefile +44 -0
  37. data/vendor/sophia/db/merge.c +662 -0
  38. data/vendor/sophia/db/merge.h +14 -0
  39. data/vendor/sophia/db/meta.h +87 -0
  40. data/vendor/sophia/db/recover.c +433 -0
  41. data/vendor/sophia/db/recover.h +14 -0
  42. data/vendor/sophia/db/ref.h +111 -0
  43. data/vendor/sophia/db/rep.c +128 -0
  44. data/vendor/sophia/db/rep.h +120 -0
  45. data/vendor/sophia/db/sophia.h +84 -0
  46. data/vendor/sophia/db/sp.c +626 -0
  47. data/vendor/sophia/db/sp.h +50 -0
  48. data/vendor/sophia/db/task.h +70 -0
  49. data/vendor/sophia/db/track.h +99 -0
  50. data/vendor/sophia/db/util.c +105 -0
  51. data/vendor/sophia/db/util.h +25 -0
  52. data/vendor/sophia/makefile +7 -0
  53. data/vendor/sophia/sophia.gyp +30 -0
  54. data/vendor/sophia/test/common.c +870 -0
  55. data/vendor/sophia/test/crash.c +492 -0
  56. data/vendor/sophia/test/i.c +403 -0
  57. data/vendor/sophia/test/limit.c +65 -0
  58. data/vendor/sophia/test/makefile +30 -0
  59. data/vendor/sophia/test/merge.c +890 -0
  60. data/vendor/sophia/test/recover.c +1550 -0
  61. data/vendor/sophia/test/test.h +66 -0
  62. metadata +134 -0
@@ -0,0 +1,492 @@
1
+
2
+ /*
3
+ * sophia database
4
+ * sphia.org
5
+ *
6
+ * Copyright (c) Dmitry Simonenko
7
+ * BSD License
8
+ */
9
+
10
+ #include <unistd.h>
11
+ #include <fcntl.h>
12
+ #include <sophia.h>
13
+ #include <sp.h>
14
+ #include "test.h"
15
+
16
+ static char *dbrep = "./rep";
17
+ static spa a;
18
+
19
+ static inline int
20
+ cmp(char *a, size_t asz, char *b, size_t bsz, void *arg) {
21
+ register uint32_t av = *(uint32_t*)a;
22
+ register uint32_t bv = *(uint32_t*)b;
23
+ if (av == bv)
24
+ return 0;
25
+ return (av > bv) ? 1 : -1;
26
+ }
27
+
28
+ static void
29
+ log_empty(void) {
30
+ spfile f;
31
+ sp_fileinit(&f, &a);
32
+ t( mkdir(dbrep, 0755) == 0 );
33
+ t( sp_lognew(&f, dbrep, 1) == 0 );
34
+ t( sp_logcomplete(&f) == 0 );
35
+ t( sp_logclose(&f) == 0 );
36
+ t( exists(dbrep, 1, "log") == 1 );
37
+ void *env = sp_env();
38
+ t( env != NULL );
39
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
40
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
41
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
42
+ void *db = sp_open(env);
43
+ t( db == NULL );
44
+ t( sp_error(env) != NULL );
45
+ t( sp_destroy(env) == 0 );
46
+ t( rmrf(dbrep) == 0 );
47
+ }
48
+
49
+ static void
50
+ log_empty_incomplete(void) {
51
+ spfile f;
52
+ sp_fileinit(&f, &a);
53
+ t( mkdir(dbrep, 0755) == 0 );
54
+ t( sp_lognew(&f, dbrep, 1) == 0 );
55
+ t( sp_logclose(&f) == 0 );
56
+ t( exists(dbrep, 1, "log.incomplete") == 1 );
57
+ void *env = sp_env();
58
+ t( env != NULL );
59
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
60
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
61
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
62
+ void *db = sp_open(env);
63
+ t( db == NULL );
64
+ t( sp_error(env) != NULL );
65
+ t( sp_destroy(env) == 0 );
66
+ t( rmrf(dbrep) == 0 );
67
+ }
68
+
69
+ static void
70
+ log_badrecord(void) {
71
+ uint32_t k = 123;
72
+ splogh h = {
73
+ .magic = SPMAGIC,
74
+ .version[0] = SP_VERSION_MAJOR,
75
+ .version[1] = SP_VERSION_MINOR
76
+ };
77
+ spvh vh = {
78
+ .crc = 0,
79
+ .size = sizeof(uint32_t),
80
+ .voffset = 0,
81
+ .vsize = sizeof(uint32_t),
82
+ .flags = SPSET
83
+ };
84
+ speofh eof = { SPEOF };
85
+ spfile f;
86
+ sp_fileinit(&f, &a);
87
+ t( mkdir(dbrep, 0755) == 0 );
88
+ t( sp_lognew(&f, dbrep, 1) == 0 );
89
+ sp_logadd(&f, &h, sizeof(h));
90
+ sp_logadd(&f, &vh, sizeof(vh));
91
+ sp_logadd(&f, &k, sizeof(k));
92
+ sp_logadd(&f, &k, sizeof(k));
93
+ sp_logadd(&f, &eof, sizeof(eof));
94
+ t( sp_logflush(&f) == 0 );
95
+ t( sp_logcomplete(&f) == 0 );
96
+ t( sp_logclose(&f) == 0 );
97
+ t( exists(dbrep, 1, "log") == 1 );
98
+ void *env = sp_env();
99
+ t( env != NULL );
100
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
101
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
102
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
103
+ void *db = sp_open(env);
104
+ t( db == NULL );
105
+ t( sp_error(env) != NULL );
106
+ t( sp_destroy(env) == 0 );
107
+ t( rmrf(dbrep) == 0 );
108
+ }
109
+
110
+ static void
111
+ log_badrecord_incomplete(void) {
112
+ uint32_t k = 123;
113
+ splogh h = {
114
+ .magic = SPMAGIC,
115
+ .version[0] = SP_VERSION_MAJOR,
116
+ .version[1] = SP_VERSION_MINOR
117
+ };
118
+ spvh vh = {
119
+ .crc = 0,
120
+ .size = sizeof(uint32_t),
121
+ .voffset = 0,
122
+ .vsize = sizeof(uint32_t),
123
+ .flags = SPSET
124
+ };
125
+ speofh eof = { SPEOF };
126
+ spfile f;
127
+ sp_fileinit(&f, &a);
128
+ t( mkdir(dbrep, 0755) == 0 );
129
+ t( sp_lognew(&f, dbrep, 1) == 0 );
130
+ sp_logadd(&f, &h, sizeof(h));
131
+ sp_logadd(&f, &vh, sizeof(vh));
132
+ sp_logadd(&f, &k, sizeof(k));
133
+ sp_logadd(&f, &k, sizeof(k));
134
+ sp_logadd(&f, &eof, sizeof(eof));
135
+ t( sp_logflush(&f) == 0 );
136
+ t( sp_logclose(&f) == 0 );
137
+ t( exists(dbrep, 1, "log.incomplete") == 1 );
138
+ void *env = sp_env();
139
+ t( env != NULL );
140
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
141
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
142
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
143
+ void *db = sp_open(env);
144
+ t( db == NULL );
145
+ t( sp_error(env) != NULL );
146
+ t( sp_destroy(env) == 0 );
147
+ t( exists(dbrep, 1, "log.incomplete") == 1 );
148
+ t( rmrf(dbrep) == 0 );
149
+ }
150
+
151
+ static void
152
+ log_1_badrecord_2_goodrecord(void) {
153
+ uint32_t k = 123;
154
+ void *env = sp_env();
155
+ t( env != NULL );
156
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
157
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
158
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
159
+ void *db = sp_open(env);
160
+ t( db != NULL );
161
+ t( sp_set(db, &k, sizeof(k), &k, sizeof(k)) == 0 );
162
+ t( sp_destroy(db) == 0 );
163
+ t( exists(dbrep, 1, "log") == 1 );
164
+ splogh h = {
165
+ .magic = SPMAGIC,
166
+ .version[0] = SP_VERSION_MAJOR,
167
+ .version[1] = SP_VERSION_MINOR
168
+ };
169
+ spvh vh = {
170
+ .crc = 0,
171
+ .size = sizeof(uint32_t),
172
+ .voffset = 0,
173
+ .vsize = sizeof(uint32_t),
174
+ .flags = SPSET
175
+ };
176
+ speofh eof = { SPEOF };
177
+ spfile f;
178
+ sp_fileinit(&f, &a);
179
+ t( sp_lognew(&f, dbrep, 2) == 0 );
180
+ sp_logadd(&f, &h, sizeof(h));
181
+ sp_logadd(&f, &vh, sizeof(vh));
182
+ sp_logadd(&f, &k, sizeof(k));
183
+ sp_logadd(&f, &k, sizeof(k));
184
+ sp_logadd(&f, &eof, sizeof(eof));
185
+ t( sp_logflush(&f) == 0 );
186
+ t( sp_logcomplete(&f) == 0 );
187
+ t( sp_logclose(&f) == 0 );
188
+ t( exists(dbrep, 2, "log") == 1 );
189
+ db = sp_open(env);
190
+ t( db == NULL );
191
+ t( sp_destroy(env) == 0 );
192
+ t( exists(dbrep, 1, "log") == 1 );
193
+ t( exists(dbrep, 2, "log") == 1 );
194
+ t( rmrf(dbrep) == 0 );
195
+ }
196
+
197
+ static void
198
+ log_noeof(void) {
199
+ uint32_t k = 123;
200
+ splogh h = {
201
+ .magic = SPMAGIC,
202
+ .version[0] = SP_VERSION_MAJOR,
203
+ .version[1] = SP_VERSION_MINOR
204
+ };
205
+ spvh vh = {
206
+ .crc = 0,
207
+ .size = sizeof(uint32_t),
208
+ .voffset = 0,
209
+ .vsize = sizeof(uint32_t),
210
+ .flags = SPSET
211
+ };
212
+ uint32_t crc;
213
+ crc = sp_crc32c(0, &k, sizeof(k));
214
+ crc = sp_crc32c(crc, &k, sizeof(k));
215
+ vh.crc = sp_crc32c(crc, &vh.size, sizeof(spvh) - sizeof(uint32_t));
216
+ spfile f;
217
+ sp_fileinit(&f, &a);
218
+ t( mkdir(dbrep, 0755) == 0 );
219
+ t( sp_lognew(&f, dbrep, 1) == 0 );
220
+ sp_logadd(&f, &h, sizeof(h));
221
+ sp_logadd(&f, &vh, sizeof(vh));
222
+ sp_logadd(&f, &k, sizeof(k));
223
+ sp_logadd(&f, &k, sizeof(k));
224
+ t( sp_logflush(&f) == 0 );
225
+ t( sp_logclose(&f) == 0 );
226
+ t( exists(dbrep, 1, "log.incomplete") == 1 );
227
+ void *env = sp_env();
228
+ t( env != NULL );
229
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
230
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
231
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
232
+ void *db = sp_open(env);
233
+ t( db != NULL );
234
+ size_t vsize = 0;
235
+ void *vp = NULL;
236
+ t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 1 );
237
+ t( vsize == sizeof(k) );
238
+ t( *(uint32_t*)vp == k );
239
+ free(vp);
240
+ t( sp_destroy(db) == 0 );
241
+ t( sp_destroy(env) == 0 );
242
+ t( rmrf(dbrep) == 0 );
243
+ }
244
+
245
+ static void
246
+ log_noeof_complete(void) {
247
+ uint32_t k = 123;
248
+ splogh h = {
249
+ .magic = SPMAGIC,
250
+ .version[0] = SP_VERSION_MAJOR,
251
+ .version[1] = SP_VERSION_MINOR
252
+ };
253
+ spvh vh = {
254
+ .crc = 0,
255
+ .size = sizeof(uint32_t),
256
+ .voffset = 0,
257
+ .vsize = sizeof(uint32_t),
258
+ .flags = SPSET
259
+ };
260
+ uint32_t crc;
261
+ crc = sp_crc32c(0, &k, sizeof(k));
262
+ crc = sp_crc32c(crc, &k, sizeof(k));
263
+ vh.crc = sp_crc32c(crc, &vh.size, sizeof(spvh) - sizeof(uint32_t));
264
+ spfile f;
265
+ sp_fileinit(&f, &a);
266
+ t( mkdir(dbrep, 0755) == 0 );
267
+ t( sp_lognew(&f, dbrep, 1) == 0 );
268
+ sp_logadd(&f, &h, sizeof(h));
269
+ sp_logadd(&f, &vh, sizeof(vh));
270
+ sp_logadd(&f, &k, sizeof(k));
271
+ sp_logadd(&f, &k, sizeof(k));
272
+ t( sp_logflush(&f) == 0 );
273
+ t( sp_logcomplete(&f) == 0 );
274
+ t( sp_logclose(&f) == 0 );
275
+ t( exists(dbrep, 1, "log") == 1 );
276
+ void *env = sp_env();
277
+ t( env != NULL );
278
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
279
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
280
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
281
+ void *db = sp_open(env);
282
+ t( db == NULL );
283
+ t( sp_error(env) != NULL );
284
+ t( sp_destroy(env) == 0 );
285
+ t( rmrf(dbrep) == 0 );
286
+ }
287
+
288
+ static void
289
+ db_empty(void) {
290
+ spfile f;
291
+ sp_fileinit(&f, &a);
292
+ t( mkdir(dbrep, 0755) == 0 );
293
+ char path[1024];
294
+ snprintf(path, sizeof(path), "%s/%"PRIu32".db",
295
+ dbrep, 1);
296
+ int fd = open(path, O_CREAT|O_RDWR, 0644);
297
+ t( fd != -1 );
298
+ t( close(fd) == 0 );
299
+ void *env = sp_env();
300
+ t( env != NULL );
301
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
302
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
303
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
304
+ void *db = sp_open(env);
305
+ t( db == NULL );
306
+ t( sp_error(env) != NULL );
307
+ t( exists(dbrep, 1, "db") == 1 );
308
+ t( sp_destroy(env) == 0 );
309
+ t( rmrf(dbrep) == 0 );
310
+ }
311
+
312
+ static void
313
+ db_empty_incomplete(void) {
314
+ spfile f;
315
+ sp_fileinit(&f, &a);
316
+ t( mkdir(dbrep, 0755) == 0 );
317
+ char path[1024];
318
+ snprintf(path, sizeof(path), "%s/%"PRIu32".db.incomplete",
319
+ dbrep, 1);
320
+ int fd = open(path, O_CREAT|O_RDWR, 0644);
321
+ t( fd != -1 );
322
+ t( close(fd) == 0 );
323
+ void *env = sp_env();
324
+ t( env != NULL );
325
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
326
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
327
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
328
+ void *db = sp_open(env);
329
+ t( db == NULL );
330
+ t( sp_error(env) != NULL );
331
+ t( exists(dbrep, 1, "db.incomplete") == 1 );
332
+ t( sp_destroy(env) == 0 );
333
+ t( rmrf(dbrep) == 0 );
334
+ }
335
+
336
+ static void
337
+ db_badpage(void) {
338
+ sppageh h = {
339
+ .crc = 0,
340
+ .count = 0,
341
+ .size = 1234,
342
+ .bsize = 1234,
343
+ };
344
+ t( mkdir(dbrep, 0755) == 0 );
345
+ char path[1024];
346
+ snprintf(path, sizeof(path), "%s/%"PRIu32".db",
347
+ dbrep, 1);
348
+ int fd = open(path, O_CREAT|O_RDWR, 0644);
349
+ t( fd != -1 );
350
+ t( write(fd, &h, sizeof(h)) == sizeof(h) );
351
+ t( close(fd) == 0 );
352
+ void *env = sp_env();
353
+ t( env != NULL );
354
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
355
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
356
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
357
+ void *db = sp_open(env);
358
+ t( db == NULL );
359
+ t( sp_error(env) != NULL );
360
+ t( sp_destroy(env) == 0 );
361
+ t( rmrf(dbrep) == 0 );
362
+ }
363
+
364
+ static void
365
+ log_incomplete_db_incomplete(void) {
366
+ uint32_t k = 123;
367
+ splogh h = {
368
+ .magic = SPMAGIC,
369
+ .version[0] = SP_VERSION_MAJOR,
370
+ .version[1] = SP_VERSION_MINOR
371
+ };
372
+ spvh vh = {
373
+ .crc = 0,
374
+ .size = sizeof(uint32_t),
375
+ .voffset = 0,
376
+ .vsize = sizeof(uint32_t),
377
+ .flags = SPSET
378
+ };
379
+ speofh eof = { SPEOF };
380
+ uint32_t crc;
381
+ crc = sp_crc32c(0, &k, sizeof(k));
382
+ crc = sp_crc32c(crc, &k, sizeof(k));
383
+ vh.crc = sp_crc32c(crc, &vh.size, sizeof(spvh) - sizeof(uint32_t));
384
+ spfile f;
385
+ sp_fileinit(&f, &a);
386
+ t( mkdir(dbrep, 0755) == 0 );
387
+ t( sp_lognew(&f, dbrep, 1) == 0 );
388
+ sp_logadd(&f, &h, sizeof(h));
389
+ sp_logadd(&f, &vh, sizeof(vh));
390
+ sp_logadd(&f, &k, sizeof(k));
391
+ sp_logadd(&f, &k, sizeof(k));
392
+ sp_logadd(&f, &eof, sizeof(eof));
393
+ t( sp_logflush(&f) == 0 );
394
+ t( sp_logclose(&f) == 0 );
395
+ char path[1024];
396
+ snprintf(path, sizeof(path), "%s/%"PRIu32".db.incomplete",
397
+ dbrep, 1);
398
+ int fd = open(path, O_CREAT|O_RDWR, 0644);
399
+ t( fd != -1 );
400
+ t( write(fd, &h, sizeof(h)) == sizeof(h) );
401
+ t( close(fd) == 0 );
402
+ void *env = sp_env();
403
+ t( env != NULL );
404
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
405
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
406
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
407
+ void *db = sp_open(env);
408
+ t( db == NULL );
409
+ t( sp_destroy(env) == 0 );
410
+ t( rmrf(dbrep) == 0 );
411
+ }
412
+
413
+ static void
414
+ log_db_incomplete(void) {
415
+ uint32_t k = 123;
416
+ splogh h = {
417
+ .magic = SPMAGIC,
418
+ .version[0] = SP_VERSION_MAJOR,
419
+ .version[1] = SP_VERSION_MINOR
420
+ };
421
+ spvh vh = {
422
+ .crc = 0,
423
+ .size = sizeof(uint32_t),
424
+ .voffset = 0,
425
+ .vsize = sizeof(uint32_t),
426
+ .flags = SPSET
427
+ };
428
+ speofh eof = { SPEOF };
429
+ uint32_t crc;
430
+ crc = sp_crc32c(0, &k, sizeof(k));
431
+ crc = sp_crc32c(crc, &k, sizeof(k));
432
+ vh.crc = sp_crc32c(crc, &vh.size, sizeof(spvh) - sizeof(uint32_t));
433
+ spfile f;
434
+ sp_fileinit(&f, &a);
435
+ t( mkdir(dbrep, 0755) == 0 );
436
+ t( sp_lognew(&f, dbrep, 1) == 0 );
437
+ sp_logadd(&f, &h, sizeof(h));
438
+ sp_logadd(&f, &vh, sizeof(vh));
439
+ sp_logadd(&f, &k, sizeof(k));
440
+ sp_logadd(&f, &k, sizeof(k));
441
+ sp_logadd(&f, &eof, sizeof(eof));
442
+ t( sp_logflush(&f) == 0 );
443
+ t( sp_logcomplete(&f) == 0 );
444
+ t( sp_logclose(&f) == 0 );
445
+ t( exists(dbrep, 1, "log") == 1 );
446
+ char path[1024];
447
+ snprintf(path, sizeof(path), "%s/%"PRIu32".db.incomplete",
448
+ dbrep, 1);
449
+ int fd = open(path, O_CREAT|O_RDWR, 0644);
450
+ t( fd != -1 );
451
+ t( write(fd, &h, sizeof(h)) == sizeof(h) );
452
+ t( close(fd) == 0 );
453
+ void *env = sp_env();
454
+ t( env != NULL );
455
+ t( sp_ctl(env, SPDIR, SPO_CREAT|SPO_RDWR, dbrep) == 0 );
456
+ t( sp_ctl(env, SPCMP, cmp, NULL) == 0 );
457
+ t( sp_ctl(env, SPMERGE, 0) == 0 );
458
+ void *db = sp_open(env);
459
+ t( db != NULL );
460
+ size_t vsize = 0;
461
+ void *vp = NULL;
462
+ t( sp_get(db, &k, sizeof(k), &vp, &vsize) == 1 );
463
+ t( vsize == sizeof(k) );
464
+ t( *(uint32_t*)vp == k );
465
+ free(vp);
466
+ t( sp_destroy(db) == 0 );
467
+ t( sp_destroy(env) == 0 );
468
+ t( rmrf(dbrep) == 0 );
469
+ }
470
+
471
+ int
472
+ main(int argc, char *argv[])
473
+ {
474
+ sp_allocinit(&a, sp_allocstd, NULL);
475
+ rmrf(dbrep);
476
+
477
+ test(log_empty);
478
+ test(log_empty_incomplete);
479
+ test(log_badrecord);
480
+ test(log_badrecord_incomplete);
481
+ test(log_1_badrecord_2_goodrecord);
482
+ test(log_noeof);
483
+ test(log_noeof_complete);
484
+
485
+ test(db_empty);
486
+ test(db_empty_incomplete);
487
+ test(db_badpage);
488
+
489
+ test(log_db_incomplete);
490
+ test(log_incomplete_db_incomplete);
491
+ return 0;
492
+ }