rippled
SHAMapInnerNode.h
1 //------------------------------------------------------------------------------
2 /*
3  This file is part of rippled: https://github.com/ripple/rippled
4  Copyright (c) 2012, 2013 Ripple Labs Inc.
5 
6  Permission to use, copy, modify, and/or distribute this software for any
7  purpose with or without fee is hereby granted, provided that the above
8  copyright notice and this permission notice appear in all copies.
9 
10  THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17 */
18 //==============================================================================
19 
20 #ifndef RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
21 #define RIPPLE_SHAMAP_SHAMAPINNERNODE_H_INCLUDED
22 
23 #include <ripple/basics/TaggedCache.h>
24 #include <ripple/beast/utility/Journal.h>
25 #include <ripple/shamap/SHAMapItem.h>
26 #include <ripple/shamap/SHAMapNodeID.h>
27 #include <ripple/shamap/SHAMapTreeNode.h>
28 #include <ripple/shamap/impl/TaggedPointer.h>
29 
30 #include <atomic>
31 #include <bit>
32 #include <bitset>
33 #include <cstdint>
34 #include <limits>
35 #include <memory>
36 #include <mutex>
37 #include <optional>
38 #include <string>
39 
40 namespace ripple {
41 
42 class SHAMapInnerNode final : public SHAMapTreeNode,
43  public CountedObject<SHAMapInnerNode>
44 {
45 public:
47  static inline constexpr unsigned int branchFactor = 16;
48 
49 private:
55 
58 
61 
72  void
73  resizeChildArrays(std::uint8_t toAllocate);
74 
84  getChildIndex(int i) const;
85 
92  template <class F>
93  void
94  iterChildren(F&& f) const;
95 
103  template <class F>
104  void
105  iterNonEmptyChildIndexes(F&& f) const;
106 
107 public:
108  explicit SHAMapInnerNode(
110  std::uint8_t numAllocatedChildren = 2);
111 
112  SHAMapInnerNode(SHAMapInnerNode const&) = delete;
114  operator=(SHAMapInnerNode const&) = delete;
116 
118  clone(std::uint32_t cowid) const override;
119 
121  getType() const override
122  {
124  }
125 
126  bool
127  isLeaf() const override
128  {
129  return false;
130  }
131 
132  bool
133  isInner() const override
134  {
135  return true;
136  }
137 
138  bool
139  isEmpty() const;
140 
141  bool
142  isEmptyBranch(int m) const;
143 
144  int
145  getBranchCount() const;
146 
147  SHAMapHash const&
148  getChildHash(int m) const;
149 
150  void
152 
153  void
154  shareChild(int m, std::shared_ptr<SHAMapTreeNode> const& child);
155 
157  getChildPointer(int branch);
158 
160  getChild(int branch);
161 
164 
165  // sync functions
166  bool
167  isFullBelow(std::uint32_t generation) const;
168 
169  void
171 
172  void
173  updateHash() override;
174 
176  void
177  updateHashDeep();
178 
179  void
180  serializeForWire(Serializer&) const override;
181 
182  void
183  serializeWithPrefix(Serializer&) const override;
184 
186  getString(SHAMapNodeID const&) const override;
187 
188  void
189  invariants(bool is_root = false) const override;
190 
192  makeFullInner(Slice data, SHAMapHash const& hash, bool hashValid);
193 
196 };
197 
198 inline bool
200 {
201  return isBranch_ == 0;
202 }
203 
204 inline bool
206 {
207  return (isBranch_ & (1 << m)) == 0;
208 }
209 
210 inline int
212 {
213  return popcnt16(isBranch_);
214 }
215 
216 inline bool
218 {
219  return fullBelowGen_ == generation;
220 }
221 
222 inline void
224 {
225  fullBelowGen_ = gen;
226 }
227 
228 } // namespace ripple
229 #endif
ripple::SHAMapTreeNode::cowid
std::uint32_t cowid() const
Returns the SHAMap that owns this node.
Definition: SHAMapTreeNode.h:116
ripple::SHAMapInnerNode::serializeWithPrefix
void serializeWithPrefix(Serializer &) const override
Serialize the node in a format appropriate for hashing.
Definition: SHAMapInnerNode.cpp:250
ripple::SHAMapInnerNode::isInner
bool isInner() const override
Determines if this is an inner node.
Definition: SHAMapInnerNode.h:133
bitset
ripple::CountedObject
Tracks the number of instances of an object.
Definition: CountedObject.h:124
ripple::SHAMapInnerNode::clone
std::shared_ptr< SHAMapTreeNode > clone(std::uint32_t cowid) const override
Make a copy of this node, setting the owner.
Definition: SHAMapInnerNode.cpp:75
std::string
STL class.
std::shared_ptr
STL class.
ripple::SHAMapNodeType::tnINNER
@ tnINNER
ripple::popcnt16
int popcnt16(std::uint16_t a)
Definition: TaggedPointer.h:223
ripple::SHAMapInnerNode::hashesAndChildren_
TaggedPointer hashesAndChildren_
Opaque type that contains the hashes array (array of type SHAMapHash) and the children array (array o...
Definition: SHAMapInnerNode.h:54
ripple::SHAMapInnerNode::getChild
std::shared_ptr< SHAMapTreeNode > getChild(int branch)
Definition: SHAMapInnerNode.cpp:336
ripple::Slice
An immutable linear range of bytes.
Definition: Slice.h:44
ripple::SHAMapInnerNode::makeFullInner
static std::shared_ptr< SHAMapTreeNode > makeFullInner(Slice data, SHAMapHash const &hash, bool hashValid)
Definition: SHAMapInnerNode.cpp:126
ripple::SHAMapInnerNode::canonicalizeChild
std::shared_ptr< SHAMapTreeNode > canonicalizeChild(int branch, std::shared_ptr< SHAMapTreeNode > node)
Definition: SHAMapInnerNode.cpp:359
ripple::SHAMapNodeType
SHAMapNodeType
Definition: SHAMapTreeNode.h:46
ripple::SHAMapInnerNode::updateHash
void updateHash() override
Recalculate the hash of this node.
Definition: SHAMapInnerNode.cpp:196
ripple::SHAMapInnerNode::branchFactor
static constexpr unsigned int branchFactor
Each inner node has 16 children (the 'radix tree' part of the map)
Definition: SHAMapInnerNode.h:47
ripple::SHAMapInnerNode::shareChild
void shareChild(int m, std::shared_ptr< SHAMapTreeNode > const &child)
Definition: SHAMapInnerNode.cpp:311
ripple::SHAMapNodeID
Identifies a node inside a SHAMap.
Definition: SHAMapNodeID.h:33
ripple::SHAMapInnerNode::iterChildren
void iterChildren(F &&f) const
Call the f callback for all 16 (branchFactor) branches - even if the branch is empty.
Definition: SHAMapInnerNode.cpp:49
ripple::TaggedPointer
TaggedPointer is a combination of a pointer and a mask stored in the lowest two bits.
Definition: TaggedPointer.h:59
ripple::SHAMapHash
Definition: SHAMapHash.h:32
ripple::SHAMapInnerNode::isEmptyBranch
bool isEmptyBranch(int m) const
Definition: SHAMapInnerNode.h:205
ripple::SHAMapInnerNode::iterNonEmptyChildIndexes
void iterNonEmptyChildIndexes(F &&f) const
Call the f callback for all non-empty branches.
Definition: SHAMapInnerNode.cpp:56
ripple::SHAMapInnerNode::getString
std::string getString(SHAMapNodeID const &) const override
Definition: SHAMapInnerNode.cpp:260
ripple::SHAMapInnerNode::operator=
SHAMapInnerNode & operator=(SHAMapInnerNode const &)=delete
ripple::SHAMapInnerNode::getChildHash
SHAMapHash const & getChildHash(int m) const
Definition: SHAMapInnerNode.cpp:349
ripple::SHAMapInnerNode::setChild
void setChild(int m, std::shared_ptr< SHAMapTreeNode > child)
Definition: SHAMapInnerNode.cpp:275
ripple::SHAMapInnerNode
Definition: SHAMapInnerNode.h:42
ripple::SHAMapInnerNode::resizeChildArrays
void resizeChildArrays(std::uint8_t toAllocate)
Convert arrays stored in hashesAndChildren_ so they can store the requested number of children.
Definition: SHAMapInnerNode.cpp:62
ripple::SHAMapInnerNode::isFullBelow
bool isFullBelow(std::uint32_t generation) const
Definition: SHAMapInnerNode.h:217
ripple::SHAMapTreeNode
Definition: SHAMapTreeNode.h:53
ripple::SHAMapInnerNode::getChildIndex
std::optional< int > getChildIndex(int i) const
Get the child's index inside the hashes or children array (stored in hashesAndChildren_.
Definition: SHAMapInnerNode.cpp:69
ripple::SHAMapInnerNode::updateHashDeep
void updateHashDeep()
Recalculate the hash of all children and this node.
Definition: SHAMapInnerNode.cpp:211
ripple::SHAMapInnerNode::SHAMapInnerNode
SHAMapInnerNode(std::uint32_t cowid, std::uint8_t numAllocatedChildren=2)
Definition: SHAMapInnerNode.cpp:38
cstdint
ripple::SHAMapInnerNode::isBranch_
std::uint16_t isBranch_
Definition: SHAMapInnerNode.h:57
ripple::SHAMapInnerNode::getBranchCount
int getBranchCount() const
Definition: SHAMapInnerNode.h:211
std::uint32_t
atomic
ripple::SHAMapInnerNode::~SHAMapInnerNode
~SHAMapInnerNode()
memory
bit
ripple::SHAMapInnerNode::getType
SHAMapNodeType getType() const override
Determines the type of node.
Definition: SHAMapInnerNode.h:121
ripple::Serializer
Definition: Serializer.h:40
ripple
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: RCLCensorshipDetector.h:29
ripple::SHAMapInnerNode::serializeForWire
void serializeForWire(Serializer &) const override
Serialize the node in a format appropriate for sending over the wire.
Definition: SHAMapInnerNode.cpp:226
limits
optional
mutex
ripple::SHAMapInnerNode::isLeaf
bool isLeaf() const override
Determines if this is a leaf node.
Definition: SHAMapInnerNode.h:127
ripple::SHAMapInnerNode::isEmpty
bool isEmpty() const
Definition: SHAMapInnerNode.h:199
ripple::SHAMapInnerNode::makeCompressedInner
static std::shared_ptr< SHAMapTreeNode > makeCompressedInner(Slice data)
Definition: SHAMapInnerNode.cpp:160
ripple::SHAMapInnerNode::getChildPointer
SHAMapTreeNode * getChildPointer(int branch)
Definition: SHAMapInnerNode.cpp:323
ripple::SHAMapInnerNode::setFullBelowGen
void setFullBelowGen(std::uint32_t gen)
Definition: SHAMapInnerNode.h:223
ripple::SHAMapInnerNode::lock_
std::atomic< std::uint16_t > lock_
A bitlock for the children of this node, with one bit per child.
Definition: SHAMapInnerNode.h:60
ripple::SHAMapInnerNode::invariants
void invariants(bool is_root=false) const override
Definition: SHAMapInnerNode.cpp:387
ripple::SHAMapInnerNode::fullBelowGen_
std::uint32_t fullBelowGen_
Definition: SHAMapInnerNode.h:56
string