1#include <xrpl/basics/contract.h>
2#include <xrpl/beast/utility/instrumentation.h>
3#include <xrpl/ledger/ApplyView.h>
4#include <xrpl/protocol/Protocol.h>
21 newRoot->setFieldH256(sfRootIndex, directory.
key);
26 newRoot->setFieldV256(sfIndexes, v);
44 LogicError(
"Directory chain: root back-pointer broken.");
49 auto indexes = node->getFieldV256(sfIndexes);
78 if (pos != indexes.
end() && key == *pos)
84 node->setFieldV256(sfIndexes, indexes);
118 node->setFieldU64(sfIndexNext, page);
121 next->setFieldU64(sfIndexPrevious, page);
129 node->setFieldH256(sfRootIndex, directory.
key);
130 node->setFieldV256(sfIndexes, indexes);
135 node->setFieldU64(sfIndexPrevious, page - 1);
136 XRPL_ASSERT_PARTS(!nextPage,
"xrpl::directory::insertPage",
"nextPage has default value");
179 auto node =
peek(directory);
185 if (directory.
type != ltDIR_NODE || node->getFieldH256(sfRootIndex) != directory.
key)
188 UNREACHABLE(
"xrpl::ApplyView::emptyDirDelete : invalid node type");
194 if (!node->getFieldV256(sfIndexes).empty())
198 auto prevPage = node->getFieldU64(sfIndexPrevious);
199 auto nextPage = node->getFieldU64(sfIndexNext);
201 if (nextPage == rootPage && prevPage != rootPage)
202 LogicError(
"Directory chain: fwd link broken");
204 if (prevPage == rootPage && nextPage != rootPage)
205 LogicError(
"Directory chain: rev link broken");
209 if (nextPage == prevPage && nextPage != rootPage)
215 LogicError(
"Directory chain: fwd link broken.");
219 if (!last->getFieldV256(sfIndexes).empty())
224 node->setFieldU64(sfIndexNext, rootPage);
225 node->setFieldU64(sfIndexPrevious, rootPage);
238 if (nextPage == rootPage && prevPage == rootPage)
255 auto entries = node->getFieldV256(sfIndexes);
257 auto it =
std::find(entries.begin(), entries.end(), key);
259 if (entries.end() == it)
265 node->setFieldV256(sfIndexes, entries);
268 if (!entries.empty())
275 auto prevPage = node->getFieldU64(sfIndexPrevious);
276 auto nextPage = node->getFieldU64(sfIndexNext);
282 if (page == rootPage)
284 if (nextPage == page && prevPage != page)
286 LogicError(
"Directory chain: fwd link broken");
290 if (prevPage == page && nextPage != page)
292 LogicError(
"Directory chain: rev link broken");
299 if (nextPage == prevPage && nextPage != page)
304 LogicError(
"Directory chain: fwd link broken.");
308 if (last->getFieldV256(sfIndexes).empty())
312 node->setFieldU64(sfIndexNext, page);
313 node->setFieldU64(sfIndexPrevious, page);
330 if (nextPage == page && prevPage == page)
337 if (nextPage == page)
338 LogicError(
"Directory chain: fwd link broken");
340 if (prevPage == page)
341 LogicError(
"Directory chain: rev link broken");
349 LogicError(
"Directory chain: fwd link broken.");
351 prev->setFieldU64(sfIndexNext, nextPage);
356 LogicError(
"Directory chain: rev link broken.");
358 next->setFieldU64(sfIndexPrevious, prevPage);
366 if (nextPage != rootPage && next->getFieldU64(sfIndexNext) == rootPage && next->getFieldV256(sfIndexes).empty())
373 prev->setFieldU64(sfIndexNext, rootPage);
380 LogicError(
"Directory chain: root link broken.");
383 root->setFieldU64(sfIndexPrevious, prevPage);
391 if (!keepRoot && nextPage == rootPage && prevPage == rootPage)
393 if (prev->getFieldV256(sfIndexes).empty())
412 for (
auto const& item : page->getFieldV256(sfIndexes))
415 pi = (*page)[~sfIndexNext];
Writeable view to a ledger, for applying a transaction.
virtual void update(std::shared_ptr< SLE > const &sle)=0
Indicate changes to a peeked SLE.
bool dirRemove(Keylet const &directory, std::uint64_t page, uint256 const &key, bool keepRoot)
Remove an entry from a directory.
virtual void erase(std::shared_ptr< SLE > const &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.
virtual void insert(std::shared_ptr< SLE > const &sle)=0
Insert a new state SLE.
bool emptyDirDelete(Keylet const &directory)
Remove the specified directory, if it is empty.
std::optional< std::uint64_t > dirAdd(bool preserveOrder, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> const &describe)
Add an entry to a directory using the specified insert strategy.
virtual std::shared_ptr< SLE > peek(Keylet const &k)=0
Prepare to modify the SLE associated with key.
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::vector< uint256 >::iterator insert(std::vector< uint256 >::const_iterator pos, uint256 const &value)
std::vector< uint256 >::iterator begin()
void push_back(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(std::shared_ptr< SLE > const &)> const &describe)
std::uint64_t createRoot(ApplyView &view, Keylet const &directory, uint256 const &key, std::function< void(std::shared_ptr< SLE > const &)> 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.
void LogicError(std::string const &how) noexcept
Called when faulty logic causes a broken invariant.
std::size_t constexpr dirNodeMaxEntries
The maximum number of entries per directory page.
Number root(Number f, unsigned d)
std::uint64_t constexpr dirNodeMaxPages
The maximum number of pages allowed in a directory.
A pair of SHAMap key and LedgerEntryType.