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,196 @@
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_BULKIO_HPP
9
+ #define NUDB_DETAIL_BULKIO_HPP
10
+
11
+ #include <nudb/type_traits.hpp>
12
+ #include <nudb/detail/buffer.hpp>
13
+ #include <nudb/detail/stream.hpp>
14
+ #include <nudb/error.hpp>
15
+ #include <algorithm>
16
+ #include <cstddef>
17
+
18
+ namespace nudb {
19
+ namespace detail {
20
+
21
+ // Scans a file in sequential large reads
22
+ template<class File>
23
+ class bulk_reader
24
+ {
25
+ File& f_;
26
+ buffer buf_;
27
+ noff_t last_; // size of file
28
+ noff_t offset_; // current position
29
+ std::size_t avail_; // bytes left to read in buf
30
+ std::size_t used_; // bytes consumed in buf
31
+
32
+ public:
33
+ bulk_reader(File& f, noff_t offset,
34
+ noff_t last, std::size_t buffer_size);
35
+
36
+ noff_t
37
+ offset() const
38
+ {
39
+ return offset_ - avail_;
40
+ }
41
+
42
+ bool
43
+ eof() const
44
+ {
45
+ return offset() >= last_;
46
+ }
47
+
48
+ istream
49
+ prepare(std::size_t needed, error_code& ec);
50
+ };
51
+
52
+ template<class File>
53
+ bulk_reader<File>::
54
+ bulk_reader(File& f, noff_t offset,
55
+ noff_t last, std::size_t buffer_size)
56
+ : f_(f)
57
+ , last_(last)
58
+ , offset_(offset)
59
+ , avail_(0)
60
+ , used_(0)
61
+ {
62
+ buf_.reserve(buffer_size);
63
+ }
64
+
65
+ template<class File>
66
+ istream
67
+ bulk_reader<File>::
68
+ prepare(std::size_t needed, error_code& ec)
69
+ {
70
+ if(needed > avail_)
71
+ {
72
+ if(offset_ + needed - avail_ > last_)
73
+ {
74
+ ec = error::short_read;
75
+ return {};
76
+ }
77
+ if(needed > buf_.size())
78
+ {
79
+ buffer buf;
80
+ buf.reserve(needed);
81
+ std::memcpy(buf.get(),
82
+ buf_.get() + used_, avail_);
83
+ buf_ = std::move(buf);
84
+ }
85
+ else
86
+ {
87
+ std::memmove(buf_.get(),
88
+ buf_.get() + used_, avail_);
89
+ }
90
+
91
+ auto const n = std::min(buf_.size() - avail_,
92
+ static_cast<std::size_t>(last_ - offset_));
93
+ f_.read(offset_, buf_.get() + avail_, n, ec);
94
+ if(ec)
95
+ return {};
96
+ offset_ += n;
97
+ avail_ += n;
98
+ used_ = 0;
99
+ }
100
+ istream is{buf_.get() + used_, needed};
101
+ used_ += needed;
102
+ avail_ -= needed;
103
+ return is;
104
+ }
105
+
106
+ //------------------------------------------------------------------------------
107
+
108
+ // Buffers file writes
109
+ // Caller must call flush manually at the end
110
+ template<class File>
111
+ class bulk_writer
112
+ {
113
+ File& f_;
114
+ buffer buf_;
115
+ noff_t offset_; // current position
116
+ std::size_t used_; // bytes written to buf
117
+
118
+ public:
119
+ bulk_writer(File& f, noff_t offset,
120
+ std::size_t buffer_size);
121
+
122
+ ostream
123
+ prepare(std::size_t needed, error_code& ec);
124
+
125
+ // Returns the number of bytes buffered
126
+ std::size_t
127
+ size()
128
+ {
129
+ return used_;
130
+ }
131
+
132
+ // Return current offset in file. This
133
+ // is advanced with each call to prepare.
134
+ noff_t
135
+ offset() const
136
+ {
137
+ return offset_ + used_;
138
+ }
139
+
140
+ // Caller must invoke flush manually in
141
+ // order to handle any error conditions.
142
+ void
143
+ flush(error_code& ec);
144
+ };
145
+
146
+ template<class File>
147
+ bulk_writer<File>::
148
+ bulk_writer(File& f,
149
+ noff_t offset, std::size_t buffer_size)
150
+ : f_(f)
151
+ , offset_(offset)
152
+ , used_(0)
153
+
154
+ {
155
+ buf_.reserve(buffer_size);
156
+ }
157
+
158
+ template<class File>
159
+ ostream
160
+ bulk_writer<File>::
161
+ prepare(std::size_t needed, error_code& ec)
162
+ {
163
+ if(used_ + needed > buf_.size())
164
+ {
165
+ flush(ec);
166
+ if(ec)
167
+ return{};
168
+ }
169
+ if(needed > buf_.size())
170
+ buf_.reserve(needed);
171
+ ostream os(buf_.get() + used_, needed);
172
+ used_ += needed;
173
+ return os;
174
+ }
175
+
176
+ template<class File>
177
+ void
178
+ bulk_writer<File>::
179
+ flush(error_code& ec)
180
+ {
181
+ if(used_)
182
+ {
183
+ auto const offset = offset_;
184
+ auto const used = used_;
185
+ offset_ += used_;
186
+ used_ = 0;
187
+ f_.write(offset, buf_.get(), used, ec);
188
+ if(ec)
189
+ return;
190
+ }
191
+ }
192
+
193
+ } // detail
194
+ } // nudb
195
+
196
+ #endif
@@ -0,0 +1,236 @@
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_CACHE_HPP
9
+ #define NUDB_DETAIL_CACHE_HPP
10
+
11
+ #include <nudb/detail/arena.hpp>
12
+ #include <nudb/detail/bucket.hpp>
13
+ #include <nudb/detail/format.hpp>
14
+ #include <boost/iterator/transform_iterator.hpp>
15
+ #include <algorithm>
16
+ #include <cstdint>
17
+ #include <utility>
18
+ #include <vector>
19
+ #include <unordered_map>
20
+
21
+ namespace nudb {
22
+ namespace detail {
23
+
24
+ // Associative container storing
25
+ // bucket blobs keyed by bucket index.
26
+ //
27
+ template<class = void>
28
+ class cache_t
29
+ {
30
+ public:
31
+ using value_type = std::pair<nbuck_t, bucket>;
32
+
33
+ private:
34
+ using map_type =
35
+ std::unordered_map<nbuck_t, void*>;
36
+
37
+ struct transform
38
+ {
39
+ using argument_type =
40
+ typename map_type::value_type;
41
+ using result_type = value_type;
42
+
43
+ cache_t* cache_;
44
+
45
+ transform()
46
+ : cache_(nullptr)
47
+ {
48
+ }
49
+
50
+ explicit
51
+ transform(cache_t& cache)
52
+ : cache_(&cache)
53
+ {
54
+ }
55
+
56
+ value_type
57
+ operator()(argument_type const& e) const
58
+ {
59
+ return std::make_pair(e.first,
60
+ bucket{cache_->block_size_, e.second});
61
+ }
62
+ };
63
+
64
+ nsize_t key_size_ = 0;
65
+ nsize_t block_size_ = 0;
66
+ arena arena_;
67
+ map_type map_;
68
+
69
+ public:
70
+ using iterator = boost::transform_iterator<
71
+ transform, typename map_type::iterator,
72
+ value_type, value_type>;
73
+
74
+ cache_t(cache_t const&) = delete;
75
+ cache_t& operator=(cache_t&&) = delete;
76
+ cache_t& operator=(cache_t const&) = delete;
77
+
78
+ // Constructs a cache that will never have inserts
79
+ cache_t() = default;
80
+
81
+ cache_t(cache_t&& other);
82
+
83
+ explicit
84
+ cache_t(nsize_t key_size,
85
+ nsize_t block_size, char const* label);
86
+
87
+ std::size_t
88
+ size() const
89
+ {
90
+ return map_.size();
91
+ }
92
+
93
+ iterator
94
+ begin()
95
+ {
96
+ return iterator{map_.begin(), transform{*this}};
97
+ }
98
+
99
+ iterator
100
+ end()
101
+ {
102
+ return iterator{map_.end(), transform{*this}};
103
+ }
104
+
105
+ bool
106
+ empty() const
107
+ {
108
+ return map_.empty();
109
+ }
110
+
111
+ void
112
+ clear();
113
+
114
+ void
115
+ reserve(std::size_t n);
116
+
117
+ void
118
+ periodic_activity();
119
+
120
+ iterator
121
+ find(nbuck_t n);
122
+
123
+ // Create an empty bucket
124
+ //
125
+ bucket
126
+ create(nbuck_t n);
127
+
128
+ // Insert a copy of a bucket.
129
+ //
130
+ iterator
131
+ insert(nbuck_t n, bucket const& b);
132
+
133
+ template<class U>
134
+ friend
135
+ void
136
+ swap(cache_t<U>& lhs, cache_t<U>& rhs);
137
+ };
138
+
139
+ template<class _>
140
+ cache_t<_>::
141
+ cache_t(cache_t&& other)
142
+ : key_size_{other.key_size_}
143
+ , block_size_(other.block_size_)
144
+ , arena_(std::move(other.arena_))
145
+ , map_(std::move(other.map_))
146
+ {
147
+ }
148
+
149
+ template<class _>
150
+ cache_t<_>::
151
+ cache_t(nsize_t key_size,
152
+ nsize_t block_size, char const* label)
153
+ : key_size_(key_size)
154
+ , block_size_(block_size)
155
+ , arena_(label)
156
+ {
157
+ }
158
+
159
+ template<class _>
160
+ void
161
+ cache_t<_>::
162
+ reserve(std::size_t n)
163
+ {
164
+ arena_.hint(n * block_size_);
165
+ map_.reserve(n);
166
+ }
167
+
168
+ template<class _>
169
+ void
170
+ cache_t<_>::
171
+ clear()
172
+ {
173
+ arena_.clear();
174
+ map_.clear();
175
+ }
176
+
177
+ template<class _>
178
+ void
179
+ cache_t<_>::
180
+ periodic_activity()
181
+ {
182
+ arena_.periodic_activity();
183
+ }
184
+
185
+ template<class _>
186
+ auto
187
+ cache_t<_>::
188
+ find(nbuck_t n) ->
189
+ iterator
190
+ {
191
+ auto const iter = map_.find(n);
192
+ if(iter == map_.end())
193
+ return iterator{map_.end(), transform(*this)};
194
+ return iterator{iter, transform(*this)};
195
+ }
196
+
197
+ template<class _>
198
+ bucket
199
+ cache_t<_>::
200
+ create(nbuck_t n)
201
+ {
202
+ auto const p = arena_.alloc(block_size_);
203
+ map_.emplace(n, p);
204
+ return bucket{block_size_, p, detail::empty};
205
+ }
206
+
207
+ template<class _>
208
+ auto
209
+ cache_t<_>::
210
+ insert(nbuck_t n, bucket const& b) ->
211
+ iterator
212
+ {
213
+ void* const p = arena_.alloc(b.block_size());
214
+ ostream os{p, b.block_size()};
215
+ b.write(os);
216
+ auto const result = map_.emplace(n, p);
217
+ return iterator{result.first, transform(*this)};
218
+ }
219
+
220
+ template<class U>
221
+ void
222
+ swap(cache_t<U>& lhs, cache_t<U>& rhs)
223
+ {
224
+ using std::swap;
225
+ swap(lhs.key_size_, rhs.key_size_);
226
+ swap(lhs.block_size_, rhs.block_size_);
227
+ swap(lhs.arena_, rhs.arena_);
228
+ swap(lhs.map_, rhs.map_);
229
+ }
230
+
231
+ using cache = cache_t<>;
232
+
233
+ } // detail
234
+ } // nudb
235
+
236
+ #endif
@@ -0,0 +1,93 @@
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_ENDIAN_HPP
9
+ #define NUDB_DETAIL_ENDIAN_HPP
10
+
11
+ #include <cstdint>
12
+ #include <type_traits>
13
+
14
+ namespace nudb {
15
+ namespace detail {
16
+
17
+ // This is a modified work, original implementation
18
+ // by Howard Hinnant <howard.hinnant@gmail.com>
19
+ //
20
+ // "This should be standardized" - Howard
21
+
22
+ // Endian provides answers to the following questions:
23
+ // 1. Is this system big or little endian?
24
+ // 2. Is the "desired endian" of some class or function the same as the
25
+ // native endian?
26
+ enum class endian
27
+ {
28
+ #ifdef _MSC_VER
29
+ big = 1,
30
+ little = 0,
31
+ native = little
32
+ #else
33
+ native = __BYTE_ORDER__,
34
+ little = __ORDER_LITTLE_ENDIAN__,
35
+ big = __ORDER_BIG_ENDIAN__
36
+ #endif
37
+ };
38
+
39
+ using is_little_endian =
40
+ std::integral_constant<bool,
41
+ endian::native == endian::little>;
42
+
43
+ static_assert(
44
+ endian::native == endian::little || endian::native == endian::big,
45
+ "endian::native shall be one of endian::little or endian::big");
46
+
47
+ static_assert(
48
+ endian::big != endian::little,
49
+ "endian::big and endian::little shall have different values");
50
+
51
+ // The pepper got baked into the file format as
52
+ // the hash of the little endian salt so now we
53
+ // need this function.
54
+ //
55
+ template<class = void>
56
+ std::uint64_t
57
+ to_little_endian(std::uint64_t v, std::false_type)
58
+ {
59
+ union U
60
+ {
61
+ std::uint64_t vi;
62
+ std::uint8_t va[8];
63
+ };
64
+ U u;
65
+ u.va[0] = v & 0xff;
66
+ u.va[1] = (v >> 8) & 0xff;
67
+ u.va[2] = (v >> 16) & 0xff;
68
+ u.va[3] = (v >> 24) & 0xff;
69
+ u.va[4] = (v >> 32) & 0xff;
70
+ u.va[5] = (v >> 40) & 0xff;
71
+ u.va[6] = (v >> 48) & 0xff;
72
+ u.va[7] = (v >> 56) & 0xff;
73
+ return u.vi;
74
+ }
75
+
76
+ inline
77
+ std::uint64_t
78
+ to_little_endian(std::uint64_t v, std::true_type)
79
+ {
80
+ return v;
81
+ }
82
+
83
+ inline
84
+ std::uint64_t
85
+ to_little_endian(std::uint64_t v)
86
+ {
87
+ return to_little_endian(v, is_little_endian{});
88
+ }
89
+
90
+ } // detail
91
+ } // nudb
92
+
93
+ #endif