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