88
99namespace ripple {
1010
11+ namespace directory {
12+
1113struct Gap
1214{
1315 uint64_t const page;
@@ -16,130 +18,142 @@ struct Gap
1618 SLE::pointer next;
1719};
1820
19- std::optional<std:: uint64_t >
20- ApplyView::dirAdd (
21- bool preserveOrder ,
21+ std::uint64_t
22+ createRoot (
23+ ApplyView& view ,
2224 Keylet const & directory,
2325 uint256 const & key,
2426 std::function<void (std::shared_ptr<SLE> const &)> const & describe)
2527{
26- auto createRoot =
27- [this ](
28- Keylet const & directory,
29- uint256 const & key,
30- std::function<void (std::shared_ptr<SLE> const &)> const & describe) {
31- auto newRoot = std::make_shared<SLE>(directory);
32- newRoot->setFieldH256 (sfRootIndex, directory.key );
33- describe (newRoot);
28+ auto newRoot = std::make_shared<SLE>(directory);
29+ newRoot->setFieldH256 (sfRootIndex, directory.key );
30+ describe (newRoot);
3431
35- STVector256 v;
36- v.push_back (key);
37- newRoot->setFieldV256 (sfIndexes, v);
32+ STVector256 v;
33+ v.push_back (key);
34+ newRoot->setFieldV256 (sfIndexes, v);
3835
39- insert (newRoot);
40- return std::uint64_t {0 };
41- };
36+ view. insert (newRoot);
37+ return std::uint64_t {0 };
38+ }
4239
43- auto findPreviousPage = [this ](Keylet const & directory, SLE::ref start) {
44- std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
40+ auto
41+ findPreviousPage (ApplyView& view, Keylet const & directory, SLE::ref start)
42+ {
43+ std::uint64_t page = start->getFieldU64 (sfIndexPrevious);
4544
46- auto node = start;
45+ auto node = start;
4746
48- if (page)
49- {
50- node = peek (keylet::page (directory, page));
51- if (!node)
52- LogicError (" Directory chain: root back-pointer broken." );
53- }
47+ if (page)
48+ {
49+ node = view. peek (keylet::page (directory, page));
50+ if (!node)
51+ LogicError (" Directory chain: root back-pointer broken." );
52+ }
5453
55- auto indexes = node->getFieldV256 (sfIndexes);
56- return std::make_tuple (page, node, indexes);
57- };
58- auto insertKey = [this ](
59- SLE::ref node,
60- std::uint64_t page,
61- bool preserveOrder,
62- STVector256& indexes,
63- uint256 const & key) {
64- if (preserveOrder)
65- {
66- if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
67- LogicError (" dirInsert: double insertion" );
54+ auto indexes = node->getFieldV256 (sfIndexes);
55+ return std::make_tuple (page, node, indexes);
56+ }
6857
69- indexes.push_back (key);
70- }
71- else
72- {
73- // We can't be sure if this page is already sorted because
74- // it may be a legacy page we haven't yet touched. Take
75- // the time to sort it.
76- std::sort (indexes.begin (), indexes.end ());
58+ std::uint64_t
59+ insertKey (
60+ ApplyView& view,
61+ SLE::ref node,
62+ std::uint64_t page,
63+ bool preserveOrder,
64+ STVector256& indexes,
65+ uint256 const & key)
66+ {
67+ if (preserveOrder)
68+ {
69+ if (std::find (indexes.begin (), indexes.end (), key) != indexes.end ())
70+ LogicError (" dirInsert: double insertion" );
7771
78- auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
72+ indexes.push_back (key);
73+ }
74+ else
75+ {
76+ // We can't be sure if this page is already sorted because
77+ // it may be a legacy page we haven't yet touched. Take
78+ // the time to sort it.
79+ std::sort (indexes.begin (), indexes.end ());
7980
80- if (pos != indexes.end () && key == *pos)
81- LogicError (" dirInsert: double insertion" );
81+ auto pos = std::lower_bound (indexes.begin (), indexes.end (), key);
8282
83- indexes.insert (pos, key);
84- }
83+ if (pos != indexes.end () && key == *pos)
84+ LogicError ( " dirInsert: double insertion " );
8585
86- node->setFieldV256 (sfIndexes, indexes);
87- update (node);
88- return page;
89- };
90- auto insertPage =
91- [this ](
92- std::uint64_t page,
93- SLE::pointer node,
94- std::uint64_t nextPage,
95- SLE::ref next,
96- uint256 const & key,
97- STVector256& indexes,
98- Keylet const & directory,
99- std::function<void (std::shared_ptr<SLE> const &)> const & describe)
100- -> std::optional<std::uint64_t > {
101- // Check whether we're out of pages.
102- if (++page >= dirNodeMaxPages)
103- {
104- return std::nullopt ;
105- }
86+ indexes.insert (pos, key);
87+ }
10688
107- // We are about to create a new node; we'll link it to
108- // the chain first:
109- node-> setFieldU64 (sfIndexNext, page) ;
110- update (node);
89+ node-> setFieldV256 (sfIndexes, indexes);
90+ view. update (node);
91+ return page;
92+ }
11193
112- next->setFieldU64 (sfIndexPrevious, page);
113- update (next);
94+ std::optional<std::uint64_t >
95+ insertPage (
96+ ApplyView& view,
97+ std::uint64_t page,
98+ SLE::pointer node,
99+ std::uint64_t nextPage,
100+ SLE::ref next,
101+ uint256 const & key,
102+ Keylet const & directory,
103+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
104+ {
105+ // Check whether we're out of pages.
106+ if (++page >= dirNodeMaxPages)
107+ {
108+ return std::nullopt ;
109+ }
114110
115- // Insert the new key:
116- indexes.clear ();
117- indexes.push_back (key);
111+ // We are about to create a new node; we'll link it to
112+ // the chain first:
113+ node->setFieldU64 (sfIndexNext, page);
114+ view.update (node);
118115
119- node = std::make_shared<SLE>(keylet::page (directory, page));
120- node->setFieldH256 (sfRootIndex, directory.key );
121- node->setFieldV256 (sfIndexes, indexes);
116+ next->setFieldU64 (sfIndexPrevious, page);
117+ view.update (next);
122118
123- // Save some space by not specifying the value 0 since
124- // it's the default.
125- if (page != 1 )
126- node->setFieldU64 (sfIndexPrevious, page - 1 );
127- if (nextPage)
128- node->setFieldU64 (sfIndexNext, nextPage);
129- describe (node);
130- insert (node);
119+ // Insert the new key:
120+ STVector256 indexes;
121+ indexes.push_back (key);
131122
132- return page;
133- };
123+ node = std::make_shared<SLE>(keylet::page (directory, page));
124+ node->setFieldH256 (sfRootIndex, directory.key );
125+ node->setFieldV256 (sfIndexes, indexes);
134126
127+ // Save some space by not specifying the value 0 since
128+ // it's the default.
129+ if (page != 1 )
130+ node->setFieldU64 (sfIndexPrevious, page - 1 );
131+ if (nextPage)
132+ node->setFieldU64 (sfIndexNext, nextPage);
133+ describe (node);
134+ view.insert (node);
135+
136+ return page;
137+ }
138+
139+ } // namespace directory
140+
141+ std::optional<std::uint64_t >
142+ ApplyView::dirAdd (
143+ bool preserveOrder,
144+ Keylet const & directory,
145+ uint256 const & key,
146+ std::function<void (std::shared_ptr<SLE> const &)> const & describe)
147+ {
135148 auto const root = peek (directory);
136149
137150 if (!root)
138151 {
139152 // No root, make it.
140- return createRoot (directory, key, describe);
153+ return directory:: createRoot (* this , directory, key, describe);
141154 }
142155
156+ // --Conflict start
143157 // We rely on modulo arithmetic of unsigned integers (guaranteed in
144158 // [basic.fundamental] paragraph 2) to detect page representation overflow.
145159 // For signed integers this would be UB, hence static_assert here.
@@ -157,19 +171,25 @@ ApplyView::dirAdd(
157171 page >= dirNodeMaxPages) // Old pages limit
158172 return std::nullopt ;
159173
160- auto [page, node, indexes] = findPreviousPage (directory, root);
174+ // The block above and below this comment conflicted, and I don't
175+ // fee like resolving it right now, so I'm saving it for later.
176+ // Because page is defined twice, it won't build.
177+
178+ auto [page, node, indexes] =
179+ directory::findPreviousPage (*this , directory, root);
180+ // --Conflict end
161181
162182 if (rules ().enabled (featureDefragDirectories))
163183 {
164184 // If there are more nodes than just the root, and there's no space in
165185 // the last one, walk backwards to find one with space, or to find one
166186 // missing.
167- std::optional<Gap> gapPages;
187+ std::optional<directory:: Gap> gapPages;
168188 while (page && indexes.size () >= dirNodeMaxEntries)
169189 {
170190 // Find a page with space, or a gap in pages.
171191 auto [prevPage, prevNode, prevIndexes] =
172- findPreviousPage (directory, node);
192+ directory:: findPreviousPage (* this , directory, node);
173193 if (!gapPages && prevPage != page - 1 )
174194 gapPages.emplace (prevPage, prevNode, page, node);
175195 page = prevPage;
@@ -182,27 +202,30 @@ ApplyView::dirAdd(
182202 // If we found a gap, use it.
183203 if (gapPages)
184204 {
185- return insertPage (
205+ return directory::insertPage (
206+ *this ,
186207 gapPages->page ,
187208 gapPages->node ,
188209 gapPages->nextPage ,
189- gapPages->node ,
210+ gapPages->next ,
190211 key,
191- indexes,
192212 directory,
193213 describe);
194214 }
195- std::tie (page, node, indexes) = findPreviousPage (directory, root);
215+ std::tie (page, node, indexes) =
216+ directory::findPreviousPage (*this , directory, root);
196217 }
197218 }
198219
199220 // If there's space, we use it:
200221 if (indexes.size () < dirNodeMaxEntries)
201222 {
202- return insertKey (node, page, preserveOrder, indexes, key);
223+ return directory::insertKey (
224+ *this , node, page, preserveOrder, indexes, key);
203225 }
204226
205- return insertPage (page, node, 0 , root, key, indexes, directory, describe);
227+ return directory::insertPage (
228+ *this , page, node, 0 , root, key, directory, describe);
206229}
207230
208231bool
0 commit comments