rippled
Loading...
Searching...
No Matches
TaggedPointer.h
1#ifndef XRPL_SHAMAP_TAGGEDPOINTER_H_INCLUDED
2#define XRPL_SHAMAP_TAGGEDPOINTER_H_INCLUDED
3
4#include <xrpl/basics/IntrusivePointer.h>
5#include <xrpl/shamap/SHAMapTreeNode.h>
6
7#include <array>
8#include <cstdint>
9#include <optional>
10
11namespace ripple {
12
41{
42private:
43 static_assert(
44 alignof(SHAMapHash) >= 4,
45 "Bad alignment: Tag pointer requires low two bits to be zero.");
51 static constexpr std::uintptr_t tagMask = 3;
53 static constexpr std::uintptr_t ptrMask = ~tagMask;
54
56 void
58
60 {
61 };
76
77public:
78 TaggedPointer() = delete;
79 explicit TaggedPointer(std::uint8_t numChildren);
80
95 explicit TaggedPointer(
96 TaggedPointer&& other,
97 std::uint16_t isBranch,
98 std::uint8_t toAllocate);
99
122 TaggedPointer&& other,
123 std::uint16_t srcBranches,
124 std::uint16_t dstBranches,
125 std::uint8_t toAllocate);
126
127 TaggedPointer(TaggedPointer const&) = delete;
128
130
133
135
138 decode() const;
139
141 [[nodiscard]] std::uint8_t
142 capacity() const;
143
149 [[nodiscard]] bool
150 isDense() const;
151
155 [[nodiscard]] std::
158
160 [[nodiscard]] SHAMapHash*
161 getHashes() const;
162
165 getChildren() const;
166
175 template <class F>
176 void
177 iterChildren(std::uint16_t isBranch, F&& f) const;
178
188 template <class F>
189 void
191
201 getChildIndex(std::uint16_t isBranch, int i) const;
202};
203
204[[nodiscard]] inline int
206{
207#if __cpp_lib_bitops
208 return std::popcount(a);
209#elif defined(__clang__) || defined(__GNUC__)
210 return __builtin_popcount(a);
211#else
212 // fallback to table lookup
213 static auto constexpr const tbl = []() {
215 for (int i = 0; i != 256; ++i)
216 {
217 for (int j = 0; j != 8; ++j)
218 {
219 if (i & (1 << j))
220 ret[i]++;
221 }
222 }
223 return ret;
224 }();
225 return tbl[a & 0xff] + tbl[a >> 8];
226#endif
227}
228
229} // namespace ripple
230
231#endif
A shared intrusive pointer class that supports weak pointers.
TaggedPointer is a combination of a pointer and a mask stored in the lowest two bits.
void iterNonEmptyChildIndexes(std::uint16_t isBranch, F &&f) const
Call the f callback for all non-empty branches.
std::pair< std::uint8_t, void * > decode() const
Decode the tagged pointer into its tag and pointer.
TaggedPointer(TaggedPointer &&other, std::uint16_t srcBranches, std::uint16_t dstBranches, std::uint8_t toAllocate)
Given other with the specified children in srcBranches, create a new TaggedPointer with the allocated...
TaggedPointer(TaggedPointer &&)
std::optional< int > getChildIndex(std::uint16_t isBranch, int i) const
Get the child's index inside the hashes or children array (which may or may not be sparse).
TaggedPointer(TaggedPointer const &)=delete
void destroyHashesAndChildren()
Deallocate memory and run destructors.
TaggedPointer(TaggedPointer &&other, std::uint16_t isBranch, std::uint8_t toAllocate)
Constructor is used change the number of allocated children.
std::tuple< std::uint8_t, SHAMapHash *, intr_ptr::SharedPtr< SHAMapTreeNode > * > getHashesAndChildren() const
Get the number of elements in each array and a pointer to the start of each array.
static constexpr std::uintptr_t tagMask
bit-and with this mask to get the tag bits (lowest two bits)
SHAMapHash * getHashes() const
Get the hashes array.
TaggedPointer & operator=(TaggedPointer &&)
static constexpr std::uintptr_t ptrMask
bit-and with this mask to get the pointer bits (mask out the tag)
std::uint8_t capacity() const
Get the number of elements allocated for each array.
std::uintptr_t tp_
Upper bits are the pointer, lowest two bits are the tag A moved-from object will have a tp_ of zero.
TaggedPointer(RawAllocateTag, std::uint8_t numChildren)
This constructor allocates space for the hashes and children, but does not run constructors.
void iterChildren(std::uint16_t isBranch, F &&f) const
Call the f callback for all 16 (branchFactor) branches - even if the branch is empty.
bool isDense() const
Check if the arrays have a dense format.
TaggedPointer(std::uint8_t numChildren)
intr_ptr::SharedPtr< SHAMapTreeNode > * getChildren() const
Get the children array.
T is_same_v
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:6
int popcnt16(std::uint16_t a)
T popcount(T... args)