20 #include <ripple/ledger/CashDiff.h>
21 #include <ripple/ledger/detail/ApplyStateTable.h>
22 #include <ripple/protocol/st.h>
23 #include <boost/container/static_vector.hpp>
117 auto const& prev = *before;
121 if (prev.getType() ==
ltOFFER &&
134 auto const& cur = *
after;
135 if (cur.getType() ==
ltOFFER &&
141 if (oldTakerPays != zero && oldTakerGets != zero)
163 auto const& prev = *before;
164 switch(prev.getType())
202 auto const& cur = *
after;
203 switch(cur.getType())
207 auto const curXrp = cur[
sfBalance].xrp();
208 if (!before || (*before)[
sfBalance].xrp() != curXrp)
216 if (!before || (*before)[
sfBalance] != curBalance)
222 curBalance.getCurrency()),
230 if (!before || (*before)[
sfTakerGets] != curTakerGets ||
256 boost::container::static_vector<FuncType, 2> filters;
263 auto each = [&result, &filters](
uint256 const& key,
bool isDelete,
268 [&result, isDelete, &before, &
after] (FuncType func) {
269 return func (result, isDelete, before, after);
274 table.
visit (view, each);
311 findDiffs (lhsFilter, lhs, rhsFilter, rhs);
359 template <
typename T,
typename U>
366 auto lhsItr = lhs.
cbegin();
367 auto rhsItr = rhs.cbegin();
369 while (lhsItr != lhs.cend() || rhsItr != rhs.cend())
371 if (lhsItr == lhs.cend())
377 else if (rhsItr == rhs.cend())
383 else if (lhsItr->first < rhsItr->first)
389 else if (rhsItr->first < lhsItr->first)
445 bool const lhsBigger =
451 if (bigger.
offerChanges[0].second.takerGets().mantissa() -
452 smaller.
offerChanges[0].second.takerGets().mantissa() != 1)
469 return lhsBigger ? -1 : 1;
477 for (
auto i = 0; i < lhs.
count(); ++i)
486 template <
typename T,
typename U,
typename L>
495 decltype (justDust (lhs[0].second, rhs[0].second))>::value,
496 "Invalid lambda passed to rmVecDust");
498 bool dustWasRemoved =
false;
499 auto lhsItr = lhs.begin();
500 while (lhsItr != lhs.end())
504 [] (value_t
const& a, value_t
const& b)
506 return a.first < b.first;
509 if (found.first != found.second)
513 if (justDust (lhsItr->second, found.first->second))
515 dustWasRemoved =
true;
516 rhs.erase (found.first);
518 lhsItr = lhs.erase (lhsItr);
524 return dustWasRemoved;
529 bool removedDust =
false;
537 removedDust |=
rmVecDust (lhsDiffs_.xrpChanges, rhsDiffs_.xrpChanges,
540 return diffIsDust (lhs, rhs);
544 removedDust |=
rmVecDust (lhsDiffs_.trustChanges, rhsDiffs_.trustChanges,
547 return diffIsDust (lhs, rhs);
551 removedDust |=
rmVecDust (lhsDiffs_.offerChanges, rhsDiffs_.offerChanges,
554 return diffIsDust (lhs, rhs);
559 lhsDiffs_.offerDeletions, rhsDiffs_.offerDeletions,
562 return diffIsDust (lhs, rhs);
570 bool const ret = !lhsDiffs_.offerDeletions.empty();
572 lhsDiffs_.offerDeletions.clear();
578 bool const ret = !rhsDiffs_.offerDeletions.empty();
580 rhsDiffs_.offerDeletions.clear();
585 template <
typename T>
605 auto lhsDiffs = getCashFlow (view_, lhsFilter, lhs);
606 auto rhsDiffs = getCashFlow (view_, rhsFilter, rhs);
609 auto const counts =
countKeys (lhsDiffs, rhsDiffs);
610 commonKeys_ = counts[0];
611 lhsKeys_ = counts[1];
612 rhsKeys_ = counts[2];
616 setDiff (lhsDiffs.xrpChanges, rhsDiffs.xrpChanges, lhsDiffs_.xrpChanges);
617 setDiff (rhsDiffs.xrpChanges, lhsDiffs.xrpChanges, rhsDiffs_.xrpChanges);
620 setDiff (lhsDiffs.trustChanges, rhsDiffs.trustChanges, lhsDiffs_.trustChanges);
621 setDiff (rhsDiffs.trustChanges, lhsDiffs.trustChanges, rhsDiffs_.trustChanges);
624 setDiff (lhsDiffs.trustDeletions, rhsDiffs.trustDeletions, lhsDiffs_.trustDeletions);
625 setDiff (rhsDiffs.trustDeletions, lhsDiffs.trustDeletions, rhsDiffs_.trustDeletions);
628 setDiff (lhsDiffs.offerChanges, rhsDiffs.offerChanges, lhsDiffs_.offerChanges);
629 setDiff (rhsDiffs.offerChanges, lhsDiffs.offerChanges, rhsDiffs_.offerChanges);
632 setDiff (lhsDiffs.offerDeletions, rhsDiffs.offerDeletions, lhsDiffs_.offerDeletions);
633 setDiff (rhsDiffs.offerDeletions, lhsDiffs.offerDeletions, rhsDiffs_.offerDeletions);
640 :
impl_ (std::move (other.impl_))
649 :
impl_ (new
Impl (view, lhsFilter, lhs, rhsFilter, rhs))
655 return impl_->commonCount();
660 return impl_->rhsOnlyCount();
665 return impl_->lhsOnlyCount();
670 return impl_->hasDiff();
675 return impl_->xrpRoundToZero();
680 return impl_->rmDust();
685 return impl_->rmLhsDeletedOffers();
690 return impl_->rmRhsDeletedOffers();
701 if (v1 != beast::zero && v2 != beast::zero && (v1.
negative() != v2.
negative()))
715 STAmount const& small = v1 < v2 ? v1 : v2;
716 STAmount const& large = v1 < v2 ? v2 : v1;
744 1
'000'000
'000'000ULL,
745 10
'000'000
'000'000ULL,
746 100
'000'000
'000'000ULL,
747 1
'000'000
'000'000
'000ULL,
748 10'000
'000'000
'000'000ULL,
749 100
'000'000
'000'000
'000ULL,
750 1'000
'000'000
'000'000
'000ULL,
751 10'000
'000'000
'000'000
'000ULL,
753 static std::size_t constexpr maxIndex =
754 sizeof (e10Lookup) / sizeof e10Lookup[0];
756 // Make sure the table is big enough.
758 std::numeric_limits<std::uint64_t>::max() /
759 e10Lookup[maxIndex - 1] < 10, "Table too small");
764 return ratio >= e10Lookup[e10];
767 // Non-native. Note that even though large and small may not be equal,
768 // their difference may be zero. One way that can happen is if two
769 // values are different, but their difference results in an STAmount
770 // with an exponent less than -96.
771 STAmount const diff = large - small;
772 if (diff == beast::zero)
775 STAmount const ratio = divide (small, diff, v1.issue());
776 STAmount const one (v1.issue(), 1);
777 int const ratioExp = ratio.exponent() - one.exponent();
779 return ratioExp >= e10;