Monero
Loading...
Searching...
No Matches
value_stream.h
Go to the documentation of this file.
1// Copyright (c) 2018-2022, The Monero Project
2
3// All rights reserved.
4//
5// Redistribution and use in source and binary forms, with or without modification, are
6// permitted provided that the following conditions are met:
7//
8// 1. Redistributions of source code must retain the above copyright notice, this list of
9// conditions and the following disclaimer.
10//
11// 2. Redistributions in binary form must reproduce the above copyright notice, this list
12// of conditions and the following disclaimer in the documentation and/or other
13// materials provided with the distribution.
14//
15// 3. Neither the name of the copyright holder nor the names of its contributors may be
16// used to endorse or promote products derived from this software without specific
17// prior written permission.
18//
19// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28#pragma once
29
30#include <boost/range/iterator_range.hpp>
31#include <cstdint>
32#include <cstring>
33#include <iterator>
34#include <lmdb.h>
35#include <utility>
36
37#include "span.h"
38
39namespace lmdb
40{
41 namespace stream
42 {
43 /*
44 \throw std::system_error if unexpected LMDB error.
45 \return 0 if `cur == nullptr`, otherwise count of values at current key.
46 */
48
64 std::pair<epee::span<const std::uint8_t>, epee::span<const std::uint8_t>>
65 get(MDB_cursor& cur, MDB_cursor_op op, std::size_t key, std::size_t value);
66 }
67
82 template<typename T, typename F = T, std::size_t offset = 0>
84 {
87
88 void increment()
89 {
90 values.remove_prefix(sizeof(T));
91 if (values.empty() && cur)
92 values = lmdb::stream::get(*cur, MDB_NEXT_DUP, 0, sizeof(T)).second;
93 }
94
95 public:
96 using value_type = F;
98 using pointer = void;
99 using difference_type = std::size_t;
100 using iterator_category = std::input_iterator_tag;
101
103 value_iterator() noexcept
104 : cur(nullptr), values()
105 {}
106
113 : cur(cur), values()
114 {
115 if (cur)
116 values = lmdb::stream::get(*cur, MDB_GET_CURRENT, 0, sizeof(T)).second;
117 }
118
120 ~value_iterator() = default;
122
124 bool is_end() const noexcept { return values.empty(); }
125
127 bool equal(value_iterator const& rhs) const noexcept
128 {
129 return
130 (values.empty() && rhs.values.empty()) ||
131 values.data() == rhs.values.data();
132 }
133
136 {
137 increment();
138 return *this;
139 }
140
143 {
144 value_iterator out{*this};
145 increment();
146 return out;
147 }
148
161 template<typename U, typename G = U, std::size_t uoffset = 0>
162 G get_value() const noexcept
163 {
164 static_assert(std::is_same<U, T>(), "bad MONERO_FIELD usage?");
165 static_assert(std::is_trivially_copyable<U>(), "value type must be memcpy safe");
166 static_assert(std::is_trivially_copyable<G>(), "field type must be memcpy safe");
167 static_assert(sizeof(G) + uoffset <= sizeof(U), "bad field and/or offset");
168 assert(sizeof(G) + uoffset <= values.size());
169 assert(!is_end());
170
171 G value;
172 std::memcpy(std::addressof(value), values.data() + uoffset, sizeof(value));
173 return value;
174 }
175
178 };
179
186 template<typename T, typename D>
188 {
189 std::unique_ptr<MDB_cursor, D> cur;
190 public:
191
193 explicit value_stream(std::unique_ptr<MDB_cursor, D> cur)
194 : cur(std::move(cur))
195 {}
196
198 value_stream(value_stream const&) = delete;
199 ~value_stream() = default;
202
209 std::unique_ptr<MDB_cursor, D> give_cursor() noexcept
210 {
211 return {std::move(cur)};
212 }
213
221 void reset()
222 {
223 if (cur)
225 }
226
231 std::size_t count() const
232 {
233 return lmdb::stream::count(cur.get());
234 }
235
249 template<typename U = T, typename F = U, std::size_t offset = 0>
251 {
252 static_assert(std::is_same<U, T>(), "was MONERO_FIELD used with wrong type?");
253 return {cur.get()};
254 }
255
267 template<typename U = T, typename F = U, std::size_t offset = 0>
268 boost::iterator_range<value_iterator<U, F, offset>> make_range() const
269 {
271 }
272 };
273
274 template<typename T, typename F, std::size_t offset>
275 inline
277 {
278 return lhs.equal(rhs);
279 }
280
281 template<typename T, typename F, std::size_t offset>
282 inline
284 {
285 return !lhs.equal(rhs);
286 }
287} // lmdb
288
#define G(r, i, a, b, c, d)
Non-owning sequence of data. Does not deep copy.
Definition span.h:55
Definition value_stream.h:84
G get_value() const noexcept
Definition value_stream.h:162
value_iterator & operator++()
Invalidates all prior copies of the iterator.
Definition value_stream.h:135
value_type reference
Definition value_stream.h:97
value_iterator & operator=(value_iterator const &)=default
value_iterator(value_iterator const &)=default
value_iterator() noexcept
Construct an "end" iterator.
Definition value_stream.h:103
value_iterator(MDB_cursor *cur)
Definition value_stream.h:112
value_iterator operator++(int)
Definition value_stream.h:142
~value_iterator()=default
value_type operator*() const noexcept
Definition value_stream.h:177
void increment()
Definition value_stream.h:88
bool equal(value_iterator const &rhs) const noexcept
Definition value_stream.h:127
MDB_cursor * cur
Definition value_stream.h:85
std::size_t difference_type
Definition value_stream.h:99
epee::span< const std::uint8_t > values
Definition value_stream.h:86
bool is_end() const noexcept
Definition value_stream.h:124
void pointer
Definition value_stream.h:98
F value_type
Definition value_stream.h:96
std::input_iterator_tag iterator_category
Definition value_stream.h:100
value_stream(value_stream const &)=delete
value_stream(value_stream &&)=default
void reset()
Definition value_stream.h:221
std::size_t count() const
Definition value_stream.h:231
value_stream(std::unique_ptr< MDB_cursor, D > cur)
Take ownership of cur without changing position. nullptr valid.
Definition value_stream.h:193
std::unique_ptr< MDB_cursor, D > cur
Definition value_stream.h:189
value_stream & operator=(value_stream &&)=default
std::unique_ptr< MDB_cursor, D > give_cursor() noexcept
Definition value_stream.h:209
value_iterator< U, F, offset > make_iterator() const
Definition value_stream.h:250
~value_stream()=default
value_stream & operator=(value_stream const &)=delete
boost::iterator_range< value_iterator< U, F, offset > > make_range() const
Definition value_stream.h:268
MDB_cursor_op
Cursor Get operations.
Definition lmdb.h:398
@ MDB_NEXT_DUP
Definition lmdb.h:412
@ MDB_GET_CURRENT
Definition lmdb.h:404
@ MDB_FIRST_DUP
Definition lmdb.h:400
struct MDB_cursor MDB_cursor
Opaque structure for navigating through a database.
Definition lmdb.h:273
const char * key
Definition hmac_keccak.cpp:40
#define const
Definition ipfrdr.c:80
Lightning memory-mapped database library.
size_t mdb_size_t
Definition lmdb.h:196
Definition value_stream.cpp:39
mdb_size_t count(MDB_cursor *cur)
Definition value_stream.cpp:40
std::pair< epee::span< const std::uint8_t >, epee::span< const std::uint8_t > > get(MDB_cursor &cur, MDB_cursor_op op, std::size_t key, std::size_t value)
Definition value_stream.cpp:53
Definition database.cpp:46
bool operator==(key_iterator< K, V > const &lhs, key_iterator< K, V > const &rhs) noexcept
Definition key_stream.h:254
bool operator!=(key_iterator< K, V > const &lhs, key_iterator< K, V > const &rhs) noexcept
Definition key_stream.h:261
Definition enums.h:68
const GenericPointer< typename T::ValueType > T2 value
Definition pointer.h:1225
#define F(w, k)
Definition sha512-blocks.c:61
Definition mdb.c:1372
#define T(x)