1#include <xrpl/ledger/ApplyView.h>
3#include <xrpl/basics/base_uint.h>
4#include <xrpl/basics/contract.h>
5#include <xrpl/beast/utility/instrumentation.h>
6#include <xrpl/protocol/Feature.h>
7#include <xrpl/protocol/Indexes.h>
8#include <xrpl/protocol/Keylet.h>
9#include <xrpl/protocol/LedgerFormats.h>
10#include <xrpl/protocol/Protocol.h>
11#include <xrpl/protocol/SField.h>
12#include <xrpl/protocol/STLedgerEntry.h>
13#include <xrpl/protocol/STVector256.h>
37 newRoot->setFieldH256(sfRootIndex,
directory.key);
42 newRoot->setFieldV256(sfIndexes, v);
51 std::uint64_t const page = start->getFieldU64(sfIndexPrevious);
61 "Directory chain: root back-pointer broken.");
65 auto indexes = node->getFieldV256(sfIndexes);
93 if (pos != indexes.
end() && key == *pos)
99 node->setFieldV256(sfIndexes, indexes);
133 node->setFieldU64(sfIndexNext, page);
136 next->setFieldU64(sfIndexPrevious, page);
144 node->setFieldH256(sfRootIndex,
directory.key);
145 node->setFieldV256(sfIndexes, indexes);
149 node->setFieldU64(sfIndexPrevious, page - 1);
150 XRPL_ASSERT_PARTS(!nextPage,
"xrpl::directory::insertPage",
"nextPage has default value");
202 UNREACHABLE(
"xrpl::ApplyView::emptyDirDelete : invalid node type");
208 if (!node->getFieldV256(sfIndexes).empty())
212 auto prevPage = node->getFieldU64(sfIndexPrevious);
213 auto nextPage = node->getFieldU64(sfIndexNext);
215 if (nextPage == kRootPage && prevPage != kRootPage)
218 if (prevPage == kRootPage && nextPage != kRootPage)
223 if (nextPage == prevPage && nextPage != kRootPage)
230 if (!last->getFieldV256(sfIndexes).empty())
235 node->setFieldU64(sfIndexNext, kRootPage);
236 node->setFieldU64(sfIndexPrevious, kRootPage);
244 nextPage = kRootPage;
245 prevPage = kRootPage;
249 if (nextPage == kRootPage && prevPage == kRootPage)
266 auto entries = node->getFieldV256(sfIndexes);
270 if (entries.end() == it)
276 node->setFieldV256(sfIndexes, entries);
279 if (!entries.empty())
285 auto prevPage = node->getFieldU64(sfIndexPrevious);
286 auto nextPage = node->getFieldU64(sfIndexNext);
292 if (page == kRootPage)
294 if (nextPage == page && prevPage != page)
297 if (prevPage == page && nextPage != page)
302 if (nextPage == prevPage && nextPage != page)
308 if (last->getFieldV256(sfIndexes).empty())
311 node->setFieldU64(sfIndexNext, page);
312 node->setFieldU64(sfIndexPrevious, page);
328 if (nextPage == page && prevPage == page)
335 if (nextPage == page)
338 if (prevPage == page)
348 prev->setFieldU64(sfIndexNext, nextPage);
355 next->setFieldU64(sfIndexPrevious, prevPage);
363 if (nextPage != kRootPage && next->getFieldU64(sfIndexNext) == kRootPage &&
364 next->getFieldV256(sfIndexes).empty())
370 prev->setFieldU64(sfIndexNext, kRootPage);
378 root->setFieldU64(sfIndexPrevious, prevPage);
381 nextPage = kRootPage;
386 if (!keepRoot && nextPage == kRootPage && prevPage == kRootPage)
388 if (prev->getFieldV256(sfIndexes).empty())
407 for (
auto const& item : page->getFieldV256(sfIndexes))
410 pi = (*page)[~sfIndexNext];
Writeable view to a ledger, for applying a transaction.
virtual SLE::pointer peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
virtual void insert(SLE::ref sle)=0
Insert a new state SLE.
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(SLE::ref)> const &describe)
Add an entry to a directory using the specified insert strategy.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(SLE::ref sle)=0
Remove a peeked SLE.
bool dirDelete(Keylet const &directory, std::function< void(uint256 const &)> const &)
Remove the specified directory, invoking the callback for every node.
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
virtual void update(SLE::ref sle)=0
Indicate changes to a peeked SLE.
virtual Rules const & rules() const =0
Returns the tx processing rules.
bool enabled(uint256 const &feature) const
Returns true if a feature is enabled.
std::shared_ptr< STLedgerEntry > const & ref
std::shared_ptr< STLedgerEntry > pointer
std::vector< uint256 >::iterator insert(std::vector< uint256 >::const_iterator pos, uint256 const &value)
void pushBack(uint256 const &v)
std::vector< uint256 >::iterator end()
auto findPreviousPage(ApplyView &view, Keylet const &directory, SLE::ref start)
std::uint64_t insertKey(ApplyView &view, SLE::ref node, std::uint64_t page, bool preserveOrder, STVector256 &indexes, uint256 const &key)
std::optional< std::uint64_t > insertPage(ApplyView &view, std::uint64_t page, SLE::pointer node, std::uint64_t nextPage, SLE::ref next, uint256 const &key, Keylet const &directory, std::function< void(SLE::ref)> const &describe)
std::uint64_t createRoot(ApplyView &view, Keylet const &directory, uint256 const &key, std::function< void(SLE::ref)> const &describe)
Helper functions for managing low-level directory operations.
Keylet page(uint256 const &root, std::uint64_t index=0) noexcept
A page in a directory.
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
constexpr std::size_t kDirNodeMaxEntries
The maximum number of entries per directory page.
Number root(Number f, unsigned d)
constexpr std::uint64_t kDirNodeMaxPages
The maximum number of pages allowed in a directory.
XRPL_NO_SANITIZE_ADDRESS void Throw(Args &&... args)
A pair of SHAMap key and LedgerEntryType.