2525
2626namespace ripple {
2727
28- std::optional<std::uint64_t >
29- ApplyView::dirAdd (
30- bool preserveOrder,
28+ namespace directory {
29+
30+ std::uint64_t
31+ createRoot (
32+ ApplyView& view,
3133 Keylet const & directory,
3234 uint256 const & key,
3335 std::function<void (std::shared_ptr<SLE> const &)> const & describe)
3436{
35- auto root = peek (directory);
36-
37- if (!root)
38- {
39- // No root, make it.
40- root = std::make_shared<SLE>(directory);
41- root->setFieldH256 (sfRootIndex, directory.key );
42- describe (root);
37+ auto newRoot = std::make_shared<SLE>(directory);
38+ newRoot->setFieldH256 (sfRootIndex, directory.key );
39+ describe (newRoot);
4340
44- STVector256 v;
45- v.push_back (key);
46- root ->setFieldV256 (sfIndexes, v);
41+ STVector256 v;
42+ v.push_back (key);
43+ newRoot ->setFieldV256 (sfIndexes, v);
4744
48- insert (root );
49- return std::uint64_t {0 };
50- }
45+ view. insert (newRoot );
46+ return std::uint64_t {0 };
47+ }
5148
52- std::uint64_t page = root->getFieldU64 (sfIndexPrevious);
49+ auto
50+ findPreviousPage (ApplyView& view, Keylet const & directory, SLE::ref start)
51+ {
52+ std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
5353
54- auto node = root ;
54+ auto node = start ;
5555
5656 if (page)
5757 {
58- node = peek (keylet::page (directory, page));
58+ node = view. peek (keylet::page (directory, page));
5959 if (!node)
6060 LogicError (" Directory chain: root back-pointer broken." );
6161 }
6262
6363 auto indexes = node->getFieldV256 (sfIndexes);
64+ return std::make_tuple (page, node, indexes);
65+ }
6466
65- // If there's space, we use it:
66- if (indexes.size () < dirNodeMaxEntries)
67+ std::uint64_t
68+ insertKey (
69+ ApplyView& view,
70+ SLE::ref node,
71+ std::uint64_t page,
72+ bool preserveOrder,
73+ STVector256& indexes,
74+ uint256 const & key)
75+ {
76+ if (preserveOrder)
6777 {
68- if (preserveOrder)
69- {
70- if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
71- LogicError (" dirInsert: double insertion" );
78+ if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
79+ LogicError (" dirInsert: double insertion" );
7280
73- indexes.push_back (key);
74- }
75- else
76- {
77- // We can't be sure if this page is already sorted because
78- // it may be a legacy page we haven't yet touched. Take
79- // the time to sort it.
80- std::sort (indexes.begin (), indexes.end ());
81+ indexes.push_back (key);
82+ }
83+ else
84+ {
85+ // We can't be sure if this page is already sorted because
86+ // it may be a legacy page we haven't yet touched. Take
87+ // the time to sort it.
88+ std::sort (indexes.begin (), indexes.end ());
8189
82- auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
90+ auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
8391
84- if (pos != indexes.end () && key == *pos)
85- LogicError (" dirInsert: double insertion" );
92+ if (pos != indexes.end () && key == *pos)
93+ LogicError (" dirInsert: double insertion" );
8694
87- indexes.insert (pos, key);
88- }
89-
90- node->setFieldV256 (sfIndexes, indexes);
91- update (node);
92- return page;
95+ indexes.insert (pos, key);
9396 }
9497
98+ node->setFieldV256 (sfIndexes, indexes);
99+ view.update (node);
100+ return page;
101+ }
102+
103+ std::optional<std::uint64_t >
104+ insertPage (
105+ ApplyView& view,
106+ std::uint64_t page,
107+ SLE::pointer node,
108+ std::uint64_t nextPage,
109+ SLE::ref next,
110+ uint256 const & key,
111+ Keylet const & directory,
112+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
113+ {
95114 // Check whether we're out of pages.
96115 if (++page >= dirNodeMaxPages)
116+ {
97117 return std::nullopt ;
118+ }
98119
99120 // We are about to create a new node; we'll link it to
100121 // the chain first:
101122 node->setFieldU64 (sfIndexNext, page);
102- update (node);
123+ view. update (node);
103124
104- root ->setFieldU64 (sfIndexPrevious, page);
105- update (root );
125+ next ->setFieldU64 (sfIndexPrevious, page);
126+ view. update (next );
106127
107128 // Insert the new key:
108- indexes. clear () ;
129+ STVector256 indexes;
109130 indexes.push_back (key);
110131
111132 node = std::make_shared<SLE>(keylet::page (directory, page));
@@ -116,12 +137,45 @@ ApplyView::dirAdd(
116137 // it's the default.
117138 if (page != 1 )
118139 node->setFieldU64 (sfIndexPrevious, page - 1 );
140+ if (nextPage)
141+ node->setFieldU64 (sfIndexNext, nextPage);
119142 describe (node);
120- insert (node);
143+ view. insert (node);
121144
122145 return page;
123146}
124147
148+ } // namespace directory
149+
150+ std::optional<std::uint64_t >
151+ ApplyView::dirAdd (
152+ bool preserveOrder,
153+ Keylet const & directory,
154+ uint256 const & key,
155+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
156+ {
157+ auto root = peek (directory);
158+
159+ if (!root)
160+ {
161+ // No root, make it.
162+ return directory::createRoot (*this , directory, key, describe);
163+ }
164+
165+ auto [page, node, indexes] =
166+ directory::findPreviousPage (*this , directory, root);
167+
168+ // If there's space, we use it:
169+ if (indexes.size () < dirNodeMaxEntries)
170+ {
171+ return directory::insertKey (
172+ *this , node, page, preserveOrder, indexes, key);
173+ }
174+
175+ return directory::insertPage (
176+ *this , page, node, 0 , root, key, directory, describe);
177+ }
178+
125179bool
126180ApplyView::emptyDirDelete (Keylet const & directory)
127181{
0 commit comments