20#ifndef FRACTURE_EDGE_INDEX_UTILS_H
21#define FRACTURE_EDGE_INDEX_UTILS_H
42 const double count = std::clamp( std::sqrt(
static_cast<double>( aEdgeCount ) ), 1.0,
44 return static_cast<uint32_t
>( count );
47inline uint32_t
MapYToStripe(
int aY,
int aMinY,
int aMaxY, uint32_t aStripeCount )
53 const int64_t range = int64_t( aMaxY ) - int64_t( aMinY ) + 1;
54 const int64_t offset = std::clamp<int64_t>( int64_t( aY ) - int64_t( aMinY ), 0, range - 1 );
55 const uint64_t mapped = uint64_t( offset ) * aStripeCount / uint64_t( range );
56 return std::min<uint32_t>(
static_cast<uint32_t
>( mapped ), aStripeCount - 1 );
59inline std::pair<uint32_t, uint32_t>
StripeSpan(
int aY1,
int aY2,
int aMinY,
int aMaxY, uint32_t aStripeCount )
61 return {
MapYToStripe( std::min( aY1, aY2 ), aMinY, aMaxY, aStripeCount ),
62 MapYToStripe( std::max( aY1, aY2 ), aMinY, aMaxY, aStripeCount ) };
65inline bool CheckedAdd(
size_t& aTotal,
size_t aCount,
size_t aElementSize )
67 if( aElementSize == 0 )
70 if( aCount > ( std::numeric_limits<size_t>::max() - aTotal ) / aElementSize )
73 aTotal += aCount * aElementSize;
83 if( !
CheckedAdd( budget, aEdgeCount, aEdgeSize ) )
84 return std::numeric_limits<size_t>::max();
90inline bool CapacityFits(
size_t aBucketIds,
size_t aLongIds,
size_t aStripeCount,
size_t aHoleCount,
size_t aNodeSize,
95 return CheckedAdd( bytes, aBucketIds,
sizeof( uint32_t ) ) &&
CheckedAdd( bytes, aLongIds,
sizeof( uint32_t ) )
96 &&
CheckedAdd( bytes, aStripeCount + 1,
sizeof( uint32_t ) )
97 &&
CheckedAdd( bytes, aStripeCount,
sizeof( uint32_t ) )
98 &&
CheckedAdd( bytes, aStripeCount + 1,
sizeof( uint32_t ) )
102inline bool ActualCapacityFits(
size_t aBucketIds,
size_t aLongIds,
size_t aOffsets,
size_t aScratch,
size_t aHeads,
103 size_t aNodes,
size_t aNodeSize,
size_t aBudget,
size_t* aBytes =
nullptr )
107 const bool valid =
CheckedAdd( bytes, aBucketIds,
sizeof( uint32_t ) )
108 &&
CheckedAdd( bytes, aLongIds,
sizeof( uint32_t ) )
109 &&
CheckedAdd( bytes, aOffsets,
sizeof( uint32_t ) )
110 &&
CheckedAdd( bytes, aScratch,
sizeof( uint32_t ) )
114 *aBytes = valid ? bytes : 0;
116 return valid && bytes <= aBudget;
119inline bool ShouldIndex( uint64_t aEstimatedVisits,
size_t aHoleCount )
std::pair< uint32_t, uint32_t > StripeSpan(int aY1, int aY2, int aMinY, int aMaxY, uint32_t aStripeCount)
constexpr size_t EDGE_SET_BUDGET_MULTIPLE
size_t CapacityBudget(size_t aEdgeCount, size_t aEdgeSize)
bool ActualCapacityFits(size_t aBucketIds, size_t aLongIds, size_t aOffsets, size_t aScratch, size_t aHeads, size_t aNodes, size_t aNodeSize, size_t aBudget, size_t *aBytes=nullptr)
constexpr uint32_t MAX_STRIPES
bool ShouldIndex(uint64_t aEstimatedVisits, size_t aHoleCount)
constexpr size_t MIN_HOLE_COUNT
constexpr uint64_t MIN_EDGE_VISITS
bool CapacityFits(size_t aBucketIds, size_t aLongIds, size_t aStripeCount, size_t aHoleCount, size_t aNodeSize, size_t aBudget)
bool CheckedAdd(size_t &aTotal, size_t aCount, size_t aElementSize)
uint32_t MapYToStripe(int aY, int aMinY, int aMaxY, uint32_t aStripeCount)
constexpr uint32_t MAX_BUCKET_SPAN
uint32_t StripeCountFor(size_t aEdgeCount)