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.
- checksums.yaml +7 -0
- data/.yardopts +1 -0
- data/LICENSE.txt +22 -0
- data/README.md +26 -0
- data/examples/example.rb +39 -0
- data/ext/rudb/NuDB/include/nudb/CMakeLists.txt +104 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/basic_seconds_clock.hpp +200 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/chrono_util.hpp +58 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/fail_file.hpp +343 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/temp_dir.hpp +73 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/test_store.hpp +451 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/test/xor_shift_engine.hpp +105 -0
- data/ext/rudb/NuDB/include/nudb/_experimental/util.hpp +288 -0
- data/ext/rudb/NuDB/include/nudb/basic_store.hpp +461 -0
- data/ext/rudb/NuDB/include/nudb/concepts.hpp +205 -0
- data/ext/rudb/NuDB/include/nudb/context.hpp +144 -0
- data/ext/rudb/NuDB/include/nudb/create.hpp +117 -0
- data/ext/rudb/NuDB/include/nudb/detail/arena.hpp +296 -0
- data/ext/rudb/NuDB/include/nudb/detail/bucket.hpp +473 -0
- data/ext/rudb/NuDB/include/nudb/detail/buffer.hpp +86 -0
- data/ext/rudb/NuDB/include/nudb/detail/bulkio.hpp +196 -0
- data/ext/rudb/NuDB/include/nudb/detail/cache.hpp +236 -0
- data/ext/rudb/NuDB/include/nudb/detail/endian.hpp +93 -0
- data/ext/rudb/NuDB/include/nudb/detail/field.hpp +265 -0
- data/ext/rudb/NuDB/include/nudb/detail/format.hpp +630 -0
- data/ext/rudb/NuDB/include/nudb/detail/gentex.hpp +259 -0
- data/ext/rudb/NuDB/include/nudb/detail/mutex.hpp +26 -0
- data/ext/rudb/NuDB/include/nudb/detail/pool.hpp +243 -0
- data/ext/rudb/NuDB/include/nudb/detail/store_base.hpp +45 -0
- data/ext/rudb/NuDB/include/nudb/detail/stream.hpp +149 -0
- data/ext/rudb/NuDB/include/nudb/detail/xxhash.hpp +328 -0
- data/ext/rudb/NuDB/include/nudb/error.hpp +257 -0
- data/ext/rudb/NuDB/include/nudb/file.hpp +55 -0
- data/ext/rudb/NuDB/include/nudb/impl/basic_store.ipp +785 -0
- data/ext/rudb/NuDB/include/nudb/impl/context.ipp +241 -0
- data/ext/rudb/NuDB/include/nudb/impl/create.ipp +163 -0
- data/ext/rudb/NuDB/include/nudb/impl/error.ipp +175 -0
- data/ext/rudb/NuDB/include/nudb/impl/posix_file.ipp +248 -0
- data/ext/rudb/NuDB/include/nudb/impl/recover.ipp +209 -0
- data/ext/rudb/NuDB/include/nudb/impl/rekey.ipp +248 -0
- data/ext/rudb/NuDB/include/nudb/impl/verify.ipp +634 -0
- data/ext/rudb/NuDB/include/nudb/impl/visit.ipp +96 -0
- data/ext/rudb/NuDB/include/nudb/impl/win32_file.ipp +264 -0
- data/ext/rudb/NuDB/include/nudb/native_file.hpp +76 -0
- data/ext/rudb/NuDB/include/nudb/nudb.hpp +27 -0
- data/ext/rudb/NuDB/include/nudb/posix_file.hpp +228 -0
- data/ext/rudb/NuDB/include/nudb/progress.hpp +32 -0
- data/ext/rudb/NuDB/include/nudb/recover.hpp +73 -0
- data/ext/rudb/NuDB/include/nudb/rekey.hpp +110 -0
- data/ext/rudb/NuDB/include/nudb/store.hpp +27 -0
- data/ext/rudb/NuDB/include/nudb/type_traits.hpp +63 -0
- data/ext/rudb/NuDB/include/nudb/verify.hpp +200 -0
- data/ext/rudb/NuDB/include/nudb/version.hpp +21 -0
- data/ext/rudb/NuDB/include/nudb/visit.hpp +63 -0
- data/ext/rudb/NuDB/include/nudb/win32_file.hpp +246 -0
- data/ext/rudb/NuDB/include/nudb/xxhasher.hpp +45 -0
- data/ext/rudb/extconf.rb +12 -0
- data/ext/rudb/rudb.cpp +234 -0
- data/lib/rudb/version.rb +3 -0
- data/lib/rudb.rb +1 -0
- 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
|