rrudb 0.0.2
Sign up to get free protection for your applications and to get access to all the features.
- 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,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
|