rrudb 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
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