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>
122 auto const& prev = *before;
139 auto const& cur = *
after;
146 if (oldTakerPays != zero && oldTakerGets != zero)
170 auto const& prev = *before;
171 switch (prev.getType())
207 auto const& cur = *
after;
208 switch (cur.getType())
211 auto const curXrp = cur[
sfBalance].xrp();
212 if (!before || (*before)[
sfBalance].xrp() != curXrp)
219 if (!before || (*before)[
sfBalance] != curBalance)
224 curBalance.getCurrency()),
231 if (!before || (*before)[
sfTakerGets] != curTakerGets ||
256 boost::container::static_vector<FuncType, 2> filters;
263 auto each = [&result, &filters](
271 [&result, isDelete, &before, &
after](FuncType func) {
272 return func(result, isDelete, before, after);
277 table.
visit(view, each);
317 findDiffs(lhsFilter, lhs, rhsFilter, rhs);
375 template <
typename T,
typename U>
383 auto lhsItr = lhs.
cbegin();
384 auto rhsItr = rhs.cbegin();
386 while (lhsItr != lhs.cend() || rhsItr != rhs.cend())
388 if (lhsItr == lhs.cend())
394 else if (rhsItr == rhs.cend())
400 else if (lhsItr->first < rhsItr->first)
406 else if (rhsItr->first < lhsItr->first)
466 bool const lhsBigger =
472 if (bigger.
offerChanges[0].second.takerGets().mantissa() -
473 smaller.
offerChanges[0].second.takerGets().mantissa() !=
491 return lhsBigger ? -1 : 1;
499 for (
auto i = 0; i < lhs.
count(); ++i)
508 template <
typename T,
typename U,
typename L>
516 std::is_same<
bool, decltype(justDust(lhs[0].second, rhs[0].second))>::
518 "Invalid lambda passed to rmVecDust");
520 bool dustWasRemoved =
false;
521 auto lhsItr = lhs.begin();
522 while (lhsItr != lhs.end())
529 [](value_t
const& a, value_t
const& b) {
530 return a.first < b.first;
533 if (found.first != found.second)
537 if (justDust(lhsItr->second, found.first->second))
539 dustWasRemoved =
true;
540 rhs.erase(found.first);
542 lhsItr = lhs.erase(lhsItr);
548 return dustWasRemoved;
554 bool removedDust =
false;
563 lhsDiffs_.xrpChanges,
564 rhsDiffs_.xrpChanges,
566 return diffIsDust(lhs, rhs);
571 lhsDiffs_.trustChanges,
572 rhsDiffs_.trustChanges,
574 return diffIsDust(lhs, rhs);
579 lhsDiffs_.offerChanges,
580 rhsDiffs_.offerChanges,
586 lhsDiffs_.offerDeletions,
587 rhsDiffs_.offerDeletions,
597 bool const ret = !lhsDiffs_.offerDeletions.empty();
599 lhsDiffs_.offerDeletions.clear();
606 bool const ret = !rhsDiffs_.offerDeletions.empty();
608 rhsDiffs_.offerDeletions.clear();
613 template <
typename T>
640 auto lhsDiffs = getCashFlow(view_, lhsFilter, lhs);
641 auto rhsDiffs = getCashFlow(view_, rhsFilter, rhs);
644 auto const counts =
countKeys(lhsDiffs, rhsDiffs);
645 commonKeys_ = counts[0];
646 lhsKeys_ = counts[1];
647 rhsKeys_ = counts[2];
651 setDiff(lhsDiffs.xrpChanges, rhsDiffs.xrpChanges, lhsDiffs_.xrpChanges);
652 setDiff(rhsDiffs.xrpChanges, lhsDiffs.xrpChanges, rhsDiffs_.xrpChanges);
656 lhsDiffs.trustChanges, rhsDiffs.trustChanges, lhsDiffs_.trustChanges);
658 rhsDiffs.trustChanges, lhsDiffs.trustChanges, rhsDiffs_.trustChanges);
662 lhsDiffs.trustDeletions,
663 rhsDiffs.trustDeletions,
664 lhsDiffs_.trustDeletions);
666 rhsDiffs.trustDeletions,
667 lhsDiffs.trustDeletions,
668 rhsDiffs_.trustDeletions);
672 lhsDiffs.offerChanges, rhsDiffs.offerChanges, lhsDiffs_.offerChanges);
674 rhsDiffs.offerChanges, lhsDiffs.offerChanges, rhsDiffs_.offerChanges);
678 lhsDiffs.offerDeletions,
679 rhsDiffs.offerDeletions,
680 lhsDiffs_.offerDeletions);
682 rhsDiffs.offerDeletions,
683 lhsDiffs.offerDeletions,
684 rhsDiffs_.offerDeletions);
702 :
impl_(new
Impl(view, lhsFilter, lhs, rhsFilter, rhs))
709 return impl_->commonCount();
715 return impl_->rhsOnlyCount();
721 return impl_->lhsOnlyCount();
727 return impl_->hasDiff();
733 return impl_->xrpRoundToZero();
739 return impl_->rmDust();
745 return impl_->rmLhsDeletedOffers();
751 return impl_->rmRhsDeletedOffers();
763 if (v1 != beast::zero && v2 != beast::zero &&
778 STAmount const& small = v1 < v2 ? v1 : v2;
779 STAmount const& large = v1 < v2 ? v2 : v1;
806 1
'000'000
'000'000ULL,
807 10
'000'000
'000'000ULL,
808 100
'000'000
'000'000ULL,
809 1
'000'000
'000'000
'000ULL,
810 10'000
'000'000
'000'000ULL,
811 100
'000'000
'000'000
'000ULL,
812 1'000
'000'000
'000'000
'000ULL,
813 10'000
'000'000
'000'000
'000ULL,
815 static std::size_t constexpr maxIndex =
816 sizeof(e10Lookup) / sizeof e10Lookup[0];
818 // Make sure the table is big enough.
820 std::numeric_limits<std::uint64_t>::max() /
821 e10Lookup[maxIndex - 1] <
828 return ratio >= e10Lookup[e10];
831 // Non-native. Note that even though large and small may not be equal,
832 // their difference may be zero. One way that can happen is if two
833 // values are different, but their difference results in an STAmount
834 // with an exponent less than -96.
835 STAmount const diff = large - small;
836 if (diff == beast::zero)
839 STAmount const ratio = divide(small, diff, v1.issue());
840 STAmount const one(v1.issue(), 1);
841 int const ratioExp = ratio.exponent() - one.exponent();
843 return ratioExp >= e10;
846 } // namespace ripple