20 #ifndef RIPPLE_APP_CONSENSUS_LEDGERS_TRIE_H_INCLUDED 
   21 #define RIPPLE_APP_CONSENSUS_LEDGERS_TRIE_H_INCLUDED 
   23 #include <ripple/basics/ToString.h> 
   24 #include <ripple/json/json_value.h> 
   36 template <
class Ledger>
 
   40     using Seq = 
typename Ledger::Seq;
 
   41     using ID = 
typename Ledger::ID;
 
   72 namespace ledger_trie_detail {
 
   75 template <
class Ledger>
 
   78     using Seq = 
typename Ledger::Seq;
 
   79     using ID = 
typename Ledger::ID;
 
  182         return o << s.
tip().id << 
"[" << s.
start_ << 
"," << s.
end_ << 
")";
 
  197 template <
class Ledger>
 
  230                 return curr.get() == child;
 
  250         res[
"span"] = sps.
str();
 
  260                 cs.
append(child->getJson());
 
  345 template <
class Ledger>
 
  348     using Seq = 
typename Ledger::Seq;
 
  349     using ID = 
typename Ledger::ID;
 
  374         Seq pos = curr->
span.diff(ledger);
 
  380         while (!done && pos == curr->
span.end())
 
  386                 auto const childPos = child->span.diff(ledger);
 
  410         if (ledger.id() == parent->span.tip().id)
 
  412         for (
auto const& child : parent->children)
 
  434                 dumpImpl(o, child, offset + 1 + ss.
str().size() + 2);
 
  451         auto const [loc, diffSeq] = 
find(ledger);
 
  485             auto newNode = std::make_unique<Node>(*oldSuffix);
 
  486             newNode->tipSupport = loc->tipSupport;
 
  487             newNode->branchSupport = loc->branchSupport;
 
  488             newNode->children = std::move(loc->children);
 
  489             assert(loc->children.empty());
 
  491                 child->parent = newNode.get();
 
  496             newNode->parent = loc;
 
  497             loc->children.emplace_back(std::move(newNode));
 
  510             auto newNode = std::make_unique<Node>(*newSuffix);
 
  511             newNode->parent = loc;
 
  513             incNode = newNode.get();
 
  514             loc->
children.push_back(std::move(newNode));
 
  521             incNode = incNode->
parent;
 
  556             decNode = decNode->
parent;
 
  571                 child->span = merge(loc->
span, child->span);
 
  572                 child->parent = parent;
 
  573                 parent->
children.emplace_back(std::move(child));
 
  592             return loc->tipSupport;
 
  611             if (!(diffSeq > ledger.
seq() && ledger.
seq() < loc->
span.end()))
 
  689         while (curr && !done)
 
  699                        uncommittedIt->first < 
std::max(nextSeq, largestIssued))
 
  701                     uncommitted += uncommittedIt->second;
 
  706                 while (nextSeq < curr->span.end() &&
 
  711                         uncommittedIt->first < curr->
span.end())
 
  713                         nextSeq = uncommittedIt->first + 
Seq{1};
 
  714                         uncommitted += uncommittedIt->second;
 
  718                         nextSeq = curr->
span.end();
 
  722                 if (nextSeq < curr->span.end())
 
  723                     return curr->
span.before(nextSeq)->tip();
 
  728             Node* best = 
nullptr;
 
  745                         return std::make_tuple(
 
  746                                    a->branchSupport, a->span.startID()) >
 
  748                                    b->branchSupport, b->span.startID());
 
  752                 margin = curr->
children[0]->branchSupport -
 
  758                 if (best->
span.startID() > curr->
children[1]->span.startID())
 
  764             if (best && ((margin > uncommitted) || (uncommitted == 0)))
 
  769         return curr->
span.tip();
 
  777         return !
root || 
root->branchSupport == 0;
 
  794         res[
"trie"] = 
root->getJson();
 
  797             res[
"seq_support"][
to_string(seq)] = sup;
 
  810         while (!nodes.
empty())
 
  812             Node const* curr = nodes.
top();
 
  826                 expectedSeqSupport[curr->
span.end() - 
Seq{1}] +=
 
  829             for (
auto const& child : curr->
children)
 
  831                 if (child->parent != curr)
 
  834                 support += child->branchSupport;
 
  835                 nodes.
push(child.get());
 
  
RCLValidatedLedger::Seq mismatch(RCLValidatedLedger const &a, RCLValidatedLedger const &b)
std::uint32_t branchSupport(Ledger const &ledger) const
Return the count of branch support for the specific ledger.
typename ripple::Ledger ::Seq Seq
The tip of a span of ledger ancestry.
Json::Value getJson() const
Dump JSON representation of trie state.
SpanTip(Seq s, ID i, Ledger const lgr)
@ arrayValue
array value (ordered list)
bool checkInvariants() const
Check the compressed trie and support invariants.
std::uint32_t tipSupport(Ledger const &ledger) const
Return count of tip support for the specific ledger.
friend std::ostream & operator<<(std::ostream &o, Span const &s)
std::optional< Span > sub(Seq from, Seq to) const
T partial_sort(T... args)
void dump(std::ostream &o) const
Dump an ascii representation of the trie to the stream.
std::optional< SpanTip< Ledger > > getPreferred(Seq const largestIssued) const
Return the preferred ledger ID.
Value & append(const Value &value)
Append value to array at the end.
void insert(Ledger const &ledger, std::uint32_t count=1)
Insert and/or increment the support for the given ledger.
std::vector< std::unique_ptr< Node > > children
@ objectValue
object value (collection of name/value pairs).
std::uint32_t branchSupport
typename ripple::Ledger ::ID ID
ID ancestor(Seq const &s) const
Lookup the ID of an ancestor of the tip ledger.
std::map< Seq, std::uint32_t > seqSupport
Span(Seq start, Seq end, Ledger const &l)
SpanTip< Ledger > tip() const
std::unique_ptr< Node > root
Node * findByLedgerID(Ledger const &ledger, Node *parent=nullptr) const
Find the node in the trie with an exact match to the given ledger ID.
Seq diff(Ledger const &o) const
friend Span merge(Span const &a, Span const &b)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Ancestry trie of ledgers.
LedgerIndex seq() const
Returns the sequence number of the base ledger.
ledger_trie_detail::Node< Ledger > Node
void dumpImpl(std::ostream &o, std::unique_ptr< Node > const &curr, int offset) const
std::pair< Node *, Seq > find(Ledger const &ledger) const
Find the node in the trie that represents the longest common ancestry with the given ledger.
bool empty() const
Return whether the trie is tracking any ledgers.
std::string to_string(Manifest const &m)
Format the specified manifest to a string for debugging purposes.
friend std::ostream & operator<<(std::ostream &o, Node const &s)
std::optional< Span > before(Seq spot) const
bool remove(Ledger const &ledger, std::uint32_t count=1)
Decrease support for a ledger, removing and compressing if possible.
void erase(Node const *child)
Remove the given node from this Node's children.
Json::Value getJson() const
std::optional< Span > from(Seq spot) const
Span & operator=(Span const &)=default