Monero
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 
39 namespace 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)
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 
119  value_iterator(value_iterator const&) = default;
120  ~value_iterator() = default;
121  value_iterator& operator=(value_iterator const&) = 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 
177  value_type operator*() const noexcept { return get_value<T, F, offset>(); }
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 
197  value_stream(value_stream&&) = default;
198  value_stream(value_stream const&) = delete;
199  ~value_stream() = default;
200  value_stream& operator=(value_stream&&) = default;
201  value_stream& operator=(value_stream const&) = delete;
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  {
270  return {make_iterator<U, F, offset>(), value_iterator<U, F, offset>{}};
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 
boost::iterator_range< value_iterator< U, F, offset > > make_range() const
Definition: value_stream.h:268
const uint32_t T[512]
Definition: groestl_tables.h:36
void reset()
Definition: value_stream.h:221
bool operator!=(key_iterator< K, V > const &lhs, key_iterator< K, V > const &rhs) noexcept
Definition: key_stream.h:261
~value_stream()=default
Definition: lmdb.h:412
G get_value() const noexcept
Definition: value_stream.h:162
Lightning memory-mapped database library.
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
#define F(w, k)
Definition: sha512-blocks.c:61
std::input_iterator_tag iterator_category
Definition: value_stream.h:100
const char * key
Definition: hmac_keccak.cpp:40
Definition: value_stream.h:83
Definition: enums.h:67
#define G(r, i, a, b, c, d)
std::unique_ptr< MDB_cursor, D > cur
Definition: value_stream.h:189
epee::span< const std::uint8_t > values
Definition: value_stream.h:86
std::unique_ptr< MDB_cursor, D > give_cursor() noexcept
Definition: value_stream.h:209
value_type operator*() const noexcept
Definition: value_stream.h:177
~value_iterator()=default
MDB_cursor * cur
Definition: value_stream.h:85
value_stream & operator=(value_stream &&)=default
constexpr std::size_t size() const noexcept
Definition: span.h:109
second
Definition: compare.py:9
mdb_size_t count(MDB_cursor *cur)
Definition: value_stream.cpp:40
std::size_t difference_type
Definition: value_stream.h:99
value_iterator(MDB_cursor *cur)
Definition: value_stream.h:112
void increment()
Definition: value_stream.h:88
std::size_t count() const
Definition: value_stream.h:231
MDB_cursor_op
Cursor Get operations.
Definition: lmdb.h:398
std::size_t remove_prefix(std::size_t amount) noexcept
Definition: span.h:93
value_iterator & operator=(value_iterator const &)=default
const T & move(const T &t)
Definition: gtest-port.h:1317
bool is_end() const noexcept
Definition: value_stream.h:124
value_iterator< U, F, offset > make_iterator() const
Definition: value_stream.h:250
const GenericPointer< typename T::ValueType > T2 value
Definition: pointer.h:1225
void * memcpy(void *a, const void *b, size_t c)
Definition: glibc_compat.cpp:16
value_iterator() noexcept
Construct an "end" iterator.
Definition: value_stream.h:103
Definition: database.cpp:45
Definition: lmdb.h:404
Definition: value_stream.h:187
Definition: lmdb.h:400
value_iterator & operator++()
Invalidates all prior copies of the iterator.
Definition: value_stream.h:135
void pointer
Definition: value_stream.h:98
bool operator==(key_iterator< K, V > const &lhs, key_iterator< K, V > const &rhs) noexcept
Definition: key_stream.h:254
value_stream(std::unique_ptr< MDB_cursor, D > cur)
Take ownership of cur without changing position. nullptr valid.
Definition: value_stream.h:193
F value_type
Definition: value_stream.h:96
Definition: mdb.c:1372
constexpr bool empty() const noexcept
Definition: span.h:107
size_t mdb_size_t
Definition: lmdb.h:196
#define const
Definition: ipfrdr.c:80
bool equal(value_iterator const &rhs) const noexcept
Definition: value_stream.h:127
Definition: blockchain_usage.cpp:71
constexpr pointer data() const noexcept
Definition: span.h:108
value_iterator operator++(int)
Definition: value_stream.h:142