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 <array>
26#include <bit>
27#include <cstdint>
28#include <optional>
29
30namespace ripple {
31
60{
61 static_assert(
62 alignof(SHAMapHash) >= 4,
63 "Bad alignment: Tag pointer requires low two bits to be zero.");
69 static constexpr std::uintptr_t tagMask = 3;
71 static constexpr std::uintptr_t ptrMask = ~tagMask;
72
74 void
76
78 {
79 };
94
95public:
96 TaggedPointer() = delete;
97 explicit TaggedPointer(std::uint8_t numChildren);
98
114 TaggedPointer&& other,
115 std::uint16_t isBranch,
116 std::uint8_t toAllocate);
117
140 TaggedPointer&& other,
141 std::uint16_t srcBranches,
142 std::uint16_t dstBranches,
143 std::uint8_t toAllocate);
144
145 TaggedPointer(TaggedPointer const&) = delete;
146
148
151
153
156 decode() const;
157
159 [[nodiscard]] std::uint8_t
160 capacity() const;
161
167 [[nodiscard]] bool
168 isDense() const;
169
173 [[nodiscard]] std::
174 tuple<std::uint8_t, SHAMapHash*, std::shared_ptr<SHAMapTreeNode>*>
176
178 [[nodiscard]] SHAMapHash*
179 getHashes() const;
180
183 getChildren() const;
184
193 template <class F>
194 void
195 iterChildren(std::uint16_t isBranch, F&& f) const;
196
206 template <class F>
207 void
209
219 getChildIndex(std::uint16_t isBranch, int i) const;
220};
221
222[[nodiscard]] inline int
224{
225#if __cpp_lib_bitops
226 return std::popcount(a);
227#elif defined(__clang__) || defined(__GNUC__)
228 return __builtin_popcount(a);
229#else
230 // fallback to table lookup
231 static auto constexpr const tbl = []() {
233 for (int i = 0; i != 256; ++i)
234 {
235 for (int j = 0; j != 8; ++j)
236 {
237 if (i & (1 << j))
238 ret[i]++;
239 }
240 }
241 return ret;
242 }();
243 return tbl[a & 0xff] + tbl[a >> 8];
244#endif
245}
246
247} // namespace ripple
248
249#endif
TaggedPointer is a combination of a pointer and a mask stored in the lowest two bits.
Definition: TaggedPointer.h:60
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.
static constexpr std::uintptr_t tagMask
bit-and with this mask to get the tag bits (lowest two bits)
Definition: TaggedPointer.h:69
SHAMapHash * getHashes() const
Get the hashes array.
TaggedPointer & operator=(TaggedPointer &&)
std::shared_ptr< SHAMapTreeNode > * getChildren() const
Get the children array.
static constexpr std::uintptr_t ptrMask
bit-and with this mask to get the pointer bits (mask out the tag)
Definition: TaggedPointer.h:71
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:67
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.
std::tuple< std::uint8_t, SHAMapHash *, std::shared_ptr< SHAMapTreeNode > * > getHashesAndChildren() const
Get the number of elements in each array and a pointer to the start of each array.
bool isDense() const
Check if the arrays have a dense format.
TaggedPointer(std::uint8_t numChildren)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:26
int popcnt16(std::uint16_t a)