@@ -453,36 +453,53 @@ bool TColumnEngineForLogs::ErasePortion(const TPortionInfo& portionInfo, bool up
453453}
454454
455455std::vector<std::shared_ptr<TPortionInfo>> TColumnEngineForLogs::Select (
456- TInternalPathId pathId, TSnapshot snapshot, const TPKRangesFilter& pkRangesFilter, const bool withUncommitted ) const {
456+ TInternalPathId pathId, TSnapshot snapshot, const TPKRangesFilter& pkRangesFilter, const bool withNonconflicting, const bool withConflicting, const std::optional<THashSet<TInsertWriteId>>& ownPortions ) const {
457457 std::vector<std::shared_ptr<TPortionInfo>> out;
458458 auto spg = GranulesStorage->GetGranuleOptional (pathId);
459459 if (!spg) {
460460 return out;
461461 }
462462
463- for (const auto & [_, portionInfo ] : spg->GetInsertedPortions ()) {
464- if (!portionInfo-> IsVisible (snapshot, !withUncommitted )) {
463+ for (const auto & [writeId, portion ] : spg->GetInsertedPortions ()) {
464+ if (portion-> IsRemovedFor (snapshot)) {
465465 continue ;
466466 }
467- const bool skipPortion = !pkRangesFilter.IsUsed (*portionInfo);
468- AFL_TRACE (NKikimrServices::TX_COLUMNSHARD_SCAN)(" event" , skipPortion ? " portion_skipped" : " portion_selected" )(" pathId" , pathId)(
469- " portion" , portionInfo->DebugString ());
470- if (skipPortion) {
467+ // nonconflicting: visible in the snapshot or own portions
468+ auto nonconflicting = portion->IsVisible (snapshot, true ) || (ownPortions.has_value () && ownPortions->contains (writeId));
469+ auto conflicting = !nonconflicting;
470+
471+ if (nonconflicting && !withNonconflicting || conflicting && !withConflicting) {
471472 continue ;
472473 }
473- out.emplace_back (portionInfo);
474+
475+ const bool takePortion = pkRangesFilter.IsUsed (*portion);
476+ AFL_TRACE (NKikimrServices::TX_COLUMNSHARD_SCAN)(" event" , takePortion ? " portion_selected" : " portion_skipped" )(" pathId" , pathId)(" portion" , portion->DebugString ());
477+ if (takePortion) {
478+ out.emplace_back (portion);
479+ }
474480 }
475- for (const auto & [_, portionInfo] : spg->GetPortions ()) {
476- if (!portionInfo->IsVisible (snapshot, !withUncommitted)) {
481+ for (const auto & [_, portion] : spg->GetPortions ()) {
482+ if (portion->IsRemovedFor (snapshot)) {
483+ continue ;
484+ }
485+
486+ auto nonconflicting = portion->IsVisible (snapshot, true );
487+ auto conflicting = !nonconflicting;
488+
489+ // take compacted portions only if all the records are visible in the snapshot
490+ if (conflicting && portion->GetPortionType () == EPortionType::Compacted) {
477491 continue ;
478492 }
479- const bool skipPortion = !pkRangesFilter.IsUsed (*portionInfo);
480- AFL_TRACE (NKikimrServices::TX_COLUMNSHARD_SCAN)(" event" , skipPortion ? " portion_skipped" : " portion_selected" )(" pathId" , pathId)(
481- " portion" , portionInfo->DebugString ());
482- if (skipPortion) {
493+
494+ if (nonconflicting && !withNonconflicting || conflicting && !withConflicting) {
483495 continue ;
484496 }
485- out.emplace_back (portionInfo);
497+
498+ const bool takePortion = pkRangesFilter.IsUsed (*portion);
499+ AFL_TRACE (NKikimrServices::TX_COLUMNSHARD_SCAN)(" event" , takePortion ? " portion_selected" : " portion_skipped" )(" pathId" , pathId)(" portion" , portion->DebugString ());
500+ if (takePortion) {
501+ out.emplace_back (portion);
502+ }
486503 }
487504
488505 return out;
0 commit comments