pstore2
hamt_set.hpp
Go to the documentation of this file.
1 //===- include/pstore/core/hamt_set.hpp -------------------*- mode: C++ -*-===//
2 //* _ _ _ *
3 //* | |__ __ _ _ __ ___ | |_ ___ ___| |_ *
4 //* | '_ \ / _` | '_ ` _ \| __| / __|/ _ \ __| *
5 //* | | | | (_| | | | | | | |_ \__ \ __/ |_ *
6 //* |_| |_|\__,_|_| |_| |_|\__| |___/\___|\__| *
7 //* *
8 //===----------------------------------------------------------------------===//
9 //
10 // Part of the pstore project, under the Apache License v2.0 with LLVM Exceptions.
11 // See https://github.com/SNSystems/pstore/blob/master/LICENSE.txt for license
12 // information.
13 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
14 //
15 //===----------------------------------------------------------------------===//
17 
18 #ifndef PSTORE_CORE_HAMT_SET_HPP
19 #define PSTORE_CORE_HAMT_SET_HPP
20 
21 // pstore includes
22 #include "pstore/core/hamt_map.hpp"
23 
24 namespace pstore {
25  namespace index {
26 
27  namespace details {
28  class empty_class {};
29  } // namespace details
30 
31  template <typename KeyType, typename Hash, typename KeyEqual>
32  class hamt_set final : public index_base {
34 
35  template <typename MapIterator>
36  class set_iterator {
37  static_assert (std::is_same<typename MapIterator::value_type::first_type,
38  typename std::add_const<KeyType>::type>::value,
39  "hamt_set key type does not match the iterator key type");
40 
41  public:
42  using iterator_category = std::forward_iterator_tag;
43  using value_type = typename std::add_const<KeyType>::type;
44  using difference_type = std::ptrdiff_t;
45  using pointer = value_type *;
46  using reference = value_type &;
47 
48  explicit set_iterator (MapIterator const & it)
49  : it_ (it) {}
50 
51  bool operator== (set_iterator const & other) const { return it_ == other.it_; }
52 
53  bool operator!= (set_iterator const & other) const { return it_ != other.it_; }
54 
58  reference operator* () const { return it_->first; }
59 
60  pointer operator-> () const { return &it_->first; }
61 
63  set_iterator & operator++ () {
64  ++it_;
65  return *this;
66  }
68  set_iterator operator++ (int) {
69  auto const old (*this);
70  it_++;
71  return old;
72  }
73 
74  address get_address () const { return it_.get_address (); }
75 
76  private:
77  MapIterator it_;
78  };
79 
80  public:
81  // types
82  using key_type = KeyType;
83  using value_type = key_type;
84  using key_equal = KeyEqual;
85  using hasher = Hash;
86  using reference = value_type &;
87  using const_reference = value_type const &;
88 
89  using const_iterator =
90  set_iterator<typename hamt_map<value_type, details::empty_class, hasher,
91  key_equal>::const_iterator>;
92  using iterator = const_iterator;
93 
94  explicit hamt_set (
95  database const & db,
97  hasher const & hash = hasher ())
98  : map_ (db, ip, hash) {}
99 
102 
103  range<database, hamt_set, iterator> make_range (database & db) { return {db, *this}; }
105  make_range (database const & db) const {
106  return {db, *this};
107  }
108 
109  iterator begin (database & db) { return iterator{map_.begin (db)}; }
110  const_iterator begin (database const & db) const {
111  return const_iterator{map_.cbegin (db)};
112  }
113  const_iterator cbegin (database const & db) const {
114  return const_iterator{map_.cbegin (db)};
115  }
116 
117  iterator end (database & db) { return iterator{map_.end (db)}; }
118  const_iterator end (database const & db) const {
119  return const_iterator{map_.cend (db)};
120  }
121  const_iterator cend (database const & db) const {
122  return const_iterator{map_.cend (db)};
123  }
125 
128 
130  bool empty () const { return map_.empty (); }
131 
133  std::size_t size () const { return map_.size (); }
135 
147  template <typename OtherKeyType,
148  typename = typename std::enable_if<
150  std::pair<iterator, bool> insert (transaction_base & transaction,
151  OtherKeyType const & key) {
152  auto it = map_.insert (transaction, std::make_pair (key, details::empty_class ()));
153  return {iterator{it.first}, it.second};
154  }
155 
165  template <typename OtherKeyType,
166  typename = typename std::enable_if<
168  const_iterator find (database const & db, OtherKeyType const & key) const {
169  return const_iterator{map_.find (db, key)};
170  }
171 
178  unsigned generation) {
179  return map_.flush (transaction, generation);
180  }
181 
185 
187  value_type load_leaf_node (database const & db, address const addr) const {
188  return map_.load_leaf_node (db, addr).first;
189  }
190 
191  index_pointer root () const { return map_.root (); }
193 
194  private:
196  };
197 
198  } // namespace index
199 
200  namespace serialize {
201 
202  template <>
203  struct serializer<index::details::empty_class> {
205 
206  template <typename Archive>
207  static auto write (Archive && archive, value_type const &)
208  -> archive_result_type<Archive> {
209  // Tell the archiver to write an array of 0 elements. This should write
210  // nothing at all but yield the location at which it would have gone (with the
211  // correct type).
212  auto const dummy = std::uint8_t{0};
213  return serialize::write (std::forward<Archive> (archive),
214  gsl::make_span (&dummy, &dummy));
215  }
216 
217  template <typename Archive>
218  static void read (Archive &&, value_type & value) {
219  new (&value) value_type;
220  }
221  };
222 
223  } // namespace serialize
224 
225 } // namespace pstore
226 #endif // PSTORE_CORE_HAMT_SET_HPP
This class provides a common base from which each of the real index types derives.
Definition: hamt_map_fwd.hpp:29
The primary template for serialization of non standard layout types.
Definition: types.hpp:118
Definition: address.hpp:81
const_iterator find(database const &db, OtherKeyType const &key) const
Find the element with a specific key.
Definition: hamt_set.hpp:168
transaction< transaction_lock > begin(database &db, transaction_lock &lock)
Creates a new transaction. Every operation performed on a transaction instance can be potentially und...
Definition: transaction.hpp:311
auto index(gsl::czstring str, std::size_t pos) -> gsl::czstring
Returns a pointer to the beginning of the pos&#39;th UTF-8 codepoint in the buffer at str or nullptr if e...
Definition: utf.cpp:49
Definition: transaction.hpp:191
Ty read(Archive &&archive)
Read a single value from an archive.
Definition: types.hpp:412
Definition: address.hpp:231
bool empty() const
Checks whether the container is empty.
Definition: hamt_set.hpp:130
typed_address< header_block > flush(transaction_base &transaction, unsigned generation)
Flush any modified index nodes to the store.
Definition: hamt_set.hpp:177
Definition: hamt_map_fwd.hpp:61
A Hash array mapped trie index type for the pstore.
Definition: hamt_map.hpp:48
Definition: print.cpp:18
The begin() and end() functions for both hamt_map and hamt_set take an extra parameter – the owning ...
Definition: hamt_map_fwd.hpp:40
std::pair< iterator, bool > insert(transaction_base &transaction, OtherKeyType const &key)
Inserts an element into the container, if the container doesn&#39;t already contain an element with an eq...
Definition: hamt_set.hpp:150
Definition: nonpod2.cpp:40
Definition: database.hpp:40
auto write(Archive &&archive, Ty const &ty) -> archive_result_type< Archive >
Write a single value to an archive.
Definition: types.hpp:453
value_type load_leaf_node(database const &db, address const addr) const
Read a leaf node from a store.
Definition: hamt_set.hpp:187
std::size_t size() const
Returns the number of elements in the container.
Definition: hamt_set.hpp:133
If the two types T1 and T2 have a compatible representation when serialized, provides the member cons...
Definition: types.hpp:321
An index pointer is either a database address or a pointer to volatile RAM.
Definition: hamt_map_types.hpp:132
A key/value index implementation.
Definition: hamt_set.hpp:28
The database transaction class.
Definition: transaction.hpp:43