diff --git a/src/ripple/shamap/SHAMapInnerNode.h b/src/ripple/shamap/SHAMapInnerNode.h index c85cdcbbc8..44ac05799f 100644 --- a/src/ripple/shamap/SHAMapInnerNode.h +++ b/src/ripple/shamap/SHAMapInnerNode.h @@ -28,6 +28,7 @@ #include #include +#include #include #include #include @@ -194,12 +195,24 @@ public: makeCompressedInner(Slice data); }; +inline bool +SHAMapInnerNode::isEmpty() const +{ + return isBranch_ == 0; +} + inline bool SHAMapInnerNode::isEmptyBranch(int m) const { return (isBranch_ & (1 << m)) == 0; } +inline int +SHAMapInnerNode::getBranchCount() const +{ + return popcnt16(isBranch_); +} + inline bool SHAMapInnerNode::isFullBelow(std::uint32_t generation) const { diff --git a/src/ripple/shamap/impl/SHAMapInnerNode.cpp b/src/ripple/shamap/impl/SHAMapInnerNode.cpp index 1cac616b00..c988495591 100644 --- a/src/ripple/shamap/impl/SHAMapInnerNode.cpp +++ b/src/ripple/shamap/impl/SHAMapInnerNode.cpp @@ -256,18 +256,6 @@ SHAMapInnerNode::serializeWithPrefix(Serializer& s) const [&](SHAMapHash const& hh) { s.addBitString(hh.as_uint256()); }); } -bool -SHAMapInnerNode::isEmpty() const -{ - return isBranch_ == 0; -} - -int -SHAMapInnerNode::getBranchCount() const -{ - return popcnt16(isBranch_); -} - std::string SHAMapInnerNode::getString(const SHAMapNodeID& id) const { @@ -292,9 +280,9 @@ SHAMapInnerNode::setChild(int m, std::shared_ptr child) auto const dstIsBranch = [&] { if (child) - return isBranch_ | (1 << m); + return isBranch_ | (1u << m); else - return isBranch_ & ~(1 << m); + return isBranch_ & ~(1u << m); }(); auto const dstToAllocate = popcnt16(dstIsBranch); diff --git a/src/ripple/shamap/impl/TaggedPointer.h b/src/ripple/shamap/impl/TaggedPointer.h index 2371d8ddb2..afc0ef582a 100644 --- a/src/ripple/shamap/impl/TaggedPointer.h +++ b/src/ripple/shamap/impl/TaggedPointer.h @@ -22,6 +22,8 @@ #include +#include +#include #include #include @@ -217,6 +219,31 @@ public: getChildIndex(std::uint16_t isBranch, int i) const; }; +[[nodiscard]] inline int +popcnt16(std::uint16_t a) +{ +#if __cpp_lib_bitops + return std::popcount(a); +#elif defined(__clang__) || defined(__GNUC__) + return __builtin_popcount(a); +#else + // fallback to table lookup + static auto constexpr const tbl = []() { + std::array ret{}; + for (int i = 0; i != 256; ++i) + { + for (int j = 0; j != 8; ++j) + { + if (i & (1 << j)) + ret[i]++; + } + } + return ret; + }(); + return tbl[a & 0xff] + tbl[a >> 8]; +#endif +} + } // namespace ripple #endif diff --git a/src/ripple/shamap/impl/TaggedPointer.ipp b/src/ripple/shamap/impl/TaggedPointer.ipp index 30bf68426b..7cdff6b494 100644 --- a/src/ripple/shamap/impl/TaggedPointer.ipp +++ b/src/ripple/shamap/impl/TaggedPointer.ipp @@ -22,6 +22,7 @@ #include #include +#include #include @@ -159,29 +160,6 @@ deallocateArrays(std::uint8_t boundaryIndex, void* p) freeArrayFuns[boundaryIndex](p); } -[[nodiscard]] inline int -popcnt16(std::uint16_t a) -{ -#if defined(__clang__) || defined(__GNUC__) - return __builtin_popcount(a); -#else - // fallback to table lookup - static auto constexpr const tbl = []() { - std::array ret{}; - for (int i = 0; i != 256; ++i) - { - for (int j = 0; j != 8; ++j) - { - if (i & (1 << j)) - ret[i]++; - } - } - return ret; - }(); - return tbl[a & 0xff] + tbl[a >> 8]; -#endif -} - // Used in `iterChildren` and elsewhere as the hash value for sparse arrays when // the hash isn't actually stored in the array. static SHAMapHash const zeroSHAMapHash; @@ -285,7 +263,7 @@ TaggedPointer::getChildIndex(std::uint16_t isBranch, int i) const // mask sets all the bits >=i to zero and all the bits