@@ -40,7 +40,7 @@ namespace NFwd {
40
40
return PageLoadingLogic.Get ();
41
41
}
42
42
43
- ui64 AddToQueue (TPageId pageId, ui16 type) noexcept override
43
+ ui64 AddToQueue (TPageId pageId, EPage type) noexcept override
44
44
{
45
45
if (!Fetch) {
46
46
Fetch.Reset (new TFetch (Cookie, PageCollection, { }));
@@ -49,7 +49,7 @@ namespace NFwd {
49
49
50
50
const auto meta = PageCollection->Page (pageId);
51
51
52
- if (meta.Type != type || meta.Size == 0 )
52
+ if (meta.Type != ui16 ( type) || meta.Size == 0 )
53
53
Y_FAIL (" Got a non-data page while part index traverse" );
54
54
55
55
Fetch->Pages .emplace_back (pageId);
@@ -75,9 +75,11 @@ namespace NFwd {
75
75
TIntrusiveConstPtr<IPageCollection> PageCollection;
76
76
};
77
77
78
- public:
79
- using TData = const TSharedData*;
78
+ struct TSimpleEnv {
79
+ TMap<TPageId, NPageCollection::TLoadedPage> Pages;
80
+ };
80
81
82
+ public:
81
83
TEnv (const TConf &conf, const TSubset &subset)
82
84
: Salt(RandomNumber<ui32>())
83
85
, Conf(conf)
@@ -106,10 +108,16 @@ namespace NFwd {
106
108
return Pending == 0 ;
107
109
}
108
110
109
- TData TryGetPage (const TPart* part, TPageId ref, TGroupId groupId) override
111
+ const TSharedData* TryGetPage (const TPart* part, TPageId ref, TGroupId groupId) override
110
112
{
111
113
ui16 room = (groupId.Historic ? part->Groups + 2 : 0 ) + groupId.Index ;
112
- return Handle (GetQueue (part, room), ref).Page ;
114
+ TSlot slot = GetQueueSlot (part, room);
115
+
116
+ if (part->IndexPages .Has (groupId, ref)) {
117
+ return TryGetIndexPage (slot, ref);
118
+ }
119
+
120
+ return Handle (Queues.at (slot), ref).Page ;
113
121
}
114
122
115
123
TResult Locate (const TMemTable *memTable, ui64 ref, ui32 tag) noexcept override
@@ -150,7 +158,18 @@ namespace NFwd {
150
158
" Page fwd cache got more pages than was requested" );
151
159
152
160
Pending -= pages.size ();
153
- Queues.at (part)->Apply (pages);
161
+
162
+ TVector<NPageCollection::TLoadedPage> queuePages (Reserve (pages.size ()));
163
+ for (auto & page : pages) {
164
+ const auto &meta = pageCollection->Page (page.PageId );
165
+ if (NTable::EPage (meta.Type ) == EPage::Index) {
166
+ IndexPages.at (part).Pages [page.PageId ] = page;
167
+ } else {
168
+ queuePages.push_back (page);
169
+ }
170
+ }
171
+
172
+ Queues.at (part)->Apply (queuePages);
154
173
}
155
174
156
175
IPages* Reset () noexcept
@@ -168,6 +187,7 @@ namespace NFwd {
168
187
Total = Stats ();
169
188
Parts.clear ();
170
189
Queues.clear ();
190
+ IndexPages.clear ();
171
191
ColdParts.clear ();
172
192
173
193
for (auto &one : Subset.Flatten )
@@ -239,6 +259,23 @@ namespace NFwd {
239
259
}
240
260
241
261
private:
262
+ const TSharedData* TryGetIndexPage (TSlot slot, TPageId pageId) noexcept
263
+ {
264
+ // TODO: count index pages in Stats later
265
+
266
+ auto &env = IndexPages.at (slot);
267
+ auto pageIt = env.Pages .find (pageId);
268
+
269
+ if (pageIt != env.Pages .end ()) {
270
+ return &pageIt->second .Data ;
271
+ } else {
272
+ auto &queue = Queues.at (slot);
273
+ queue.AddToQueue (pageId, EPage::Index);
274
+ Queue.PushBack (&queue);
275
+ return nullptr ;
276
+ }
277
+ }
278
+
242
279
TResult Handle (TPageLoadingQueue &q, TPageId ref) noexcept
243
280
{
244
281
auto got = q->Handle (&q, ref, Conf.AheadLo );
@@ -277,7 +314,7 @@ namespace NFwd {
277
314
" Cannot handle multiple parts on the same page collection" );
278
315
}
279
316
280
- TPageLoadingQueue& GetQueue (const TPart *part, ui16 room) noexcept
317
+ TSlot GetQueueSlot (const TPart *part, ui16 room) noexcept
281
318
{
282
319
auto it = Parts.find (part);
283
320
Y_VERIFY (it != Parts.end (),
@@ -289,7 +326,12 @@ namespace NFwd {
289
326
Y_VERIFY (Queues.at (it->second [0 ]).PageCollection ->Label () == part->Label ,
290
327
" Cannot handle multiple parts on the same page collection" );
291
328
292
- return Queues.at (it->second [room]);
329
+ return it->second [room];
330
+ }
331
+
332
+ TPageLoadingQueue& GetQueue (const TPart *part, ui16 room) noexcept
333
+ {
334
+ return Queues.at (GetQueueSlot (part, room));
293
335
}
294
336
295
337
TSlot Settle (TEgg egg, ui32 slot) noexcept
@@ -298,6 +340,7 @@ namespace NFwd {
298
340
const ui64 cookie = (ui64 (Queues.size ()) << 32 ) | ui32 (Salt + Epoch);
299
341
300
342
Queues.emplace_back (slot, cookie, std::move (egg.PageCollection ), egg.PageLoadingLogic );
343
+ IndexPages.emplace_back ();
301
344
302
345
return Queues.size () - 1 ;
303
346
} else {
@@ -373,6 +416,7 @@ namespace NFwd {
373
416
const TVector<ui32> Keys; /* Tags to expand ELargeObj references */
374
417
375
418
TDeque<TPageLoadingQueue> Queues;
419
+ TDeque<TSimpleEnv> IndexPages;
376
420
THashMap<const TPart*, TSlotVec> Parts;
377
421
THashSet<const TPart*> ColdParts;
378
422
// Wrapper for memable blobs
0 commit comments