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 <xrpl/basics/IntrusivePointer.h>
24#include <xrpl/shamap/SHAMapTreeNode.h>
25
26#include <array>
27#include <cstdint>
28#include <optional>
29
30namespace ripple {
31
60{
61private:
62 static_assert(
63 alignof(SHAMapHash) >= 4,
64 "Bad alignment: Tag pointer requires low two bits to be zero.");
70 static constexpr std::uintptr_t tagMask = 3;
72 static constexpr std::uintptr_t ptrMask = ~tagMask;
73
75 void
77
79 {
80 };
95
96public:
97 TaggedPointer() = delete;
98 explicit TaggedPointer(std::uint8_t numChildren);
99
115 TaggedPointer&& other,
116 std::uint16_t isBranch,
117 std::uint8_t toAllocate);
118
141 TaggedPointer&& other,
142 std::uint16_t srcBranches,
143 std::uint16_t dstBranches,
144 std::uint8_t toAllocate);
145
146 TaggedPointer(TaggedPointer const&) = delete;
147
149
152
154
157 decode() const;
158
160 [[nodiscard]] std::uint8_t
161 capacity() const;
162
168 [[nodiscard]] bool
169 isDense() const;
170
174 [[nodiscard]] std::
177
179 [[nodiscard]] SHAMapHash*
180 getHashes() const;
181
184 getChildren() const;
185
194 template <class F>
195 void
196 iterChildren(std::uint16_t isBranch, F&& f) const;
197
207 template <class F>
208 void
210
220 getChildIndex(std::uint16_t isBranch, int i) const;
221};
222
223[[nodiscard]] inline int
225{
226#if __cpp_lib_bitops
227 return std::popcount(a);
228#elif defined(__clang__) || defined(__GNUC__)
229 return __builtin_popcount(a);
230#else
231 // fallback to table lookup
232 static auto constexpr const tbl = []() {
234 for (int i = 0; i != 256; ++i)
235 {
236 for (int j = 0; j != 8; ++j)
237 {
238 if (i & (1 << j))
239 ret[i]++;
240 }
241 }
242 return ret;
243 }();
244 return tbl[a & 0xff] + tbl[a >> 8];
245#endif
246}
247
248} // namespace ripple
249
250#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:25
int popcnt16(std::uint16_t a)
T popcount(T... args)