2424
2525namespace ripple {
2626
27+ namespace directory {
28+
2729struct Gap
2830{
2931 uint64_t const page;
@@ -32,143 +34,155 @@ struct Gap
3234 SLE::pointer next;
3335};
3436
35- std::optional<std:: uint64_t >
36- ApplyView::dirAdd (
37- bool preserveOrder ,
37+ std::uint64_t
38+ createRoot (
39+ ApplyView& view ,
3840 Keylet const & directory,
3941 uint256 const & key,
4042 std::function<void (std::shared_ptr<SLE> const &)> const & describe)
4143{
42- auto createRoot =
43- [this ](
44- Keylet const & directory,
45- uint256 const & key,
46- std::function<void (std::shared_ptr<SLE> const &)> const & describe) {
47- auto newRoot = std::make_shared<SLE>(directory);
48- newRoot->setFieldH256 (sfRootIndex, directory.key );
49- describe (newRoot);
44+ auto newRoot = std::make_shared<SLE>(directory);
45+ newRoot->setFieldH256 (sfRootIndex, directory.key );
46+ describe (newRoot);
5047
51- STVector256 v;
52- v.push_back (key);
53- newRoot->setFieldV256 (sfIndexes, v);
48+ STVector256 v;
49+ v.push_back (key);
50+ newRoot->setFieldV256 (sfIndexes, v);
5451
55- insert (newRoot);
56- return std::uint64_t {0 };
57- };
52+ view. insert (newRoot);
53+ return std::uint64_t {0 };
54+ }
5855
59- auto findPreviousPage = [this ](Keylet const & directory, SLE::ref start) {
60- std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
56+ auto
57+ findPreviousPage (ApplyView& view, Keylet const & directory, SLE::ref start)
58+ {
59+ std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
6160
62- auto node = start;
61+ auto node = start;
6362
64- if (page)
65- {
66- node = peek (keylet::page (directory, page));
67- if (!node)
68- LogicError (" Directory chain: root back-pointer broken." );
69- }
63+ if (page)
64+ {
65+ node = view. peek (keylet::page (directory, page));
66+ if (!node)
67+ LogicError (" Directory chain: root back-pointer broken." );
68+ }
7069
71- auto indexes = node->getFieldV256 (sfIndexes);
72- return std::make_tuple (page, node, indexes);
73- };
74- auto insertKey = [this ](
75- SLE::ref node,
76- std::uint64_t page,
77- bool preserveOrder,
78- STVector256& indexes,
79- uint256 const & key) {
80- if (preserveOrder)
81- {
82- if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
83- LogicError (" dirInsert: double insertion" );
70+ auto indexes = node->getFieldV256 (sfIndexes);
71+ return std::make_tuple (page, node, indexes);
72+ }
8473
85- indexes.push_back (key);
86- }
87- else
88- {
89- // We can't be sure if this page is already sorted because
90- // it may be a legacy page we haven't yet touched. Take
91- // the time to sort it.
92- std::sort (indexes.begin (), indexes.end ());
74+ std::uint64_t
75+ insertKey (
76+ ApplyView& view,
77+ SLE::ref node,
78+ std::uint64_t page,
79+ bool preserveOrder,
80+ STVector256& indexes,
81+ uint256 const & key)
82+ {
83+ if (preserveOrder)
84+ {
85+ if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
86+ LogicError (" dirInsert: double insertion" );
9387
94- auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
88+ indexes.push_back (key);
89+ }
90+ else
91+ {
92+ // We can't be sure if this page is already sorted because
93+ // it may be a legacy page we haven't yet touched. Take
94+ // the time to sort it.
95+ std::sort (indexes.begin (), indexes.end ());
9596
96- if (pos != indexes.end () && key == *pos)
97- LogicError (" dirInsert: double insertion" );
97+ auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
9898
99- indexes.insert (pos, key);
100- }
99+ if (pos != indexes.end () && key == *pos)
100+ LogicError ( " dirInsert: double insertion " );
101101
102- node->setFieldV256 (sfIndexes, indexes);
103- update (node);
104- return page;
105- };
106- auto insertPage =
107- [this ](
108- std::uint64_t page,
109- SLE::pointer node,
110- std::uint64_t nextPage,
111- SLE::ref next,
112- uint256 const & key,
113- STVector256& indexes,
114- Keylet const & directory,
115- std::function<void (std::shared_ptr<SLE> const &)> const & describe)
116- -> std::optional<std::uint64_t > {
117- // Check whether we're out of pages.
118- if (++page >= dirNodeMaxPages)
119- {
120- return std::nullopt ;
121- }
102+ indexes.insert (pos, key);
103+ }
122104
123- // We are about to create a new node; we'll link it to
124- // the chain first:
125- node-> setFieldU64 (sfIndexNext, page) ;
126- update (node);
105+ node-> setFieldV256 (sfIndexes, indexes);
106+ view. update (node);
107+ return page;
108+ }
127109
128- next->setFieldU64 (sfIndexPrevious, page);
129- update (next);
110+ std::optional<std::uint64_t >
111+ insertPage (
112+ ApplyView& view,
113+ std::uint64_t page,
114+ SLE::pointer node,
115+ std::uint64_t nextPage,
116+ SLE::ref next,
117+ uint256 const & key,
118+ Keylet const & directory,
119+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
120+ {
121+ // Check whether we're out of pages.
122+ if (++page >= dirNodeMaxPages)
123+ {
124+ return std::nullopt ;
125+ }
130126
131- // Insert the new key:
132- indexes.clear ();
133- indexes.push_back (key);
127+ // We are about to create a new node; we'll link it to
128+ // the chain first:
129+ node->setFieldU64 (sfIndexNext, page);
130+ view.update (node);
134131
135- node = std::make_shared<SLE>(keylet::page (directory, page));
136- node->setFieldH256 (sfRootIndex, directory.key );
137- node->setFieldV256 (sfIndexes, indexes);
132+ next->setFieldU64 (sfIndexPrevious, page);
133+ view.update (next);
138134
139- // Save some space by not specifying the value 0 since
140- // it's the default.
141- if (page != 1 )
142- node->setFieldU64 (sfIndexPrevious, page - 1 );
143- if (nextPage)
144- node->setFieldU64 (sfIndexNext, nextPage);
145- describe (node);
146- insert (node);
135+ // Insert the new key:
136+ STVector256 indexes;
137+ indexes.push_back (key);
147138
148- return page;
149- };
139+ node = std::make_shared<SLE>(keylet::page (directory, page));
140+ node->setFieldH256 (sfRootIndex, directory.key );
141+ node->setFieldV256 (sfIndexes, indexes);
150142
143+ // Save some space by not specifying the value 0 since
144+ // it's the default.
145+ if (page != 1 )
146+ node->setFieldU64 (sfIndexPrevious, page - 1 );
147+ if (nextPage)
148+ node->setFieldU64 (sfIndexNext, nextPage);
149+ describe (node);
150+ view.insert (node);
151+
152+ return page;
153+ }
154+
155+ } // namespace directory
156+
157+ std::optional<std::uint64_t >
158+ ApplyView::dirAdd (
159+ bool preserveOrder,
160+ Keylet const & directory,
161+ uint256 const & key,
162+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
163+ {
151164 auto const root = peek (directory);
152165
153166 if (!root)
154167 {
155168 // No root, make it.
156- return createRoot (directory, key, describe);
169+ return directory:: createRoot (* this , directory, key, describe);
157170 }
158171
159- auto [page, node, indexes] = findPreviousPage (directory, root);
172+ auto [page, node, indexes] =
173+ directory::findPreviousPage (*this , directory, root);
160174
161175 if (rules ().enabled (featureDefragDirectories))
162176 {
163177 // If there are more nodes than just the root, and there's no space in
164178 // the last one, walk backwards to find one with space, or to find one
165179 // missing.
166- std::optional<Gap> gapPages;
180+ std::optional<directory:: Gap> gapPages;
167181 while (page && indexes.size () >= dirNodeMaxEntries)
168182 {
169183 // Find a page with space, or a gap in pages.
170184 auto [prevPage, prevNode, prevIndexes] =
171- findPreviousPage (directory, node);
185+ directory:: findPreviousPage (* this , directory, node);
172186 if (!gapPages && prevPage != page - 1 )
173187 gapPages.emplace (prevPage, prevNode, page, node);
174188 page = prevPage;
@@ -181,27 +195,30 @@ ApplyView::dirAdd(
181195 // If we found a gap, use it.
182196 if (gapPages)
183197 {
184- return insertPage (
198+ return directory::insertPage (
199+ *this ,
185200 gapPages->page ,
186201 gapPages->node ,
187202 gapPages->nextPage ,
188- gapPages->node ,
203+ gapPages->next ,
189204 key,
190- indexes,
191205 directory,
192206 describe);
193207 }
194- std::tie (page, node, indexes) = findPreviousPage (directory, root);
208+ std::tie (page, node, indexes) =
209+ directory::findPreviousPage (*this , directory, root);
195210 }
196211 }
197212
198213 // If there's space, we use it:
199214 if (indexes.size () < dirNodeMaxEntries)
200215 {
201- return insertKey (node, page, preserveOrder, indexes, key);
216+ return directory::insertKey (
217+ *this , node, page, preserveOrder, indexes, key);
202218 }
203219
204- return insertPage (page, node, 0 , root, key, indexes, directory, describe);
220+ return directory::insertPage (
221+ *this , page, node, 0 , root, key, directory, describe);
205222}
206223
207224bool
0 commit comments