xrpld
Loading...
Searching...
No Matches
DirectoryHelpers.cpp
1#include <xrpl/ledger/helpers/DirectoryHelpers.h>
2
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/beast/utility/instrumentation.h>
5#include <xrpl/ledger/ApplyView.h>
6#include <xrpl/ledger/ReadView.h>
7#include <xrpl/protocol/AccountID.h>
8#include <xrpl/protocol/Indexes.h>
9#include <xrpl/protocol/Keylet.h>
10#include <xrpl/protocol/LedgerFormats.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/STLedgerEntry.h>
13
14#include <cstdint>
15#include <functional>
16namespace xrpl {
17
18bool
20 ApplyView& view,
21 uint256 const& root,
22 SLE::pointer& page,
23 unsigned int& index,
24 uint256& entry)
25{
26 return detail::internalDirFirst(view, root, page, index, entry);
27}
28
29bool
31 ApplyView& view,
32 uint256 const& root,
33 SLE::pointer& page,
34 unsigned int& index,
35 uint256& entry)
36{
37 return detail::internalDirNext(view, root, page, index, entry);
38}
39
40bool
42 ReadView const& view,
43 uint256 const& root,
45 unsigned int& index,
46 uint256& entry)
47{
48 return detail::internalDirFirst(view, root, page, index, entry);
49}
50
51bool
53 ReadView const& view,
54 uint256 const& root,
56 unsigned int& index,
57 uint256& entry)
58{
59 return detail::internalDirNext(view, root, page, index, entry);
60}
61
62void
63forEachItem(ReadView const& view, Keylet const& root, std::function<void(SLE::const_ref)> const& f)
64{
65 XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItem : valid root type");
66
67 if (root.type != ltDIR_NODE)
68 return;
69
70 auto pos = root;
71
72 while (true)
73 {
74 auto sle = view.read(pos);
75 if (!sle)
76 return;
77 for (auto const& key : sle->getFieldV256(sfIndexes))
78 f(view.read(keylet::child(key)));
79 auto const next = sle->getFieldU64(sfIndexNext);
80 if (next == 0u)
81 return;
82 pos = keylet::page(root, next);
83 }
84}
85
86bool
88 ReadView const& view,
89 Keylet const& root,
90 uint256 const& after,
91 std::uint64_t const hint,
92 unsigned int limit,
93 std::function<bool(SLE::const_ref)> const& f)
94{
95 XRPL_ASSERT(root.type == ltDIR_NODE, "xrpl::forEachItemAfter : valid root type");
96
97 if (root.type != ltDIR_NODE)
98 return false;
99
100 auto currentIndex = root;
101
102 // If startAfter is not zero try jumping to that page using the hint
103 if (after.isNonZero())
104 {
105 auto const hintIndex = keylet::page(root, hint);
106
107 if (auto hintDir = view.read(hintIndex))
108 {
109 for (auto const& key : hintDir->getFieldV256(sfIndexes))
110 {
111 if (key == after)
112 {
113 // We found the hint, we can start here
114 currentIndex = hintIndex;
115 break;
116 }
117 }
118 }
119
120 bool found = false;
121 for (;;)
122 {
123 auto const ownerDir = view.read(currentIndex);
124 if (!ownerDir)
125 return found;
126 for (auto const& key : ownerDir->getFieldV256(sfIndexes))
127 {
128 if (!found)
129 {
130 if (key == after)
131 found = true;
132 }
133 else if (f(view.read(keylet::child(key))) && limit-- <= 1)
134 {
135 return found;
136 }
137 }
138
139 auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
140 if (uNodeNext == 0)
141 return found;
142 currentIndex = keylet::page(root, uNodeNext);
143 }
144 }
145 else
146 {
147 for (;;)
148 {
149 auto const ownerDir = view.read(currentIndex);
150 if (!ownerDir)
151 return true;
152 for (auto const& key : ownerDir->getFieldV256(sfIndexes))
153 {
154 if (f(view.read(keylet::child(key))) && limit-- <= 1)
155 return true;
156 }
157 auto const uNodeNext = ownerDir->getFieldU64(sfIndexNext);
158 if (uNodeNext == 0)
159 return true;
160 currentIndex = keylet::page(root, uNodeNext);
161 }
162 }
163}
164
165bool
166dirIsEmpty(ReadView const& view, Keylet const& k)
167{
168 auto const sleNode = view.read(k);
169 if (!sleNode)
170 return true;
171 if (!sleNode->getFieldV256(sfIndexes).empty())
172 return false;
173 // The first page of a directory may legitimately be empty even if there
174 // are other pages (the first page is the anchor page) so check to see if
175 // there is another page. If there is, the directory isn't empty.
176 return sleNode->getFieldU64(sfIndexNext) == 0;
177}
178
181{
182 return [account](SLE::ref sle) { (*sle)[sfOwner] = account; };
183}
184
185} // namespace xrpl
Writeable view to a ledger, for applying a transaction.
Definition ApplyView.h:118
A view into a ledger.
Definition ReadView.h:31
virtual SLE::const_pointer read(Keylet const &k) const =0
Return the state item associated with a key.
std::shared_ptr< STLedgerEntry > const & ref
std::shared_ptr< STLedgerEntry > pointer
std::shared_ptr< STLedgerEntry const > const & const_ref
std::shared_ptr< STLedgerEntry const > const_pointer
bool internalDirFirst(V &view, uint256 const &root, std::shared_ptr< N > &page, unsigned int &index, uint256 &entry)
bool internalDirNext(V &view, uint256 const &root, std::shared_ptr< N > &page, unsigned int &index, uint256 &entry)
Keylet child(uint256 const &key) noexcept
Any item that can be in an owner dir.
Definition Indexes.cpp:192
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Definition Indexes.cpp:363
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
Definition algorithm.h:5
bool dirIsEmpty(ReadView const &view, Keylet const &k)
Returns true if the directory is empty.
Number root(Number f, unsigned d)
Definition Number.cpp:1201
bool dirNext(ApplyView &view, uint256 const &root, SLE::pointer &page, unsigned int &index, uint256 &entry)
bool after(NetClock::time_point now, std::uint32_t mark)
Has the specified time passed?
Definition View.cpp:554
std::function< void(SLE::ref)> describeOwnerDir(AccountID const &account)
Returns a function that sets the owner on a directory SLE.
BaseUInt< 160, detail::AccountIDTag > AccountID
A 160-bit unsigned that uniquely identifies an account.
Definition AccountID.h:28
bool cdirNext(ReadView const &view, uint256 const &root, SLE::const_pointer &page, unsigned int &index, uint256 &entry)
Returns the next entry in the directory, advancing the index.
void forEachItem(ReadView const &view, Keylet const &root, std::function< void(SLE::const_ref)> const &f)
Iterate all items in the given directory.
bool cdirFirst(ReadView const &view, uint256 const &root, SLE::const_pointer &page, unsigned int &index, uint256 &entry)
Returns the first entry in the directory, advancing the index.
BaseUInt< 256 > uint256
Definition base_uint.h:562
bool forEachItemAfter(ReadView const &view, Keylet const &root, uint256 const &after, std::uint64_t const hint, unsigned int limit, std::function< bool(SLE::const_ref)> const &f)
Iterate all items after an item in the given directory.
bool dirFirst(ApplyView &view, uint256 const &root, SLE::pointer &page, unsigned int &index, uint256 &entry)
A pair of SHAMap key and LedgerEntryType.
Definition Keylet.h:19