5#ifndef BITCOIN_UTIL_FEEFRAC_H
6#define BITCOIN_UTIL_FEEFRAC_H
26 static inline std::pair<int64_t, uint32_t>
MulFallback(int64_t a, int32_t b)
noexcept
28 int64_t low = int64_t{
static_cast<uint32_t
>(a)} * b;
29 int64_t high = (a >> 32) * b;
30 return {high + (low >> 32),
static_cast<uint32_t
>(low)};
41 static inline int64_t
DivFallback(std::pair<int64_t, uint32_t> n, int32_t d,
bool round_down)
noexcept
47 int64_t quot_high = n.first / d;
50 int64_t n_low = ((n.first % d) << 32) + n.second;
55 int64_t quot_low = n_low / d;
56 int32_t mod_low = n_low % d;
57 quot_low += (mod_low > 0) - (mod_low && round_down);
59 return (quot_high << 32) + quot_low;
62#ifdef __SIZEOF_INT128__
65 static inline __int128
Mul(int64_t a, int32_t b)
noexcept
67 return __int128{a} * b;
75 static inline int64_t
Div(__int128 n, int32_t d,
bool round_down)
noexcept
82 return quot + ((mod > 0) - (mod && round_down));
123 return {a.
fee + b.fee, a.size + b.size};
129 return {a.
fee - b.fee, a.size - b.size};
135 return a.fee == b.fee && a.size == b.size;
141 std::swap(a.fee, b.fee);
142 std::swap(a.size, b.size);
154 template<
bool RoundDown>
159 if (
fee >= 0 &&
fee < 0x200000000) [[likely]] {
161 if constexpr (RoundDown) {
162 return (uint64_t(
fee) * at_size) / uint32_t(
size);
174 int64_t
EvaluateFeeDown(int32_t at_size)
const noexcept {
return EvaluateFee<true>(at_size); }
176 int64_t
EvaluateFeeUp(int32_t at_size)
const noexcept {
return EvaluateFee<false>(at_size); }
187std::partial_ordering
CompareChunks(std::span<const FeeFrac> chunks0, std::span<const FeeFrac> chunks1);
190template<
typename Tag>
199 return {feefrac.
fee, feefrac.size};
217template<std::derived_from<FeeFrac> T>
227 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
228 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
229 return cross_a == cross_b;
237 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
238 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
239 return cross_a <=> cross_b;
246 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
247 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
248 return cross_a < cross_b;
252 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
253 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
254 return cross_a > cross_b;
258 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
259 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
260 return cross_a <= cross_b;
264 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
265 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
266 return cross_a >= cross_b;
288template<std::derived_from<FeeFrac> T>
298 return a.m_feefrac == b.m_feefrac;
303 auto cross_a = T::Mul(a.m_feefrac.fee, b.m_feefrac.size);
304 auto cross_b = T::Mul(b.m_feefrac.fee, a.m_feefrac.size);
305 auto cmp = cross_a <=> cross_b;
306 if (cmp != 0)
return cmp;
307 return b.m_feefrac.size <=> a.m_feefrac.size;
#define Assume(val)
Assume is the identity function.
Wrapper around FeeFrac & derived types, which adds a feerate-based ordering which treats equal-feerat...
friend bool operator<(const ByRatio &a, const ByRatio &b) noexcept
friend bool operator>=(const ByRatio &a, const ByRatio &b) noexcept
friend bool operator<=(const ByRatio &a, const ByRatio &b) noexcept
constexpr ByRatio(const T &feefrac) noexcept
friend bool operator==(const ByRatio &a, const ByRatio &b) noexcept
friend std::strong_ordering operator<=>(const ByRatio &a, const ByRatio &b) noexcept
friend bool operator>(const ByRatio &a, const ByRatio &b) noexcept
Wrapper around FeeFrac & derived types, which adds a total ordering which first sorts by feerate and ...
friend std::strong_ordering operator<=>(const ByRatioNegSize &a, const ByRatioNegSize &b) noexcept
constexpr ByRatioNegSize(const T &feefrac) noexcept
friend bool operator==(const ByRatioNegSize &a, const ByRatioNegSize &b) noexcept
std::partial_ordering CompareChunks(std::span< const FeeFrac > chunks0, std::span< const FeeFrac > chunks1)
Compare the feerate diagrams implied by the provided sorted chunks data.
constexpr auto CeilDiv(const Dividend dividend, const Divisor divisor)
Integer ceiling division (for unsigned values).
Data structure storing a fee and size.
constexpr FeeFrac(int64_t f, int32_t s) noexcept
Construct a FeeFrac with specified fee and size.
friend FeeFrac operator-(const FeeFrac &a, const FeeFrac &b) noexcept
Subtract both fee and size.
friend void swap(FeeFrac &a, FeeFrac &b) noexcept
Swap two FeeFracs.
int64_t EvaluateFeeDown(int32_t at_size) const noexcept
Compute the fee for a given size at_size using this object's feerate, rounding down.
int64_t EvaluateFee(int32_t at_size) const noexcept
Compute the fee for a given size at_size using this object's feerate.
static int64_t DivFallback(std::pair< int64_t, uint32_t > n, int32_t d, bool round_down) noexcept
Helper function for 96/32 signed division, rounding towards negative infinity (if round_down) or posi...
int64_t EvaluateFeeUp(int32_t at_size) const noexcept
Compute the fee for a given size at_size using this object's feerate, rounding up.
constexpr FeeFrac(const FeeFrac &) noexcept=default
static constexpr auto Div
constexpr FeeFrac & operator=(const FeeFrac &) noexcept=default
static constexpr auto Mul
void operator-=(const FeeFrac &other) noexcept
Subtract fee and size of another FeeFrac from this one.
void operator+=(const FeeFrac &other) noexcept
Add fee and size of another FeeFrac to this one.
bool IsEmpty() const noexcept
Check if this is empty (size and fee are 0).
constexpr FeeFrac() noexcept
Construct an IsEmpty() FeeFrac.
static std::pair< int64_t, uint32_t > MulFallback(int64_t a, int32_t b) noexcept
Helper function for 32*64 signed multiplication, returning an unspecified but totally ordered type.
friend FeeFrac operator+(const FeeFrac &a, const FeeFrac &b) noexcept
Sum fee and size.
friend bool operator==(const FeeFrac &a, const FeeFrac &b) noexcept
Check if two FeeFrac objects are equal (both same fee and same size).
Tagged wrapper around FeeFrac to avoid unit confusion.
static FeePerUnit FromFeeFrac(const FeeFrac &feefrac) noexcept
Convert a FeeFrac to a FeePerUnit.