rippled
Loading...
Searching...
No Matches
TaggedPointer.h
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2020 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_TAGGEDPOINTER_H_INCLUDED
21#define RIPPLE_SHAMAP_TAGGEDPOINTER_H_INCLUDED
22
23#include <xrpld/shamap/SHAMapTreeNode.h>
24
25#include <xrpl/basics/IntrusivePointer.h>
26
27#include <array>
28#include <cstdint>
29#include <optional>
30
31namespace ripple {
32
61{
62private:
63 static_assert(
64 alignof(SHAMapHash) >= 4,
65 "Bad alignment: Tag pointer requires low two bits to be zero.");
71 static constexpr std::uintptr_t tagMask = 3;
73 static constexpr std::uintptr_t ptrMask = ~tagMask;
74
76 void
78
80 {
81 };
96
97public:
98 TaggedPointer() = delete;
99 explicit TaggedPointer(std::uint8_t numChildren);
100
116 TaggedPointer&& other,
117 std::uint16_t isBranch,
118 std::uint8_t toAllocate);
119
142 TaggedPointer&& other,
143 std::uint16_t srcBranches,
144 std::uint16_t dstBranches,
145 std::uint8_t toAllocate);
146
147 TaggedPointer(TaggedPointer const&) = delete;
148
150
153
155
158 decode() const;
159
161 [[nodiscard]] std::uint8_t
162 capacity() const;
163
169 [[nodiscard]] bool
170 isDense() const;
171
175 [[nodiscard]] std::
176 tuple<std::uint8_t, SHAMapHash*, intr_ptr::SharedPtr<SHAMapTreeNode>*>
178
180 [[nodiscard]] SHAMapHash*
181 getHashes() const;
182
185 getChildren() const;
186
195 template <class F>
196 void
197 iterChildren(std::uint16_t isBranch, F&& f) const;
198
208 template <class F>
209 void
211
221 getChildIndex(std::uint16_t isBranch, int i) const;
222};
223
224[[nodiscard]] inline int
226{
227#if __cpp_lib_bitops
228 return std::popcount(a);
229#elif defined(__clang__) || defined(__GNUC__)
230 return __builtin_popcount(a);
231#else
232 // fallback to table lookup
233 static auto constexpr const tbl = []() {
235 for (int i = 0; i != 256; ++i)
236 {
237 for (int j = 0; j != 8; ++j)
238 {
239 if (i & (1 << j))
240 ret[i]++;
241 }
242 }
243 return ret;
244 }();
245 return tbl[a & 0xff] + tbl[a >> 8];
246#endif
247}
248
249} // namespace ripple
250
251#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.
Definition: TaggedPointer.h:61
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)
Definition: TaggedPointer.h:71
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)
Definition: TaggedPointer.h:73
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.
Definition: TaggedPointer.h:69
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.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
int popcnt16(std::uint16_t a)
T popcount(T... args)