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,451 @@
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_TEST_TEST_STORE_HPP
9
+ #define NUDB_TEST_TEST_STORE_HPP
10
+
11
+ #include <nudb/_experimental/util.hpp>
12
+ #include <nudb/_experimental/test/temp_dir.hpp>
13
+ #include <nudb/_experimental/test/xor_shift_engine.hpp>
14
+ #include <nudb/create.hpp>
15
+ #include <nudb/native_file.hpp>
16
+ #include <nudb/store.hpp>
17
+ #include <nudb/verify.hpp>
18
+ #include <nudb/xxhasher.hpp>
19
+ #include <iomanip>
20
+ #include <iostream>
21
+
22
+ namespace nudb {
23
+ namespace test {
24
+
25
+ template<class = void>
26
+ class Buffer_t
27
+ {
28
+ std::size_t size_ = 0;
29
+ std::size_t capacity_ = 0;
30
+ std::unique_ptr<std::uint8_t[]> p_;
31
+
32
+ public:
33
+ Buffer_t() = default;
34
+
35
+ Buffer_t(Buffer_t&& other);
36
+
37
+ Buffer_t(Buffer_t const& other);
38
+
39
+ Buffer_t& operator=(Buffer_t&& other);
40
+
41
+ Buffer_t& operator=(Buffer_t const& other);
42
+
43
+ bool
44
+ empty() const
45
+ {
46
+ return size_ == 0;
47
+ }
48
+
49
+ std::size_t
50
+ size() const
51
+ {
52
+ return size_;
53
+ }
54
+
55
+ std::uint8_t*
56
+ data()
57
+ {
58
+ return p_.get();
59
+ }
60
+
61
+ std::uint8_t const*
62
+ data() const
63
+ {
64
+ return p_.get();
65
+ }
66
+
67
+ void
68
+ clear();
69
+
70
+ void
71
+ shrink_to_fit();
72
+
73
+ std::uint8_t*
74
+ resize(std::size_t size);
75
+
76
+ std::uint8_t*
77
+ operator()(void const* data, std::size_t size);
78
+ };
79
+
80
+ template<class _>
81
+ Buffer_t<_>::
82
+ Buffer_t(Buffer_t&& other)
83
+ : size_(other.size_)
84
+ , capacity_(other.capacity_)
85
+ , p_(std::move(other.p_))
86
+ {
87
+ other.size_ = 0;
88
+ other.capacity_ = 0;
89
+ }
90
+
91
+ template<class _>
92
+ Buffer_t<_>::
93
+ Buffer_t(Buffer_t const& other)
94
+ {
95
+ if(! other.empty())
96
+ std::memcpy(resize(other.size()),
97
+ other.data(), other.size());
98
+ }
99
+
100
+ template<class _>
101
+ auto
102
+ Buffer_t<_>::
103
+ operator=(Buffer_t&& other) ->
104
+ Buffer_t&
105
+ {
106
+ if(&other != this)
107
+ {
108
+ size_ = other.size_;
109
+ capacity_ = other.capacity_;
110
+ p_ = std::move(other.p_);
111
+ other.size_ = 0;
112
+ other.capacity_ = 0;
113
+ }
114
+ return *this;
115
+ }
116
+
117
+ template<class _>
118
+ auto
119
+ Buffer_t<_>::
120
+ operator=(Buffer_t const& other) ->
121
+ Buffer_t&
122
+ {
123
+ if(&other != this)
124
+ {
125
+ if(other.empty())
126
+ size_ = 0;
127
+ else
128
+ std::memcpy(resize(other.size()),
129
+ other.data(), other.size());
130
+ }
131
+ return *this;
132
+ }
133
+
134
+ template<class _>
135
+ void
136
+ Buffer_t<_>::
137
+ clear()
138
+ {
139
+ size_ = 0;
140
+ capacity_ = 0;
141
+ p_.reset();
142
+ }
143
+
144
+ template<class _>
145
+ void
146
+ Buffer_t<_>::
147
+ shrink_to_fit()
148
+ {
149
+ if(empty() || size_ == capacity_)
150
+ return;
151
+ std::unique_ptr<std::uint8_t[]> p{
152
+ new std::uint8_t[size_]};
153
+ capacity_ = size_;
154
+ std::memcpy(p.get(), p_.get(), size_);
155
+ std::swap(p, p_);
156
+ }
157
+
158
+ template<class _>
159
+ std::uint8_t*
160
+ Buffer_t<_>::
161
+ resize(std::size_t size)
162
+ {
163
+ if(capacity_ < size)
164
+ {
165
+ p_.reset(new std::uint8_t[size]);
166
+ capacity_ = size;
167
+ }
168
+ size_ = size;
169
+ return p_.get();
170
+ }
171
+
172
+ template<class _>
173
+ std::uint8_t*
174
+ Buffer_t<_>::
175
+ operator()(void const* data, std::size_t size)
176
+ {
177
+ if(data == nullptr || size == 0)
178
+ return resize(0);
179
+ return reinterpret_cast<std::uint8_t*>(
180
+ std::memcpy(resize(size), data, size));
181
+ }
182
+
183
+ using Buffer = Buffer_t<>;
184
+
185
+ //------------------------------------------------------------------------------
186
+
187
+ /// Describes a test generated key/value pair
188
+ struct item_type
189
+ {
190
+ std::uint8_t* key;
191
+ std::uint8_t* data;
192
+ std::size_t size;
193
+ };
194
+
195
+ /// Interface to facilitate tests
196
+ template<class File>
197
+ class basic_test_store
198
+ {
199
+ using Hasher = xxhasher;
200
+
201
+ temp_dir td_;
202
+ std::uniform_int_distribution<std::size_t> sizef_;
203
+ std::function<void(error_code&)> createf_;
204
+ std::function<void(error_code&)> openf_;
205
+ Buffer buf_;
206
+
207
+ public:
208
+ path_type const dp;
209
+ path_type const kp;
210
+ path_type const lp;
211
+ std::size_t const keySize;
212
+ std::size_t const blockSize;
213
+ float const loadFactor;
214
+ static std::uint64_t constexpr appnum = 1;
215
+ static std::uint64_t constexpr salt = 42;
216
+ basic_store<xxhasher, File> db;
217
+
218
+ template<class... Args>
219
+ basic_test_store(std::size_t keySize,
220
+ std::size_t blockSize, float loadFactor,
221
+ Args&&... args);
222
+
223
+ template<class... Args>
224
+ basic_test_store(
225
+ boost::filesystem::path const& temp_dir,
226
+ std::size_t keySize, std::size_t blockSize, float loadFactor,
227
+ Args&&... args);
228
+
229
+ ~basic_test_store();
230
+
231
+ item_type
232
+ operator[](std::uint64_t i);
233
+
234
+ void
235
+ create(error_code& ec);
236
+
237
+ void
238
+ open(error_code& ec);
239
+
240
+ void
241
+ close(error_code& ec)
242
+ {
243
+ db.close(ec);
244
+ }
245
+
246
+ void
247
+ erase();
248
+
249
+ private:
250
+ template<class Generator>
251
+ static
252
+ void
253
+ rngfill(
254
+ void* dest, std::size_t size, Generator& g);
255
+ };
256
+
257
+ template <class File>
258
+ template <class... Args>
259
+ basic_test_store<File>::basic_test_store(
260
+ boost::filesystem::path const& temp_dir,
261
+ std::size_t keySize_, std::size_t blockSize_,
262
+ float loadFactor_, Args&&... args)
263
+ : td_(temp_dir)
264
+ , sizef_(250, 750)
265
+ , createf_(
266
+ [this, args...](error_code& ec)
267
+ {
268
+ nudb::create<Hasher, File>(
269
+ dp, kp, lp, appnum, salt,
270
+ keySize, blockSize, loadFactor, ec,
271
+ args...);
272
+ })
273
+ , openf_(
274
+ [this, args...](error_code& ec)
275
+ {
276
+ db.open(dp, kp, lp, ec, args...);
277
+ })
278
+ , dp(td_.file("nudb.dat"))
279
+ , kp(td_.file("nudb.key"))
280
+ , lp(td_.file("nudb.log"))
281
+ , keySize(keySize_)
282
+ , blockSize(blockSize_)
283
+ , loadFactor(loadFactor_)
284
+ {
285
+ }
286
+
287
+ template <class File>
288
+ template <class... Args>
289
+ basic_test_store<File>::basic_test_store(std::size_t keySize_,
290
+ std::size_t blockSize_, float loadFactor_,
291
+ Args&&... args)
292
+ : basic_test_store(boost::filesystem::path{},
293
+ keySize_,
294
+ blockSize_,
295
+ loadFactor_,
296
+ std::forward<Args>(args)...)
297
+ {
298
+ }
299
+
300
+ template<class File>
301
+ basic_test_store<File>::
302
+ ~basic_test_store()
303
+ {
304
+ erase();
305
+ }
306
+
307
+ template<class File>
308
+ auto
309
+ basic_test_store<File>::
310
+ operator[](std::uint64_t i) ->
311
+ item_type
312
+ {
313
+ xor_shift_engine g{i + 1};
314
+ item_type item;
315
+ item.size = sizef_(g);
316
+ auto const needed = keySize + item.size;
317
+ rngfill(buf_.resize(needed), needed, g);
318
+ // put key last so we can get some unaligned
319
+ // keys, this increases coverage of xxhash.
320
+ item.data = buf_.data();
321
+ item.key = buf_.data() + item.size;
322
+ return item;
323
+ }
324
+
325
+ template<class File>
326
+ void
327
+ basic_test_store<File>::
328
+ create(error_code& ec)
329
+ {
330
+ createf_(ec);
331
+ }
332
+
333
+ template<class File>
334
+ void
335
+ basic_test_store<File>::
336
+ open(error_code& ec)
337
+ {
338
+ openf_(ec);
339
+ if(ec)
340
+ return;
341
+ if(db.key_size() != keySize)
342
+ ec = error::invalid_key_size;
343
+ else if(db.block_size() != blockSize)
344
+ ec = error::invalid_block_size;
345
+ }
346
+
347
+ template<class File>
348
+ void
349
+ basic_test_store<File>::
350
+ erase()
351
+ {
352
+ erase_file(dp);
353
+ erase_file(kp);
354
+ erase_file(lp);
355
+ }
356
+
357
+ template<class File>
358
+ template<class Generator>
359
+ void
360
+ basic_test_store<File>::
361
+ rngfill(
362
+ void* dest, std::size_t size, Generator& g)
363
+ {
364
+ using result_type =
365
+ typename Generator::result_type;
366
+ while(size >= sizeof(result_type))
367
+ {
368
+ auto const v = g();
369
+ std::memcpy(dest, &v, sizeof(v));
370
+ dest = reinterpret_cast<
371
+ std::uint8_t*>(dest) + sizeof(v);
372
+ size -= sizeof(v);
373
+ }
374
+ if(size > 0)
375
+ {
376
+ auto const v = g();
377
+ std::memcpy(dest, &v, size);
378
+ }
379
+ }
380
+
381
+ using test_store = basic_test_store<native_file>;
382
+
383
+ //------------------------------------------------------------------------------
384
+
385
+ template<class T>
386
+ static
387
+ std::string
388
+ num (T t)
389
+ {
390
+ std::string s = std::to_string(t);
391
+ std::reverse(s.begin(), s.end());
392
+ std::string s2;
393
+ s2.reserve(s.size() + (s.size()+2)/3);
394
+ int n = 0;
395
+ for (auto c : s)
396
+ {
397
+ if (n == 3)
398
+ {
399
+ n = 0;
400
+ s2.insert (s2.begin(), ',');
401
+ }
402
+ ++n;
403
+ s2.insert(s2.begin(), c);
404
+ }
405
+ return s2;
406
+ }
407
+
408
+ template<class = void>
409
+ std::ostream&
410
+ operator<<(std::ostream& os, verify_info const& info)
411
+ {
412
+ os <<
413
+ "avg_fetch: " << std::fixed << std::setprecision(3) << info.avg_fetch << "\n" <<
414
+ "waste: " << std::fixed << std::setprecision(3) << info.waste * 100 << "%" << "\n" <<
415
+ "overhead: " << std::fixed << std::setprecision(1) << info.overhead * 100 << "%" << "\n" <<
416
+ "actual_load: " << std::fixed << std::setprecision(0) << info.actual_load * 100 << "%" << "\n" <<
417
+ "version: " << num(info.version) << "\n" <<
418
+ "uid: " << fhex(info.uid) << "\n" <<
419
+ "appnum: " << info.appnum << "\n" <<
420
+ "key_size: " << num(info.key_size) << "\n" <<
421
+ "salt: " << fhex(info.salt) << "\n" <<
422
+ "pepper: " << fhex(info.pepper) << "\n" <<
423
+ "block_size: " << num(info.block_size) << "\n" <<
424
+ "bucket_size: " << num(info.bucket_size) << "\n" <<
425
+ "load_factor: " << std::fixed << std::setprecision(0) << info.load_factor * 100 << "%" << "\n" <<
426
+ "capacity: " << num(info.capacity) << "\n" <<
427
+ "buckets: " << num(info.buckets) << "\n" <<
428
+ "key_count: " << num(info.key_count) << "\n" <<
429
+ "value_count: " << num(info.value_count) << "\n" <<
430
+ "value_bytes: " << num(info.value_bytes) << "\n" <<
431
+ "spill_count: " << num(info.spill_count) << "\n" <<
432
+ "spill_count_tot: " << num(info.spill_count_tot) << "\n" <<
433
+ "spill_bytes: " << num(info.spill_bytes) << "\n" <<
434
+ "spill_bytes_tot: " << num(info.spill_bytes_tot) << "\n" <<
435
+ "key_file_size: " << num(info.key_file_size) << "\n" <<
436
+ "dat_file_size: " << num(info.dat_file_size) << std::endl;
437
+
438
+ std::string s;
439
+ for (size_t i = 0; i < info.hist.size(); ++i)
440
+ s += (i==0) ?
441
+ std::to_string(info.hist[i]) :
442
+ (", " + std::to_string(info.hist[i]));
443
+ os << "hist: " << s << std::endl;
444
+ return os;
445
+ }
446
+
447
+ } // test
448
+ } // nudb
449
+
450
+ #endif
451
+
@@ -0,0 +1,105 @@
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_TEST_XOR_SHIFT_ENGINE_HPP
9
+ #define NUDB_TEST_XOR_SHIFT_ENGINE_HPP
10
+
11
+ #include <cstdint>
12
+ #include <limits>
13
+ #include <stdexcept>
14
+
15
+ namespace nudb {
16
+ namespace test {
17
+
18
+ /** XOR-shift Generator.
19
+
20
+ Meets the requirements of UniformRandomNumberGenerator.
21
+
22
+ Simple and fast RNG based on:
23
+ http://xorshift.di.unimi.it/xorshift128plus.c
24
+ does not accept seed==0
25
+ */
26
+ class xor_shift_engine
27
+ {
28
+ public:
29
+ using result_type = std::uint64_t;
30
+
31
+ xor_shift_engine(xor_shift_engine const&) = default;
32
+ xor_shift_engine& operator=(xor_shift_engine const&) = default;
33
+
34
+ explicit
35
+ xor_shift_engine(result_type val = 1977u)
36
+ {
37
+ seed(val);
38
+ }
39
+
40
+ void
41
+ seed(result_type seed);
42
+
43
+ result_type
44
+ operator()();
45
+
46
+ static
47
+ result_type constexpr
48
+ min()
49
+ {
50
+ return std::numeric_limits<result_type>::min();
51
+ }
52
+
53
+ static
54
+ result_type constexpr
55
+ max()
56
+ {
57
+ return std::numeric_limits<result_type>::max();
58
+ }
59
+
60
+ private:
61
+ result_type s_[2];
62
+
63
+ static
64
+ result_type
65
+ murmurhash3(result_type x);
66
+ };
67
+
68
+ inline
69
+ void
70
+ xor_shift_engine::seed(result_type seed)
71
+ {
72
+ if(seed == 0)
73
+ throw std::domain_error("invalid seed");
74
+ s_[0] = murmurhash3(seed);
75
+ s_[1] = murmurhash3(s_[0]);
76
+ }
77
+
78
+ inline
79
+ auto
80
+ xor_shift_engine::operator()() ->
81
+ result_type
82
+ {
83
+ result_type s1 = s_[0];
84
+ result_type const s0 = s_[1];
85
+ s_[0] = s0;
86
+ s1 ^= s1<< 23;
87
+ return(s_[1] =(s1 ^ s0 ^(s1 >> 17) ^(s0 >> 26))) + s0;
88
+ }
89
+
90
+ inline
91
+ auto
92
+ xor_shift_engine::murmurhash3(result_type x)
93
+ -> result_type
94
+ {
95
+ x ^= x >> 33;
96
+ x *= 0xff51afd7ed558ccdULL;
97
+ x ^= x >> 33;
98
+ x *= 0xc4ceb9fe1a85ec53ULL;
99
+ return x ^= x >> 33;
100
+ }
101
+
102
+ } // test
103
+ } // nudb
104
+
105
+ #endif