rippled
Loading...
Searching...
No Matches
RippleLineCache.cpp
1//------------------------------------------------------------------------------
2/*
3 This file is part of rippled: https://github.com/ripple/rippled
4 Copyright (c) 2012, 2013 Ripple Labs Inc.
5
6 Permission to use, copy, modify, and/or distribute this software for any
7 purpose with or without fee is hereby granted, provided that the above
8 copyright notice and this permission notice appear in all copies.
9
10 THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 ANY SPECIAL , DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17*/
18//==============================================================================
19
20#include <xrpld/app/paths/RippleLineCache.h>
21#include <xrpld/app/paths/TrustLine.h>
22
23namespace ripple {
24
28 : ledger_(ledger), journal_(j)
29{
30 JLOG(journal_.debug()) << "created for ledger " << ledger_->info().seq;
31}
32
34{
35 JLOG(journal_.debug()) << "destroyed for ledger " << ledger_->info().seq
36 << " with " << lines_.size() << " accounts and "
37 << totalLineCount_ << " distinct trust lines.";
38}
39
42 AccountID const& accountID,
43 LineDirection direction)
44{
45 auto const hash = hasher_(accountID);
46 AccountKey key(accountID, direction, hash);
47 AccountKey otherkey(
48 accountID,
51 hash);
52
54
55 auto [it, inserted] = [&]() {
56 if (auto otheriter = lines_.find(otherkey); otheriter != lines_.end())
57 {
58 // The whole point of using the direction flag is to reduce the
59 // number of trust line objects held in memory. Ensure that there is
60 // only a single set of trustlines in the cache per account.
61 auto const size = otheriter->second ? otheriter->second->size() : 0;
62 JLOG(journal_.info())
63 << "Request for "
64 << (direction == LineDirection::outgoing ? "outgoing"
65 : "incoming")
66 << " trust lines for account " << accountID << " found " << size
67 << (direction == LineDirection::outgoing ? " incoming"
68 : " outgoing")
69 << " trust lines. "
70 << (direction == LineDirection::outgoing
71 ? "Deleting the subset of incoming"
72 : "Returning the superset of outgoing")
73 << " trust lines. ";
74 if (direction == LineDirection::outgoing)
75 {
76 // This request is for the outgoing set, but there is already a
77 // subset of incoming lines in the cache. Erase that subset
78 // to be replaced by the full set. The full set will be built
79 // below, and will be returned, if needed, on subsequent calls
80 // for either value of outgoing.
81 XRPL_ASSERT(
82 size <= totalLineCount_,
83 "ripple::RippleLineCache::getRippleLines : maximum lines");
84 totalLineCount_ -= size;
85 lines_.erase(otheriter);
86 }
87 else
88 {
89 // This request is for the incoming set, but there is
90 // already a superset of the outgoing trust lines in the cache.
91 // The path finding engine will disregard the non-rippling trust
92 // lines, so to prevent them from being stored twice, return the
93 // outgoing set.
94 key = otherkey;
95 return std::pair{otheriter, false};
96 }
97 }
98 return lines_.emplace(key, nullptr);
99 }();
100
101 if (inserted)
102 {
103 XRPL_ASSERT(
104 it->second == nullptr,
105 "ripple::RippleLineCache::getRippleLines : null lines");
106 auto lines =
107 PathFindTrustLine::getItems(accountID, *ledger_, direction);
108 if (lines.size())
109 {
110 it->second = std::make_shared<std::vector<PathFindTrustLine>>(
111 std::move(lines));
112 totalLineCount_ += it->second->size();
113 }
114 }
115
116 XRPL_ASSERT(
117 !it->second || (it->second->size() > 0),
118 "ripple::RippleLineCache::getRippleLines : null or nonempty lines");
119 auto const size = it->second ? it->second->size() : 0;
120 JLOG(journal_.trace()) << "getRippleLines for ledger "
121 << ledger_->info().seq << " found " << size
123 ? " outgoing"
124 : " incoming")
125 << " lines for " << (inserted ? "new " : "existing ")
126 << accountID << " out of a total of "
127 << lines_.size() << " accounts and "
128 << totalLineCount_ << " trust lines";
129
130 return it->second;
131}
132
133} // namespace ripple
A generic endpoint for log messages.
Definition: Journal.h:60
Stream debug() const
Definition: Journal.h:328
Stream info() const
Definition: Journal.h:334
Stream trace() const
Severity stream access functions.
Definition: Journal.h:322
static std::vector< PathFindTrustLine > getItems(AccountID const &accountID, ReadView const &view, LineDirection direction)
Definition: TrustLine.cpp:89
std::shared_ptr< ReadView const > ledger_
ripple::hardened_hash hasher_
hash_map< AccountKey, std::shared_ptr< std::vector< PathFindTrustLine > >, AccountKey::Hash > lines_
std::shared_ptr< std::vector< PathFindTrustLine > > getRippleLines(AccountID const &accountID, LineDirection direction)
Find the trust lines associated with an account.
RippleLineCache(std::shared_ptr< ReadView const > const &l, beast::Journal j)
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition: algorithm.h:25
LineDirection
Describes how an account was found in a path, and how to find the next set of paths.
Definition: TrustLine.h:42