@@ -364,8 +364,13 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
364
364
enum class ETasteResult : i8 {
365
365
Init = -1 ,
366
366
Update,
367
- ConsumeRawData,
368
- ExtractRawData
367
+ ConsumeRawData
368
+ };
369
+
370
+ enum class EUpdateResult : i8 {
371
+ Yield = -1 ,
372
+ ExtractRawData,
373
+ None
369
374
};
370
375
TSpillingSupportState (
371
376
TMemoryUsageInfo* memInfo,
@@ -398,28 +403,28 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
398
403
bool IsProcessingRequired () const {
399
404
if (InputStatus != EFetchResult::Finish) return true ;
400
405
401
- return HasRawDataToExtract || HasDataForProcessing ;
406
+ return !SpilledBuckets. empty () && SpilledBuckets. front (). BucketState != TSpilledBucket::EBucketState::InMemory ;
402
407
}
403
408
404
- bool UpdateAndWait () {
409
+ EUpdateResult Update () {
405
410
switch (GetMode ()) {
406
411
case EOperatingMode::InMemory: {
407
412
if (CheckMemoryAndSwitchToSpilling ()) {
408
- return UpdateAndWait ();
413
+ return Update ();
409
414
}
410
- return false ;
415
+ return EUpdateResult::None ;
411
416
}
412
417
413
418
case EOperatingMode::ProcessSpilled:
414
419
return ProcessSpilledDataAndWait ();
415
420
case EOperatingMode::Spilling: {
416
421
UpdateSpillingBuckets ();
417
422
418
- if (!HasMemoryForProcessing () && InputStatus != EFetchResult::Finish && TryToReduceMemoryAndWait ()) return true ;
423
+ if (!HasMemoryForProcessing () && InputStatus != EFetchResult::Finish && TryToReduceMemoryAndWait ()) return EUpdateResult::Yield ;
419
424
420
425
if (BufferForUsedInputItems.size ()) {
421
426
auto & bucket = SpilledBuckets[BufferForUsedInputItemsBucketId];
422
- if (bucket.AsyncWriteOperation .has_value ()) return true ;
427
+ if (bucket.AsyncWriteOperation .has_value ()) return EUpdateResult::Yield ;
423
428
424
429
bucket.AsyncWriteOperation = bucket.SpilledData ->WriteWideItem (BufferForUsedInputItems);
425
430
BufferForUsedInputItems.resize (0 ); // for freeing allocated key value asap
@@ -429,7 +434,7 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
429
434
430
435
// Prepare buffer for reading new key
431
436
BufferForKeyAndState.resize (KeyWidth);
432
- return false ;
437
+ return EUpdateResult::None ;
433
438
}
434
439
}
435
440
}
@@ -442,14 +447,6 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
442
447
return isNew ? ETasteResult::Init : ETasteResult::Update;
443
448
}
444
449
if (GetMode () == EOperatingMode::ProcessSpilled) {
445
- if (HasRawDataToExtract) {
446
- // Tongue not used here.
447
- Throat = BufferForUsedInputItems.data ();
448
- HasRawDataToExtract = false ;
449
- HasDataForProcessing = true ;
450
- return ETasteResult::ExtractRawData;
451
- }
452
- HasDataForProcessing = false ;
453
450
// while restoration we process buckets one by one starting from the first in a queue
454
451
bool isNew = SpilledBuckets.front ().InMemoryProcessingState ->TasteIt ();
455
452
Throat = SpilledBuckets.front ().InMemoryProcessingState ->Throat ;
@@ -476,8 +473,11 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
476
473
MKQL_ENSURE (BufferForUsedInputItems.size () == 0 , " Internal logic error" );
477
474
BufferForUsedInputItems.resize (ItemNodesSize);
478
475
BufferForUsedInputItemsBucketId = bucketId;
476
+
479
477
Throat = BufferForUsedInputItems.data ();
480
-
478
+ Tongue = nullptr ;
479
+
480
+
481
481
return ETasteResult::ConsumeRawData;
482
482
}
483
483
@@ -503,7 +503,7 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
503
503
BufferForKeyAndState.resize (0 );
504
504
}
505
505
506
- bool FlushSpillingBuffersAndWait () {
506
+ EUpdateResult FlushSpillingBuffersAndWait () {
507
507
UpdateSpillingBuckets ();
508
508
509
509
ui64 finishedCount = 0 ;
@@ -519,7 +519,7 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
519
519
}
520
520
}
521
521
522
- if (finishedCount != SpilledBuckets.size ()) return true ;
522
+ if (finishedCount != SpilledBuckets.size ()) return EUpdateResult::Yield ;
523
523
524
524
SwitchMode (EOperatingMode::ProcessSpilled);
525
525
@@ -628,11 +628,11 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
628
628
return false ;
629
629
}
630
630
631
- bool ProcessSpilledDataAndWait () {
632
- if (SpilledBuckets.empty ()) return false ;
631
+ EUpdateResult ProcessSpilledDataAndWait () {
632
+ if (SpilledBuckets.empty ()) return EUpdateResult::None ;
633
633
634
634
if (AsyncReadOperation) {
635
- if (!AsyncReadOperation->HasValue ()) return true ;
635
+ if (!AsyncReadOperation->HasValue ()) return EUpdateResult::Yield ;
636
636
if (RecoverState) {
637
637
SpilledBuckets[0 ].SpilledState ->AsyncReadCompleted (AsyncReadOperation->ExtractValue ().value (), Ctx.HolderFactory );
638
638
} else {
@@ -642,20 +642,16 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
642
642
}
643
643
644
644
auto & bucket = SpilledBuckets.front ();
645
- if (bucket.BucketState == TSpilledBucket::EBucketState::InMemory) return false ;
646
- if (HasDataForProcessing) {
647
- Tongue = bucket.InMemoryProcessingState ->Tongue ;
648
- Throat = bucket.InMemoryProcessingState ->Throat ;
649
- return false ;
650
- }
645
+ if (bucket.BucketState == TSpilledBucket::EBucketState::InMemory) return EUpdateResult::None;
646
+
651
647
// recover spilled state
652
648
while (!bucket.SpilledState ->Empty ()) {
653
649
RecoverState = true ;
654
650
BufferForKeyAndState.resize (KeyAndStateType->GetElementsCount ());
655
651
AsyncReadOperation = bucket.SpilledState ->ExtractWideItem (BufferForKeyAndState);
656
652
if (AsyncReadOperation) {
657
653
BufferForKeyAndState.resize (0 );
658
- return true ;
654
+ return EUpdateResult::Yield ;
659
655
}
660
656
for (size_t i = 0 ; i< KeyWidth; ++i) {
661
657
// jumping into unsafe world, refusing ownership
@@ -675,18 +671,16 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
675
671
BufferForUsedInputItems.resize (UsedInputItemType->GetElementsCount ());
676
672
AsyncReadOperation = bucket.SpilledData ->ExtractWideItem (BufferForUsedInputItems);
677
673
if (AsyncReadOperation) {
678
- return true ;
674
+ return EUpdateResult::Yield ;
679
675
}
680
676
677
+ Throat = BufferForUsedInputItems.data ();
681
678
Tongue = bucket.InMemoryProcessingState ->Tongue ;
682
- Throat = bucket.InMemoryProcessingState ->Throat ;
683
679
684
- HasRawDataToExtract = true ;
685
- return false ;
680
+ return EUpdateResult::ExtractRawData;
686
681
}
687
682
bucket.BucketState = TSpilledBucket::EBucketState::InMemory;
688
- HasDataForProcessing = false ;
689
- return false ;
683
+ return EUpdateResult::None;
690
684
}
691
685
692
686
EOperatingMode GetMode () const {
@@ -744,10 +738,6 @@ class TSpillingSupportState : public TComputationValue<TSpillingSupportState> {
744
738
private:
745
739
ui64 NextBucketToSpill = 0 ;
746
740
747
- bool HasDataForProcessing = false ;
748
-
749
- bool HasRawDataToExtract = false ;
750
-
751
741
TState InMemoryProcessingState;
752
742
const TMultiType* const UsedInputItemType;
753
743
const TMultiType* const KeyAndStateType;
@@ -1259,6 +1249,7 @@ using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWra
1259
1249
, AllowSpilling(allowSpilling)
1260
1250
{}
1261
1251
1252
+ // MARK: DoCalculate
1262
1253
EFetchResult DoCalculate (NUdf::TUnboxedValue& state, TComputationContext& ctx, NUdf::TUnboxedValue*const * output) const {
1263
1254
if (!state.HasValue ()) {
1264
1255
MakeState (ctx, state);
@@ -1268,8 +1259,14 @@ using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWra
1268
1259
auto **fields = ctx.WideFields .data () + WideFieldsIndex;
1269
1260
1270
1261
while (true ) {
1271
- if (ptr->UpdateAndWait ()) {
1272
- return EFetchResult::Yield;
1262
+ switch (ptr->Update ()) {
1263
+ case TSpillingSupportState::EUpdateResult::Yield:
1264
+ return EFetchResult::Yield;
1265
+ case TSpillingSupportState::EUpdateResult::ExtractRawData:
1266
+ Nodes.ExtractValues (ctx, static_cast <NUdf::TUnboxedValue*>(ptr->Throat ), fields);
1267
+ break ;
1268
+ case TSpillingSupportState::EUpdateResult::None:
1269
+ break ;
1273
1270
}
1274
1271
if (ptr->InputStatus != EFetchResult::Finish) {
1275
1272
for (auto i = 0U ; i < Nodes.ItemNodes .size (); ++i)
@@ -1297,9 +1294,6 @@ using TBaseComputation = TStatefulWideFlowCodegeneratorNode<TWideLastCombinerWra
1297
1294
case TSpillingSupportState::ETasteResult::ConsumeRawData:
1298
1295
Nodes.ExtractValues (ctx, fields, static_cast <NUdf::TUnboxedValue*>(ptr->Throat ));
1299
1296
break ;
1300
- case TSpillingSupportState::ETasteResult::ExtractRawData:
1301
- Nodes.ExtractValues (ctx, static_cast <NUdf::TUnboxedValue*>(ptr->Throat ), fields);
1302
- break ;
1303
1297
}
1304
1298
continue ;
1305
1299
}
0 commit comments