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,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