2525
2626namespace ripple {
2727
28+ namespace directory {
29+
2830struct Gap
2931{
3032 uint64_t const page;
@@ -33,143 +35,155 @@ struct Gap
3335 SLE::pointer next;
3436};
3537
36- std::optional<std:: uint64_t >
37- ApplyView::dirAdd (
38- bool preserveOrder ,
38+ std::uint64_t
39+ createRoot (
40+ ApplyView& view ,
3941 Keylet const & directory,
4042 uint256 const & key,
4143 std::function<void (std::shared_ptr<SLE> const &)> const & describe)
4244{
43- auto createRoot =
44- [this ](
45- Keylet const & directory,
46- uint256 const & key,
47- std::function<void (std::shared_ptr<SLE> const &)> const & describe) {
48- auto newRoot = std::make_shared<SLE>(directory);
49- newRoot->setFieldH256 (sfRootIndex, directory.key );
50- describe (newRoot);
45+ auto newRoot = std::make_shared<SLE>(directory);
46+ newRoot->setFieldH256 (sfRootIndex, directory.key );
47+ describe (newRoot);
5148
52- STVector256 v;
53- v.push_back (key);
54- newRoot->setFieldV256 (sfIndexes, v);
49+ STVector256 v;
50+ v.push_back (key);
51+ newRoot->setFieldV256 (sfIndexes, v);
5552
56- insert (newRoot);
57- return std::uint64_t {0 };
58- };
53+ view. insert (newRoot);
54+ return std::uint64_t {0 };
55+ }
5956
60- auto findPreviousPage = [this ](Keylet const & directory, SLE::ref start) {
61- std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
57+ auto
58+ findPreviousPage (ApplyView& view, Keylet const & directory, SLE::ref start)
59+ {
60+ std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
6261
63- auto node = start;
62+ auto node = start;
6463
65- if (page)
66- {
67- node = peek (keylet::page (directory, page));
68- if (!node)
69- LogicError (" Directory chain: root back-pointer broken." );
70- }
64+ if (page)
65+ {
66+ node = view. peek (keylet::page (directory, page));
67+ if (!node)
68+ LogicError (" Directory chain: root back-pointer broken." );
69+ }
7170
72- auto indexes = node->getFieldV256 (sfIndexes);
73- return std::make_tuple (page, node, indexes);
74- };
75- auto insertKey = [this ](
76- SLE::ref node,
77- std::uint64_t page,
78- bool preserveOrder,
79- STVector256& indexes,
80- uint256 const & key) {
81- if (preserveOrder)
82- {
83- if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
84- LogicError (" dirInsert: double insertion" );
71+ auto indexes = node->getFieldV256 (sfIndexes);
72+ return std::make_tuple (page, node, indexes);
73+ }
8574
86- indexes.push_back (key);
87- }
88- else
89- {
90- // We can't be sure if this page is already sorted because
91- // it may be a legacy page we haven't yet touched. Take
92- // the time to sort it.
93- std::sort (indexes.begin (), indexes.end ());
75+ std::uint64_t
76+ insertKey (
77+ ApplyView& view,
78+ SLE::ref node,
79+ std::uint64_t page,
80+ bool preserveOrder,
81+ STVector256& indexes,
82+ uint256 const & key)
83+ {
84+ if (preserveOrder)
85+ {
86+ if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
87+ LogicError (" dirInsert: double insertion" );
9488
95- auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
89+ indexes.push_back (key);
90+ }
91+ else
92+ {
93+ // We can't be sure if this page is already sorted because
94+ // it may be a legacy page we haven't yet touched. Take
95+ // the time to sort it.
96+ std::sort (indexes.begin (), indexes.end ());
9697
97- if (pos != indexes.end () && key == *pos)
98- LogicError (" dirInsert: double insertion" );
98+ auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
9999
100- indexes.insert (pos, key);
101- }
100+ if (pos != indexes.end () && key == *pos)
101+ LogicError ( " dirInsert: double insertion " );
102102
103- node->setFieldV256 (sfIndexes, indexes);
104- update (node);
105- return page;
106- };
107- auto insertPage =
108- [this ](
109- std::uint64_t page,
110- SLE::pointer node,
111- std::uint64_t nextPage,
112- SLE::ref next,
113- uint256 const & key,
114- STVector256& indexes,
115- Keylet const & directory,
116- std::function<void (std::shared_ptr<SLE> const &)> const & describe)
117- -> std::optional<std::uint64_t > {
118- // Check whether we're out of pages.
119- if (++page >= dirNodeMaxPages)
120- {
121- return std::nullopt ;
122- }
103+ indexes.insert (pos, key);
104+ }
123105
124- // We are about to create a new node; we'll link it to
125- // the chain first:
126- node-> setFieldU64 (sfIndexNext, page) ;
127- update (node);
106+ node-> setFieldV256 (sfIndexes, indexes);
107+ view. update (node);
108+ return page;
109+ }
128110
129- next->setFieldU64 (sfIndexPrevious, page);
130- update (next);
111+ std::optional<std::uint64_t >
112+ insertPage (
113+ ApplyView& view,
114+ std::uint64_t page,
115+ SLE::pointer node,
116+ std::uint64_t nextPage,
117+ SLE::ref next,
118+ uint256 const & key,
119+ Keylet const & directory,
120+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
121+ {
122+ // Check whether we're out of pages.
123+ if (++page >= dirNodeMaxPages)
124+ {
125+ return std::nullopt ;
126+ }
131127
132- // Insert the new key:
133- indexes.clear ();
134- indexes.push_back (key);
128+ // We are about to create a new node; we'll link it to
129+ // the chain first:
130+ node->setFieldU64 (sfIndexNext, page);
131+ view.update (node);
135132
136- node = std::make_shared<SLE>(keylet::page (directory, page));
137- node->setFieldH256 (sfRootIndex, directory.key );
138- node->setFieldV256 (sfIndexes, indexes);
133+ next->setFieldU64 (sfIndexPrevious, page);
134+ view.update (next);
139135
140- // Save some space by not specifying the value 0 since
141- // it's the default.
142- if (page != 1 )
143- node->setFieldU64 (sfIndexPrevious, page - 1 );
144- if (nextPage)
145- node->setFieldU64 (sfIndexNext, nextPage);
146- describe (node);
147- insert (node);
136+ // Insert the new key:
137+ STVector256 indexes;
138+ indexes.push_back (key);
148139
149- return page;
150- };
140+ node = std::make_shared<SLE>(keylet::page (directory, page));
141+ node->setFieldH256 (sfRootIndex, directory.key );
142+ node->setFieldV256 (sfIndexes, indexes);
151143
144+ // Save some space by not specifying the value 0 since
145+ // it's the default.
146+ if (page != 1 )
147+ node->setFieldU64 (sfIndexPrevious, page - 1 );
148+ if (nextPage)
149+ node->setFieldU64 (sfIndexNext, nextPage);
150+ describe (node);
151+ view.insert (node);
152+
153+ return page;
154+ }
155+
156+ } // namespace directory
157+
158+ std::optional<std::uint64_t >
159+ ApplyView::dirAdd (
160+ bool preserveOrder,
161+ Keylet const & directory,
162+ uint256 const & key,
163+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
164+ {
152165 auto const root = peek (directory);
153166
154167 if (!root)
155168 {
156169 // No root, make it.
157- return createRoot (directory, key, describe);
170+ return directory:: createRoot (* this , directory, key, describe);
158171 }
159172
160- auto [page, node, indexes] = findPreviousPage (directory, root);
173+ auto [page, node, indexes] =
174+ directory::findPreviousPage (*this , directory, root);
161175
162176 if (rules ().enabled (featureDefragDirectories))
163177 {
164178 // If there are more nodes than just the root, and there's no space in
165179 // the last one, walk backwards to find one with space, or to find one
166180 // missing.
167- std::optional<Gap> gapPages;
181+ std::optional<directory:: Gap> gapPages;
168182 while (page && indexes.size () >= dirNodeMaxEntries)
169183 {
170184 // Find a page with space, or a gap in pages.
171185 auto [prevPage, prevNode, prevIndexes] =
172- findPreviousPage (directory, node);
186+ directory:: findPreviousPage (* this , directory, node);
173187 if (!gapPages && prevPage != page - 1 )
174188 gapPages.emplace (prevPage, prevNode, page, node);
175189 page = prevPage;
@@ -182,27 +196,30 @@ ApplyView::dirAdd(
182196 // If we found a gap, use it.
183197 if (gapPages)
184198 {
185- return insertPage (
199+ return directory::insertPage (
200+ *this ,
186201 gapPages->page ,
187202 gapPages->node ,
188203 gapPages->nextPage ,
189- gapPages->node ,
204+ gapPages->next ,
190205 key,
191- indexes,
192206 directory,
193207 describe);
194208 }
195- std::tie (page, node, indexes) = findPreviousPage (directory, root);
209+ std::tie (page, node, indexes) =
210+ directory::findPreviousPage (*this , directory, root);
196211 }
197212 }
198213
199214 // If there's space, we use it:
200215 if (indexes.size () < dirNodeMaxEntries)
201216 {
202- return insertKey (node, page, preserveOrder, indexes, key);
217+ return directory::insertKey (
218+ *this , node, page, preserveOrder, indexes, key);
203219 }
204220
205- return insertPage (page, node, 0 , root, key, indexes, directory, describe);
221+ return directory::insertPage (
222+ *this , page, node, 0 , root, key, directory, describe);
206223}
207224
208225bool
0 commit comments