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,259 @@
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_GENTEX_HPP
9
+ #define NUDB_DETAIL_GENTEX_HPP
10
+
11
+ #include <boost/assert.hpp>
12
+ #include <condition_variable>
13
+ #include <cstddef>
14
+ #include <mutex>
15
+ #include <system_error>
16
+
17
+ namespace nudb {
18
+ namespace detail {
19
+
20
+ // Generation counting mutex
21
+ //
22
+ template<class = void>
23
+ class gentex_t
24
+ {
25
+ private:
26
+ std::mutex m_;
27
+ std::size_t gen_ = 0;
28
+ std::size_t cur_ = 0;
29
+ std::size_t prev_ = 0;
30
+ std::condition_variable cond_;
31
+
32
+ public:
33
+ gentex_t() = default;
34
+ gentex_t(gentex_t const&) = delete;
35
+ gentex_t& operator=(gentex_t const&) = delete;
36
+
37
+ void
38
+ start();
39
+
40
+ void
41
+ finish();
42
+
43
+ std::size_t
44
+ lock_gen();
45
+
46
+ void
47
+ unlock_gen(std::size_t gen);
48
+ };
49
+
50
+ template<class _>
51
+ void
52
+ gentex_t<_>::
53
+ start()
54
+ {
55
+ std::unique_lock<std::mutex> l{m_};
56
+ prev_ += cur_;
57
+ cur_ = 0;
58
+ ++gen_;
59
+ }
60
+
61
+ template<class _>
62
+ void
63
+ gentex_t<_>::
64
+ finish()
65
+ {
66
+ std::unique_lock<std::mutex> l{m_};
67
+ while(prev_ > 0)
68
+ cond_.wait(l);
69
+ }
70
+
71
+ template<class _>
72
+ std::size_t
73
+ gentex_t<_>::
74
+ lock_gen()
75
+ {
76
+ std::lock_guard<
77
+ std::mutex> l{m_};
78
+ ++cur_;
79
+ return gen_;
80
+ }
81
+
82
+ template<class _>
83
+ void
84
+ gentex_t<_>::
85
+ unlock_gen(std::size_t gen)
86
+ {
87
+ std::unique_lock<std::mutex> l{m_};
88
+ if(gen == gen_)
89
+ {
90
+ --cur_;
91
+ }
92
+ else
93
+ {
94
+ --prev_;
95
+ if(prev_ == 0)
96
+ cond_.notify_all();
97
+ }
98
+ }
99
+
100
+ using gentex = gentex_t<>;
101
+
102
+ //------------------------------------------------------------------------------
103
+
104
+ template<class GenerationLockable>
105
+ class genlock
106
+ {
107
+ private:
108
+ bool owned_ = false;
109
+ GenerationLockable* g_ = nullptr;
110
+ std::size_t gen_;
111
+
112
+ public:
113
+ using mutex_type = GenerationLockable;
114
+
115
+ genlock() = default;
116
+ genlock(genlock const&) = delete;
117
+ genlock& operator=(genlock const&) = delete;
118
+
119
+ genlock(genlock&& other);
120
+
121
+ genlock& operator=(genlock&& other);
122
+
123
+ explicit
124
+ genlock(mutex_type& g);
125
+
126
+ genlock(mutex_type& g, std::defer_lock_t);
127
+
128
+ ~genlock();
129
+
130
+ mutex_type*
131
+ mutex() noexcept
132
+ {
133
+ return g_;
134
+ }
135
+
136
+ bool
137
+ owns_lock() const noexcept
138
+ {
139
+ return g_ && owned_;
140
+ }
141
+
142
+ explicit
143
+ operator bool() const noexcept
144
+ {
145
+ return owns_lock();
146
+ }
147
+
148
+ void
149
+ lock();
150
+
151
+ void
152
+ unlock();
153
+
154
+ mutex_type*
155
+ release() noexcept;
156
+
157
+ template<class U>
158
+ friend
159
+ void
160
+ swap(genlock<U>& lhs, genlock<U>& rhs) noexcept;
161
+ };
162
+
163
+ template<class G>
164
+ genlock<G>::
165
+ genlock(genlock&& other)
166
+ : owned_(other.owned_)
167
+ , g_(other.g_)
168
+ {
169
+ other.owned_ = false;
170
+ other.g_ = nullptr;
171
+ }
172
+
173
+ template<class G>
174
+ genlock<G>&
175
+ genlock<G>::
176
+ operator=(genlock&& other)
177
+ {
178
+ if(owns_lock())
179
+ unlock();
180
+ owned_ = other.owned_;
181
+ g_ = other.g_;
182
+ other.owned_ = false;
183
+ other.g_ = nullptr;
184
+ return *this;
185
+ }
186
+
187
+ template<class G>
188
+ genlock<G>::
189
+ genlock(mutex_type& g)
190
+ : g_(&g)
191
+ {
192
+ lock();
193
+ }
194
+
195
+ template<class G>
196
+ genlock<G>::
197
+ genlock(mutex_type& g, std::defer_lock_t)
198
+ : g_(&g)
199
+ {
200
+ }
201
+
202
+ template<class G>
203
+ genlock<G>::
204
+ ~genlock()
205
+ {
206
+ if(owns_lock())
207
+ unlock();
208
+ }
209
+
210
+ template<class G>
211
+ void
212
+ genlock<G>::
213
+ lock()
214
+ {
215
+ // no associated gentex
216
+ BOOST_ASSERT(g_ != nullptr);
217
+ // gentex is already owned
218
+ BOOST_ASSERT(! owned_);
219
+ gen_ = g_->lock_gen();
220
+ owned_ = true;
221
+ }
222
+
223
+ template<class G>
224
+ void
225
+ genlock<G>::
226
+ unlock()
227
+ {
228
+ // no associated gentex
229
+ BOOST_ASSERT(g_ != nullptr);
230
+ // gentex is not owned
231
+ BOOST_ASSERT(owned_);
232
+ g_->unlock_gen(gen_);
233
+ owned_ = false;
234
+ }
235
+
236
+ template<class G>
237
+ auto
238
+ genlock<G>::
239
+ release() noexcept ->
240
+ mutex_type*
241
+ {
242
+ mutex_type* const g = g_;
243
+ g_ = nullptr;
244
+ return g;
245
+ }
246
+
247
+ template<class G>
248
+ void
249
+ swap(genlock<G>& lhs, genlock<G>& rhs) noexcept
250
+ {
251
+ using namespace std;
252
+ swap(lhs.owned_, rhs.owned_);
253
+ swap(lhs.g_, rhs.g_);
254
+ }
255
+
256
+ } // detail
257
+ } // nudb
258
+
259
+ #endif
@@ -0,0 +1,26 @@
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_MUTEX_HPP
9
+ #define NUDB_DETAIL_MUTEX_HPP
10
+
11
+ #include <boost/thread/lock_types.hpp>
12
+ #include <boost/thread/shared_mutex.hpp>
13
+
14
+ namespace nudb {
15
+ namespace detail {
16
+
17
+ using shared_lock_type =
18
+ boost::shared_lock<boost::shared_mutex>;
19
+
20
+ using unique_lock_type =
21
+ boost::unique_lock<boost::shared_mutex>;
22
+
23
+ } // detail
24
+ } // nudb
25
+
26
+ #endif
@@ -0,0 +1,243 @@
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_POOL_HPP
9
+ #define NUDB_DETAIL_POOL_HPP
10
+
11
+ #include <nudb/detail/arena.hpp>
12
+ #include <nudb/detail/bucket.hpp>
13
+ #include <nudb/detail/format.hpp>
14
+ #include <boost/assert.hpp>
15
+ #include <boost/thread/lock_types.hpp>
16
+ #include <cstdint>
17
+ #include <cstring>
18
+ #include <memory>
19
+ #include <map>
20
+ #include <utility>
21
+
22
+ namespace nudb {
23
+ namespace detail {
24
+
25
+ // Buffers key/value pairs in a map, associating
26
+ // them with a modifiable data file offset.
27
+ template<class = void>
28
+ class pool_t
29
+ {
30
+ public:
31
+ struct value_type;
32
+ class compare;
33
+
34
+ private:
35
+ using map_type = std::map<
36
+ value_type, noff_t, compare>;
37
+
38
+ arena arena_;
39
+ nsize_t key_size_;
40
+ nsize_t data_size_ = 0;
41
+ map_type map_;
42
+
43
+ public:
44
+ using iterator =
45
+ typename map_type::iterator;
46
+
47
+ pool_t(pool_t const&) = delete;
48
+ pool_t& operator=(pool_t const&) = delete;
49
+
50
+ pool_t(pool_t&& other);
51
+
52
+ pool_t(nsize_t key_size, char const* label);
53
+
54
+ iterator
55
+ begin()
56
+ {
57
+ return map_.begin();
58
+ }
59
+
60
+ iterator
61
+ end()
62
+ {
63
+ return map_.end();
64
+ }
65
+
66
+ bool
67
+ empty() const
68
+ {
69
+ return map_.size() == 0;
70
+ }
71
+
72
+ // Returns the number of elements in the pool
73
+ std::size_t
74
+ size() const
75
+ {
76
+ return map_.size();
77
+ }
78
+
79
+ // Returns the sum of data sizes in the pool
80
+ std::size_t
81
+ data_size() const
82
+ {
83
+ return data_size_;
84
+ }
85
+
86
+ void
87
+ clear();
88
+
89
+ void
90
+ periodic_activity();
91
+
92
+ iterator
93
+ find(void const* key);
94
+
95
+ // Insert a value
96
+ // @param h The hash of the key
97
+ void
98
+ insert(nhash_t h, void const* key,
99
+ void const* buffer, nsize_t size);
100
+
101
+ template<class U>
102
+ friend
103
+ void
104
+ swap(pool_t<U>& lhs, pool_t<U>& rhs);
105
+ };
106
+
107
+ template<class _>
108
+ struct pool_t<_>::value_type
109
+ {
110
+ nhash_t hash;
111
+ nsize_t size;
112
+ void const* key;
113
+ void const* data;
114
+
115
+ value_type(value_type const&) = default;
116
+ value_type& operator=(value_type const&) = default;
117
+
118
+ value_type(nhash_t hash_, nsize_t size_,
119
+ void const* key_, void const* data_)
120
+ : hash(hash_)
121
+ , size(size_)
122
+ , key(key_)
123
+ , data(data_)
124
+ {
125
+ }
126
+ };
127
+
128
+ template<class _>
129
+ class pool_t<_>::compare
130
+ {
131
+ std::size_t key_size_;
132
+
133
+ public:
134
+ using result_type = bool;
135
+ using first_argument_type = value_type;
136
+ using second_argument_type = value_type;
137
+
138
+ compare(compare const&) = default;
139
+ compare& operator=(compare const&) = default;
140
+
141
+ explicit
142
+ compare(nsize_t key_size)
143
+ : key_size_(key_size)
144
+ {
145
+ }
146
+
147
+ bool
148
+ operator()(value_type const& lhs,
149
+ value_type const& rhs) const
150
+ {
151
+ return std::memcmp(
152
+ lhs.key, rhs.key, key_size_) < 0;
153
+ }
154
+ };
155
+
156
+ //------------------------------------------------------------------------------
157
+
158
+ template<class _>
159
+ pool_t<_>::
160
+ pool_t(pool_t&& other)
161
+ : arena_(std::move(other.arena_))
162
+ , key_size_(other.key_size_)
163
+ , data_size_(other.data_size_)
164
+ , map_(std::move(other.map_))
165
+ {
166
+ }
167
+
168
+ template<class _>
169
+ pool_t<_>::
170
+ pool_t(nsize_t key_size, char const* label)
171
+ : arena_(label)
172
+ , key_size_(key_size)
173
+ , map_(compare{key_size})
174
+ {
175
+ }
176
+
177
+ template<class _>
178
+ void
179
+ pool_t<_>::
180
+ clear()
181
+ {
182
+ arena_.clear();
183
+ data_size_ = 0;
184
+ map_.clear();
185
+ }
186
+
187
+ template<class _>
188
+ void
189
+ pool_t<_>::
190
+ periodic_activity()
191
+ {
192
+ arena_.periodic_activity();
193
+ }
194
+
195
+ template<class _>
196
+ auto
197
+ pool_t<_>::
198
+ find(void const* key) ->
199
+ iterator
200
+ {
201
+ // VFALCO need is_transparent here
202
+ value_type tmp{0, 0, key, nullptr};
203
+ auto const iter = map_.find(tmp);
204
+ return iter;
205
+ }
206
+
207
+ template<class _>
208
+ void
209
+ pool_t<_>::
210
+ insert(nhash_t h,
211
+ void const* key, void const* data, nsize_t size)
212
+ {
213
+ auto const k = arena_.alloc(key_size_);
214
+ auto const d = arena_.alloc(size);
215
+ std::memcpy(k, key, key_size_);
216
+ std::memcpy(d, data, size);
217
+ auto const result = map_.emplace(
218
+ std::piecewise_construct,
219
+ std::make_tuple(h, size, k, d),
220
+ std::make_tuple(0));
221
+ (void)result.second;
222
+ // Must not already exist!
223
+ BOOST_ASSERT(result.second);
224
+ data_size_ += size;
225
+ }
226
+
227
+ template<class _>
228
+ void
229
+ swap(pool_t<_>& lhs, pool_t<_>& rhs)
230
+ {
231
+ using std::swap;
232
+ swap(lhs.arena_, rhs.arena_);
233
+ swap(lhs.key_size_, rhs.key_size_);
234
+ swap(lhs.data_size_, rhs.data_size_);
235
+ swap(lhs.map_, rhs.map_);
236
+ }
237
+
238
+ using pool = pool_t<>;
239
+
240
+ } // detail
241
+ } // nudb
242
+
243
+ #endif
@@ -0,0 +1,45 @@
1
+ //
2
+ // Copyright (c) 2019 Miguel Portilla (miguelportilla64 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_STORE_BASE_HPP
9
+ #define NUDB_DETAIL_STORE_BASE_HPP
10
+
11
+ namespace nudb {
12
+
13
+ class context;
14
+
15
+ namespace detail {
16
+
17
+ class store_base
18
+ {
19
+ protected:
20
+ friend class nudb::context;
21
+
22
+ virtual void flush() = 0;
23
+
24
+ private:
25
+ #if ! NUDB_DOXYGEN
26
+ friend class test::context_test;
27
+ #endif
28
+
29
+ enum class state
30
+ {
31
+ waiting,
32
+ flushing,
33
+ intermediate,
34
+ none
35
+ };
36
+
37
+ store_base* next_ = nullptr;
38
+ store_base* prev_ = nullptr;
39
+ state state_ = state::none;
40
+ };
41
+
42
+ } // detail
43
+ } // nudb
44
+
45
+ #endif
@@ -0,0 +1,149 @@
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_STREAM_HPP
9
+ #define NUDB_DETAIL_STREAM_HPP
10
+
11
+ #include <boost/assert.hpp>
12
+ #include <array>
13
+ #include <cstddef>
14
+ #include <cstdint>
15
+ #include <cstring>
16
+ #include <memory>
17
+
18
+ namespace nudb {
19
+ namespace detail {
20
+
21
+ // Input stream from bytes
22
+ template<class = void>
23
+ class istream_t
24
+ {
25
+ std::uint8_t const* buf_ = nullptr;
26
+ std::size_t size_ = 0;
27
+
28
+ public:
29
+ istream_t() = default;
30
+ istream_t(istream_t const&) = default;
31
+ istream_t& operator=(istream_t const&) = default;
32
+
33
+ istream_t(void const* data, std::size_t size)
34
+ : buf_(reinterpret_cast<std::uint8_t const*>(data))
35
+ , size_(size)
36
+ {
37
+ }
38
+
39
+ template<std::size_t N>
40
+ istream_t(std::array<std::uint8_t, N> const& a)
41
+ : buf_(a.data())
42
+ , size_(a.size())
43
+ {
44
+ }
45
+
46
+ std::uint8_t const*
47
+ data(std::size_t bytes);
48
+
49
+ std::uint8_t const*
50
+ operator()(std::size_t bytes)
51
+ {
52
+ return data(bytes);
53
+ }
54
+ };
55
+
56
+ // Precondition: bytes <= size_
57
+ //
58
+ template<class _>
59
+ std::uint8_t const*
60
+ istream_t<_>::data(std::size_t bytes)
61
+ {
62
+ BOOST_ASSERT(bytes <= size_);
63
+ if(size_ < bytes)
64
+ throw std::logic_error("short read from istream");
65
+ auto const data = buf_;
66
+ buf_ = buf_ + bytes;
67
+ size_ -= bytes;
68
+ return data;
69
+ }
70
+
71
+ using istream = istream_t<>;
72
+
73
+ //------------------------------------------------------------------------------
74
+
75
+ // Output stream to bytes
76
+ // VFALCO Should this assert on overwriting the buffer?
77
+ template<class = void>
78
+ class ostream_t
79
+ {
80
+ std::uint8_t* buf_ = nullptr;
81
+ std::size_t size_ = 0;
82
+
83
+ public:
84
+ ostream_t() = default;
85
+ ostream_t(ostream_t const&) = default;
86
+ ostream_t& operator=(ostream_t const&) = default;
87
+
88
+ ostream_t(void* data, std::size_t)
89
+ : buf_(reinterpret_cast<std::uint8_t*>(data))
90
+ {
91
+ }
92
+
93
+ template<std::size_t N>
94
+ ostream_t(std::array<std::uint8_t, N>& a)
95
+ : buf_(a.data())
96
+ {
97
+ }
98
+
99
+ // Returns the number of bytes written
100
+ std::size_t
101
+ size() const
102
+ {
103
+ return size_;
104
+ }
105
+
106
+ std::uint8_t*
107
+ data(std::size_t bytes);
108
+
109
+ std::uint8_t*
110
+ operator()(std::size_t bytes)
111
+ {
112
+ return data(bytes);
113
+ }
114
+ };
115
+
116
+ template<class _>
117
+ std::uint8_t*
118
+ ostream_t<_>::data(std::size_t bytes)
119
+ {
120
+ auto const data = buf_;
121
+ buf_ = buf_ + bytes;
122
+ size_ += bytes;
123
+ return data;
124
+ }
125
+
126
+ using ostream = ostream_t<>;
127
+
128
+ //------------------------------------------------------------------------------
129
+
130
+ // read blob
131
+ inline
132
+ void
133
+ read(istream& is, void* buffer, std::size_t bytes)
134
+ {
135
+ std::memcpy(buffer, is.data(bytes), bytes);
136
+ }
137
+
138
+ // write blob
139
+ inline
140
+ void
141
+ write(ostream& os, void const* buffer, std::size_t bytes)
142
+ {
143
+ std::memcpy(os.data(bytes), buffer, bytes);
144
+ }
145
+
146
+ } // detail
147
+ } // nudb
148
+
149
+ #endif