rrudb 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. checksums.yaml +7 -0
  2. data/.yardopts +1 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +26 -0
  5. data/examples/example.rb +39 -0
  6. data/ext/rudb/NuDB/include/nudb/CMakeLists.txt +104 -0
  7. data/ext/rudb/NuDB/include/nudb/_experimental/basic_seconds_clock.hpp +200 -0
  8. data/ext/rudb/NuDB/include/nudb/_experimental/chrono_util.hpp +58 -0
  9. data/ext/rudb/NuDB/include/nudb/_experimental/test/fail_file.hpp +343 -0
  10. data/ext/rudb/NuDB/include/nudb/_experimental/test/temp_dir.hpp +73 -0
  11. data/ext/rudb/NuDB/include/nudb/_experimental/test/test_store.hpp +451 -0
  12. data/ext/rudb/NuDB/include/nudb/_experimental/test/xor_shift_engine.hpp +105 -0
  13. data/ext/rudb/NuDB/include/nudb/_experimental/util.hpp +288 -0
  14. data/ext/rudb/NuDB/include/nudb/basic_store.hpp +461 -0
  15. data/ext/rudb/NuDB/include/nudb/concepts.hpp +205 -0
  16. data/ext/rudb/NuDB/include/nudb/context.hpp +144 -0
  17. data/ext/rudb/NuDB/include/nudb/create.hpp +117 -0
  18. data/ext/rudb/NuDB/include/nudb/detail/arena.hpp +296 -0
  19. data/ext/rudb/NuDB/include/nudb/detail/bucket.hpp +473 -0
  20. data/ext/rudb/NuDB/include/nudb/detail/buffer.hpp +86 -0
  21. data/ext/rudb/NuDB/include/nudb/detail/bulkio.hpp +196 -0
  22. data/ext/rudb/NuDB/include/nudb/detail/cache.hpp +236 -0
  23. data/ext/rudb/NuDB/include/nudb/detail/endian.hpp +93 -0
  24. data/ext/rudb/NuDB/include/nudb/detail/field.hpp +265 -0
  25. data/ext/rudb/NuDB/include/nudb/detail/format.hpp +630 -0
  26. data/ext/rudb/NuDB/include/nudb/detail/gentex.hpp +259 -0
  27. data/ext/rudb/NuDB/include/nudb/detail/mutex.hpp +26 -0
  28. data/ext/rudb/NuDB/include/nudb/detail/pool.hpp +243 -0
  29. data/ext/rudb/NuDB/include/nudb/detail/store_base.hpp +45 -0
  30. data/ext/rudb/NuDB/include/nudb/detail/stream.hpp +149 -0
  31. data/ext/rudb/NuDB/include/nudb/detail/xxhash.hpp +328 -0
  32. data/ext/rudb/NuDB/include/nudb/error.hpp +257 -0
  33. data/ext/rudb/NuDB/include/nudb/file.hpp +55 -0
  34. data/ext/rudb/NuDB/include/nudb/impl/basic_store.ipp +785 -0
  35. data/ext/rudb/NuDB/include/nudb/impl/context.ipp +241 -0
  36. data/ext/rudb/NuDB/include/nudb/impl/create.ipp +163 -0
  37. data/ext/rudb/NuDB/include/nudb/impl/error.ipp +175 -0
  38. data/ext/rudb/NuDB/include/nudb/impl/posix_file.ipp +248 -0
  39. data/ext/rudb/NuDB/include/nudb/impl/recover.ipp +209 -0
  40. data/ext/rudb/NuDB/include/nudb/impl/rekey.ipp +248 -0
  41. data/ext/rudb/NuDB/include/nudb/impl/verify.ipp +634 -0
  42. data/ext/rudb/NuDB/include/nudb/impl/visit.ipp +96 -0
  43. data/ext/rudb/NuDB/include/nudb/impl/win32_file.ipp +264 -0
  44. data/ext/rudb/NuDB/include/nudb/native_file.hpp +76 -0
  45. data/ext/rudb/NuDB/include/nudb/nudb.hpp +27 -0
  46. data/ext/rudb/NuDB/include/nudb/posix_file.hpp +228 -0
  47. data/ext/rudb/NuDB/include/nudb/progress.hpp +32 -0
  48. data/ext/rudb/NuDB/include/nudb/recover.hpp +73 -0
  49. data/ext/rudb/NuDB/include/nudb/rekey.hpp +110 -0
  50. data/ext/rudb/NuDB/include/nudb/store.hpp +27 -0
  51. data/ext/rudb/NuDB/include/nudb/type_traits.hpp +63 -0
  52. data/ext/rudb/NuDB/include/nudb/verify.hpp +200 -0
  53. data/ext/rudb/NuDB/include/nudb/version.hpp +21 -0
  54. data/ext/rudb/NuDB/include/nudb/visit.hpp +63 -0
  55. data/ext/rudb/NuDB/include/nudb/win32_file.hpp +246 -0
  56. data/ext/rudb/NuDB/include/nudb/xxhasher.hpp +45 -0
  57. data/ext/rudb/extconf.rb +12 -0
  58. data/ext/rudb/rudb.cpp +234 -0
  59. data/lib/rudb/version.rb +3 -0
  60. data/lib/rudb.rb +1 -0
  61. metadata +104 -0
@@ -0,0 +1,630 @@
1
+ //
2
+ // Copyright (c) 2015-2016 Vinnie Falco (vinnie dot falco at gmail dot com)
3
+ //
4
+ // Distributed under the Boost Software License, Version 1.0. (See accompanying
5
+ // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6
+ //
7
+
8
+ #ifndef NUDB_DETAIL_FORMAT_HPP
9
+ #define NUDB_DETAIL_FORMAT_HPP
10
+
11
+ #include <nudb/error.hpp>
12
+ #include <nudb/type_traits.hpp>
13
+ #include <nudb/detail/buffer.hpp>
14
+ #include <nudb/detail/endian.hpp>
15
+ #include <nudb/detail/field.hpp>
16
+ #include <nudb/detail/stream.hpp>
17
+ #include <boost/assert.hpp>
18
+ #include <algorithm>
19
+ #include <array>
20
+ #include <limits>
21
+ #include <cstdint>
22
+ #include <cstring>
23
+ #include <memory>
24
+ #include <stdexcept>
25
+ #include <type_traits>
26
+
27
+ namespace nudb {
28
+ namespace detail {
29
+
30
+ // Format of the nudb files:
31
+
32
+ /*
33
+
34
+ Integer sizes
35
+
36
+ block_size less than 32 bits (maybe restrict it to 16 bits)
37
+ buckets more than 32 bits
38
+ capacity (same as bucket index)
39
+ file offsets 63 bits
40
+ hash up to 64 bits (48 currently)
41
+ item index less than 32 bits (index of item in bucket)
42
+ modulus (same as buckets)
43
+ value size up to 32 bits (or 32-bit builds can't read it)
44
+
45
+ */
46
+
47
+ static std::size_t constexpr currentVersion = 2;
48
+
49
+ struct dat_file_header
50
+ {
51
+ static std::size_t constexpr size =
52
+ 8 + // Type
53
+ 2 + // Version
54
+ 8 + // UID
55
+ 8 + // Appnum
56
+ 2 + // KeySize
57
+
58
+ 64; // (Reserved)
59
+
60
+ char type[8];
61
+ std::size_t version;
62
+ std::uint64_t uid;
63
+ std::uint64_t appnum;
64
+ nsize_t key_size;
65
+ };
66
+
67
+ struct key_file_header
68
+ {
69
+ static std::size_t constexpr size =
70
+ 8 + // Type
71
+ 2 + // Version
72
+ 8 + // UID
73
+ 8 + // Appnum
74
+ 2 + // KeySize
75
+
76
+ 8 + // Salt
77
+ 8 + // Pepper
78
+ 2 + // BlockSize
79
+ 2 + // LoadFactor
80
+
81
+ 56; // (Reserved)
82
+
83
+ char type[8];
84
+ std::size_t version;
85
+ std::uint64_t uid;
86
+ std::uint64_t appnum;
87
+ nsize_t key_size;
88
+
89
+ std::uint64_t salt;
90
+ std::uint64_t pepper;
91
+ nsize_t block_size;
92
+ std::size_t load_factor;
93
+
94
+ // Computed values
95
+ nkey_t capacity; // Entries per bucket
96
+ nbuck_t buckets; // Number of buckets
97
+ nbuck_t modulus; // pow(2,ceil(log2(buckets)))
98
+ };
99
+
100
+ struct log_file_header
101
+ {
102
+ static std::size_t constexpr size =
103
+ 8 + // Type
104
+ 2 + // Version
105
+ 8 + // UID
106
+ 8 + // Appnum
107
+ 2 + // KeySize
108
+
109
+ 8 + // Salt
110
+ 8 + // Pepper
111
+ 2 + // BlockSize
112
+
113
+ 8 + // KeyFileSize
114
+ 8; // DataFileSize
115
+
116
+ char type[8];
117
+ std::size_t version;
118
+ std::uint64_t uid;
119
+ std::uint64_t appnum;
120
+ nsize_t key_size;
121
+ std::uint64_t salt;
122
+ std::uint64_t pepper;
123
+ nsize_t block_size;
124
+ noff_t key_file_size;
125
+ noff_t dat_file_size;
126
+ };
127
+
128
+ // Type used to store hashes in buckets.
129
+ // This can be smaller than the output
130
+ // of the hash function.
131
+ //
132
+ using f_hash = uint48_t;
133
+
134
+ static_assert(field<f_hash>::size <=
135
+ sizeof(nhash_t), "");
136
+
137
+ template<class T>
138
+ nhash_t
139
+ make_hash(nhash_t h);
140
+
141
+ template<>
142
+ inline
143
+ nhash_t
144
+ make_hash<uint48_t>(nhash_t h)
145
+ {
146
+ return(h>>16)&0xffffffffffff;
147
+ }
148
+
149
+ // Returns the hash of a key given the salt.
150
+ // Note: The hash is expressed in f_hash units
151
+ //
152
+ template<class Hasher>
153
+ inline
154
+ nhash_t
155
+ hash(void const* key, nsize_t key_size, std::uint64_t salt)
156
+ {
157
+ Hasher h{salt};
158
+ return make_hash<f_hash>(h(key, key_size));
159
+ }
160
+
161
+ template<class Hasher>
162
+ inline
163
+ nhash_t
164
+ hash(void const* key, nsize_t key_size, Hasher const& h)
165
+ {
166
+ return make_hash<f_hash>(h(key, key_size));
167
+ }
168
+
169
+ // Computes pepper from salt
170
+ //
171
+ template<class Hasher>
172
+ std::uint64_t
173
+ pepper(std::uint64_t salt)
174
+ {
175
+ auto const v = to_little_endian(salt);
176
+ Hasher h{salt};
177
+ return h(&v, sizeof(v));
178
+ }
179
+
180
+ // Returns the actual size of a bucket.
181
+ // This can be smaller than the block size.
182
+ //
183
+ template<class = void>
184
+ nsize_t
185
+ bucket_size(nkey_t capacity)
186
+ {
187
+ // Bucket Record
188
+ return
189
+ field<std::uint16_t>::size + // Count
190
+ field<uint48_t>::size + // Spill
191
+ capacity * (
192
+ field<uint48_t>::size + // Offset
193
+ field<uint48_t>::size + // Size
194
+ field<f_hash>::size); // Hash
195
+ }
196
+
197
+ // Returns the number of entries that fit in a bucket
198
+ //
199
+ template<class = void>
200
+ nkey_t
201
+ bucket_capacity(nsize_t block_size)
202
+ {
203
+ // Bucket Record
204
+ auto const size =
205
+ field<std::uint16_t>::size + // Count
206
+ field<uint48_t>::size; // Spill
207
+ auto const entry_size =
208
+ field<uint48_t>::size + // Offset
209
+ field<uint48_t>::size + // Size
210
+ field<f_hash>::size; // Hash
211
+ if(block_size < key_file_header::size ||
212
+ block_size < size)
213
+ return 0;
214
+ auto const n =
215
+ (block_size - size) / entry_size;
216
+ BOOST_ASSERT(n <= std::numeric_limits<nkey_t>::max());
217
+ return static_cast<nkey_t>(std::min<std::size_t>(
218
+ std::numeric_limits<nkey_t>::max(), n));
219
+ }
220
+
221
+ // Returns the number of bytes occupied by a value record
222
+ // VFALCO TODO Fix this
223
+ inline
224
+ std::size_t
225
+ value_size(std::size_t size,
226
+ std::size_t key_size)
227
+ {
228
+ // Data Record
229
+ return
230
+ field<uint48_t>::size + // Size
231
+ key_size + // Key
232
+ size; // Data
233
+ }
234
+
235
+ // Returns the closest power of 2 not less than x
236
+ template<class T>
237
+ T
238
+ ceil_pow2(T x)
239
+ {
240
+ static const unsigned long long t[6] = {
241
+ 0xFFFFFFFF00000000ull,
242
+ 0x00000000FFFF0000ull,
243
+ 0x000000000000FF00ull,
244
+ 0x00000000000000F0ull,
245
+ 0x000000000000000Cull,
246
+ 0x0000000000000002ull
247
+ };
248
+
249
+ int y =(((x &(x - 1)) == 0) ? 0 : 1);
250
+ int j = 32;
251
+ int i;
252
+
253
+ for(i = 0; i < 6; i++) {
254
+ int k =(((x & t[i]) == 0) ? 0 : j);
255
+ y += k;
256
+ x >>= k;
257
+ j >>= 1;
258
+ }
259
+
260
+ return T{1}<<y;
261
+ }
262
+
263
+ //------------------------------------------------------------------------------
264
+
265
+ // Read data file header from stream
266
+ template<class = void>
267
+ void
268
+ read(istream& is, dat_file_header& dh)
269
+ {
270
+ read(is, dh.type, sizeof(dh.type));
271
+ read<std::uint16_t>(is, dh.version);
272
+ read<std::uint64_t>(is, dh.uid);
273
+ read<std::uint64_t>(is, dh.appnum);
274
+ read<std::uint16_t>(is, dh.key_size);
275
+ std::array<std::uint8_t, 64> reserved;
276
+ read(is, reserved.data(), reserved.size());
277
+ }
278
+
279
+ // Read data file header from file
280
+ template<class File>
281
+ void
282
+ read(File& f, dat_file_header& dh, error_code& ec)
283
+ {
284
+ std::array<std::uint8_t, dat_file_header::size> buf;
285
+ f.read(0, buf.data(), buf.size(), ec);
286
+ if(ec)
287
+ return;
288
+ istream is(buf);
289
+ read(is, dh);
290
+ }
291
+
292
+ // Write data file header to stream
293
+ template<class = void>
294
+ void
295
+ write(ostream& os, dat_file_header const& dh)
296
+ {
297
+ write(os, "nudb.dat", 8);
298
+ write<std::uint16_t>(os, dh.version);
299
+ write<std::uint64_t>(os, dh.uid);
300
+ write<std::uint64_t>(os, dh.appnum);
301
+ write<std::uint16_t>(os, dh.key_size);
302
+ std::array<std::uint8_t, 64> reserved;
303
+ reserved.fill(0);
304
+ write(os, reserved.data(), reserved.size());
305
+ }
306
+
307
+ // Write data file header to file
308
+ template<class File>
309
+ void
310
+ write(File& f, dat_file_header const& dh, error_code& ec)
311
+ {
312
+ std::array<std::uint8_t, dat_file_header::size> buf;
313
+ ostream os(buf);
314
+ write(os, dh);
315
+ f.write(0, buf.data(), buf.size(), ec);
316
+ }
317
+
318
+ // Read key file header from stream
319
+ template<class = void>
320
+ void
321
+ read(istream& is, noff_t file_size, key_file_header& kh)
322
+ {
323
+ read(is, kh.type, sizeof(kh.type));
324
+ read<std::uint16_t>(is, kh.version);
325
+ read<std::uint64_t>(is, kh.uid);
326
+ read<std::uint64_t>(is, kh.appnum);
327
+ read<std::uint16_t>(is, kh.key_size);
328
+ read<std::uint64_t>(is, kh.salt);
329
+ read<std::uint64_t>(is, kh.pepper);
330
+ read<std::uint16_t>(is, kh.block_size);
331
+ read<std::uint16_t>(is, kh.load_factor);
332
+ std::array<std::uint8_t, 56> reserved;
333
+ read(is, reserved.data(), reserved.size());
334
+
335
+ // VFALCO These need to be checked to handle
336
+ // when the file size is too small
337
+ kh.capacity = bucket_capacity(kh.block_size);
338
+ if(file_size > kh.block_size)
339
+ {
340
+ if(kh.block_size > 0)
341
+ kh.buckets = static_cast<nbuck_t>(
342
+ (file_size - kh.block_size) / kh.block_size);
343
+ else
344
+ // VFALCO Corruption or logic error
345
+ kh.buckets = 0;
346
+ }
347
+ else
348
+ {
349
+ kh.buckets = 0;
350
+ }
351
+ kh.modulus = ceil_pow2(kh.buckets);
352
+ }
353
+
354
+ // Read key file header from file
355
+ template<class File>
356
+ void
357
+ read(File& f, key_file_header& kh, error_code& ec)
358
+ {
359
+ std::array<std::uint8_t, key_file_header::size> buf;
360
+ f.read(0, buf.data(), buf.size(), ec);
361
+ if(ec)
362
+ return;
363
+ istream is{buf};
364
+ auto const size = f.size(ec);
365
+ if(ec)
366
+ return;
367
+ read(is, size, kh);
368
+ }
369
+
370
+ // Write key file header to stream
371
+ template<class = void>
372
+ void
373
+ write(ostream& os, key_file_header const& kh)
374
+ {
375
+ write(os, "nudb.key", 8);
376
+ write<std::uint16_t>(os, kh.version);
377
+ write<std::uint64_t>(os, kh.uid);
378
+ write<std::uint64_t>(os, kh.appnum);
379
+ write<std::uint16_t>(os, kh.key_size);
380
+ write<std::uint64_t>(os, kh.salt);
381
+ write<std::uint64_t>(os, kh.pepper);
382
+ write<std::uint16_t>(os, kh.block_size);
383
+ write<std::uint16_t>(os, kh.load_factor);
384
+ std::array<std::uint8_t, 56> reserved;
385
+ reserved.fill(0);
386
+ write(os, reserved.data(), reserved.size());
387
+ }
388
+
389
+ // Write key file header to file
390
+ template<class File>
391
+ void
392
+ write(File& f, key_file_header const& kh, error_code& ec)
393
+ {
394
+ buffer buf;
395
+ buf.reserve(kh.block_size);
396
+ if(kh.block_size < key_file_header::size)
397
+ {
398
+ ec = error::invalid_block_size;
399
+ return;
400
+ }
401
+ std::fill(buf.get(), buf.get() + buf.size(),
402
+ (unsigned char)0);
403
+ ostream os{buf.get(), buf.size()};
404
+ write(os, kh);
405
+ f.write(0, buf.get(), buf.size(), ec);
406
+ }
407
+
408
+ // Read log file header from stream
409
+ template<class = void>
410
+ void
411
+ read(istream& is, log_file_header& lh)
412
+ {
413
+ read(is, lh.type, sizeof(lh.type));
414
+ read<std::uint16_t>(is, lh.version);
415
+ read<std::uint64_t>(is, lh.uid);
416
+ read<std::uint64_t>(is, lh.appnum);
417
+ read<std::uint16_t>(is, lh.key_size);
418
+ read<std::uint64_t>(is, lh.salt);
419
+ read<std::uint64_t>(is, lh.pepper);
420
+ read<std::uint16_t>(is, lh.block_size);
421
+ read<std::uint64_t>(is, lh.key_file_size);
422
+ read<std::uint64_t>(is, lh.dat_file_size);
423
+ }
424
+
425
+ // Read log file header from file
426
+ template<class File>
427
+ void
428
+ read(File& f, log_file_header& lh, error_code& ec)
429
+ {
430
+ std::array<std::uint8_t, log_file_header::size> buf;
431
+ f.read(0, buf.data(), buf.size(), ec);
432
+ if(ec)
433
+ return;
434
+ istream is{buf};
435
+ read(is, lh);
436
+ }
437
+
438
+ // Write log file header to stream
439
+ template<class = void>
440
+ void
441
+ write(ostream& os, log_file_header const& lh)
442
+ {
443
+ write(os, "nudb.log", 8);
444
+ write<std::uint16_t>(os, lh.version);
445
+ write<std::uint64_t>(os, lh.uid);
446
+ write<std::uint64_t>(os, lh.appnum);
447
+ write<std::uint16_t>(os, lh.key_size);
448
+ write<std::uint64_t>(os, lh.salt);
449
+ write<std::uint64_t>(os, lh.pepper);
450
+ write<std::uint16_t>(os, lh.block_size);
451
+ write<std::uint64_t>(os, lh.key_file_size);
452
+ write<std::uint64_t>(os, lh.dat_file_size);
453
+ }
454
+
455
+ // Write log file header to file
456
+ template<class File>
457
+ void
458
+ write(File& f, log_file_header const& lh, error_code& ec)
459
+ {
460
+ std::array<std::uint8_t, log_file_header::size> buf;
461
+ ostream os{buf};
462
+ write(os, lh);
463
+ f.write(0, buf.data(), buf.size(), ec);
464
+ }
465
+
466
+ // Verify contents of data file header
467
+ template<class = void>
468
+ void
469
+ verify(dat_file_header const& dh, error_code& ec)
470
+ {
471
+ std::string const type{dh.type, 8};
472
+ if(type != "nudb.dat")
473
+ {
474
+ ec = error::not_data_file;
475
+ return;
476
+ }
477
+ if(dh.version != currentVersion)
478
+ {
479
+ ec = error::different_version;
480
+ return;
481
+ }
482
+ if(dh.key_size < 1)
483
+ {
484
+ ec = error::invalid_key_size;
485
+ return;
486
+ }
487
+ }
488
+
489
+ // Verify contents of key file header
490
+ template<class Hasher>
491
+ void
492
+ verify(key_file_header const& kh, error_code& ec)
493
+ {
494
+ std::string const type{kh.type, 8};
495
+ if(type != "nudb.key")
496
+ {
497
+ ec = error::not_key_file;
498
+ return;
499
+ }
500
+ if(kh.version != currentVersion)
501
+ {
502
+ ec = error::different_version;
503
+ return;
504
+ }
505
+ if(kh.key_size < 1)
506
+ {
507
+ ec = error::invalid_key_size;
508
+ return;
509
+ }
510
+ if(kh.pepper != pepper<Hasher>(kh.salt))
511
+ {
512
+ ec = error::hash_mismatch;
513
+ return;
514
+ }
515
+ if(kh.load_factor < 1)
516
+ {
517
+ ec = error::invalid_load_factor;
518
+ return;
519
+ }
520
+ if(kh.capacity < 1)
521
+ {
522
+ ec = error::invalid_capacity;
523
+ return;
524
+ }
525
+ if(kh.buckets < 1)
526
+ {
527
+ ec = error::invalid_bucket_count;
528
+ return;
529
+ }
530
+ }
531
+
532
+ // Verify contents of log file header
533
+ template<class Hasher>
534
+ void
535
+ verify(log_file_header const& lh, error_code& ec)
536
+ {
537
+ std::string const type{lh.type, 8};
538
+ if(type != "nudb.log")
539
+ {
540
+ ec = error::not_log_file;
541
+ return;
542
+ }
543
+ if(lh.version != currentVersion)
544
+ {
545
+ ec = error::different_version;
546
+ return;
547
+ }
548
+ if(lh.pepper != pepper<Hasher>(lh.salt))
549
+ {
550
+ ec = error::hash_mismatch;
551
+ return;
552
+ }
553
+ if(lh.key_size < 1)
554
+ {
555
+ ec = error::invalid_key_size;
556
+ return;
557
+ }
558
+ }
559
+
560
+ // Make sure key file and value file headers match
561
+ template<class Hasher>
562
+ void
563
+ verify(dat_file_header const& dh,
564
+ key_file_header const& kh, error_code& ec)
565
+ {
566
+ verify<Hasher>(kh, ec);
567
+ if(ec)
568
+ return;
569
+ if(kh.uid != dh.uid)
570
+ {
571
+ ec = error::uid_mismatch;
572
+ return;
573
+ }
574
+ if(kh.appnum != dh.appnum)
575
+ {
576
+ ec = error::appnum_mismatch;
577
+ return;
578
+ }
579
+ if(kh.key_size != dh.key_size)
580
+ {
581
+ ec = error::key_size_mismatch;
582
+ return;
583
+ }
584
+ }
585
+
586
+ // Make sure key file and log file headers match
587
+ template<class Hasher>
588
+ void
589
+ verify(key_file_header const& kh,
590
+ log_file_header const& lh, error_code& ec)
591
+ {
592
+ verify<Hasher>(lh, ec);
593
+ if(ec)
594
+ return;
595
+ if(kh.uid != lh.uid)
596
+ {
597
+ ec = error::uid_mismatch;
598
+ return;
599
+ }
600
+ if(kh.appnum != lh.appnum)
601
+ {
602
+ ec = error::appnum_mismatch;
603
+ return;
604
+ }
605
+ if(kh.key_size != lh.key_size)
606
+ {
607
+ ec = error::key_size_mismatch;
608
+ return;
609
+ }
610
+ if(kh.salt != lh.salt)
611
+ {
612
+ ec = error::salt_mismatch;
613
+ return;
614
+ }
615
+ if(kh.pepper != lh.pepper)
616
+ {
617
+ ec = error::pepper_mismatch;
618
+ return;
619
+ }
620
+ if(kh.block_size != lh.block_size)
621
+ {
622
+ ec = error::block_size_mismatch;
623
+ return;
624
+ }
625
+ }
626
+
627
+ } // detail
628
+ } // nudb
629
+
630
+ #endif