Skip to content

test#62496

Open
BiteTheDDDDt wants to merge 1 commit intoapache:branch-4.1from
BiteTheDDDDt:test_0414
Open

test#62496
BiteTheDDDDt wants to merge 1 commit intoapache:branch-4.1from
BiteTheDDDDt:test_0414

Conversation

@BiteTheDDDDt
Copy link
Copy Markdown
Contributor

pick from #61617

What problem does this PR solve?

Issue Number: close #xxx

Related PR: #xxx

Problem Summary:

Release note

None

Check List (For Author)

  • Test

    • Regression test
    • Unit Test
    • Manual test (add detailed scripts or steps below)
    • No need to test or manual test. Explain why:
      • This is a refactor/code format and no logic has been changed.
      • Previous test can cover this change.
      • No code files have been changed.
      • Other reason
  • Behavior changed:

    • No.
    • Yes.
  • Does this need documentation?

    • No.
    • Yes.

Check List (For Reviewer who merge this PR)

  • Confirm the release note
  • Confirm test cases
  • Confirm document
  • Add branch pick label

Copilot AI review requested due to automatic review settings April 14, 2026 15:50
@BiteTheDDDDt BiteTheDDDDt requested a review from yiguolei as a code owner April 14, 2026 15:50
@hello-stephen
Copy link
Copy Markdown
Contributor

Thank you for your contribution to Apache Doris.
Don't know what should be done next? See How to process your PR.

Please clearly describe your PR:

  1. What problem was fixed (it's best to include specific error reporting information). How it was fixed.
  2. Which behaviors were modified. What was the previous behavior, what is it now, why was it modified, and what possible impacts might there be.
  3. What features were added. Why was this function added?
  4. Which code was refactored and why was this part of the code refactored?
  5. Which functions were optimized and what is the difference before and after the optimization?

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Note

Copilot was unable to run its full agentic suite in this review.

This PR introduces a shared, atomic scan limit that is enforced across all parallel scan instances (and their scanners) so that total produced rows respect the SQL LIMIT globally rather than per-instance.

Changes:

  • Thread a shared std::atomic<int64_t> limit counter from ScanOperatorX into ScannerContext.
  • Enforce the shared limit in ScannerScheduler::_scanner_scan() by discarding/truncating blocks when quota is exhausted.
  • Update unit tests to pass a shared_limit pointer into ScannerContext::create_shared().

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
be/test/exec/scan/scanner_context_test.cpp Updates test setup to provide the new shared-limit parameter to ScannerContext.
be/src/exec/scan/scanner_scheduler.cpp Stops scanning and truncates/discards blocks when the shared limit quota is exhausted.
be/src/exec/scan/scanner_context.h Extends ScannerContext API/state with a pointer to a shared limit and quota acquisition helpers.
be/src/exec/scan/scanner_context.cpp Implements atomic quota acquisition and finishes early when shared limit is exhausted.
be/src/exec/operator/scan_operator.h Adds _shared_scan_limit to ScanOperatorX to share remaining limit across instances.
be/src/exec/operator/scan_operator.cpp Initializes _shared_scan_limit and passes it into ScannerContext.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +224 to +226
// Points to the shared remaining limit on ScanOperatorX, shared across all
// parallel instances and their scanners. -1 means no limit.
std::atomic<int64_t>* _shared_scan_limit = nullptr;
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remaining_limit() unconditionally dereferences _shared_scan_limit, which is default-initialized to nullptr and is also used throughout the implementation (e.g., quota acquisition / finish checks). If any call path constructs a ScannerContext without a valid shared limit pointer (or with a pointer whose lifetime ends early), this will crash. Make _shared_scan_limit a non-null invariant (e.g., store a reference, or enforce non-null via constructor + DCHECK(_shared_scan_limit != nullptr)), and document/guarantee that the pointed-to atomic outlives the ScannerContext.

Suggested change
// Points to the shared remaining limit on ScanOperatorX, shared across all
// parallel instances and their scanners. -1 means no limit.
std::atomic<int64_t>* _shared_scan_limit = nullptr;
// Default shared remaining limit used to preserve a non-null invariant for
// _shared_scan_limit. A value of -1 means "no limit".
inline static std::atomic<int64_t> _default_shared_scan_limit {-1};
// Points to the shared remaining limit on ScanOperatorX, shared across all
// parallel instances and their scanners. This pointer must always be non-null;
// if a caller does not provide one explicitly, it falls back to
// _default_shared_scan_limit. Any externally supplied atomic must outlive this
// ScannerContext. A value of -1 means no limit.
std::atomic<int64_t>* _shared_scan_limit = &_default_shared_scan_limit;

Copilot uses AI. Check for mistakes.
std::shared_ptr<CgroupCpuCtl> cgroup_cpu_ctl = std::make_shared<CgroupV2CpuCtl>(1);
std::unique_ptr<ScannerScheduler> scan_scheduler =
std::make_unique<ThreadPoolSimplifiedScanScheduler>("ForTest", cgroup_cpu_ctl);
std::atomic<int64_t> shared_limit {-1};
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests now pass a shared_limit pointer but keep it at -1 (no limit). This means the newly added shared-limit enforcement paths (quota acquisition, truncation/discard-on-exhaustion, early finish when remaining==0) are not exercised by these unit tests. To cover the new behavior, initialize shared_limit from limit in tests that set a positive limit, and add at least one case asserting: (1) blocks are truncated when the remaining quota is smaller than a block, and (2) scanning stops/finishes when quota reaches 0.

Copilot uses AI. Check for mistakes.
std::shared_ptr<ScannerContext> scanner_context = ScannerContext::create_shared(
state.get(), olap_scan_local_state.get(), output_tuple_desc, output_row_descriptor,
scanners, limit, scan_dependency, parallel_tasks);
scanners, limit, scan_dependency, &shared_limit, parallel_tasks);
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tests now pass a shared_limit pointer but keep it at -1 (no limit). This means the newly added shared-limit enforcement paths (quota acquisition, truncation/discard-on-exhaustion, early finish when remaining==0) are not exercised by these unit tests. To cover the new behavior, initialize shared_limit from limit in tests that set a positive limit, and add at least one case asserting: (1) blocks are truncated when the remaining quota is smaller than a block, and (2) scanning stops/finishes when quota reaches 0.

Copilot uses AI. Check for mistakes.
const RowDescriptor* output_row_descriptor,
const std::list<std::shared_ptr<ScannerDelegate>>& scanners, int64_t limit_,
std::shared_ptr<Dependency> dependency
std::shared_ptr<Dependency> dependency, std::atomic<int64_t>* shared_scan_limit
Copy link

Copilot AI Apr 14, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Passing a raw pointer for shared_scan_limit makes lifetime requirements implicit and easy to violate (dangling pointer risk), especially since ScannerContext instances can outlive some surrounding scaffolding during shutdown/cancellation. Consider making the API express ownership/lifetime explicitly (e.g., std::shared_ptr<std::atomic<int64_t>>, or a small shared state object), or accept/store a reference with a clearly documented guarantee that the referenced atomic outlives ScannerContext.

Suggested change
std::shared_ptr<Dependency> dependency, std::atomic<int64_t>* shared_scan_limit
std::shared_ptr<Dependency> dependency,
std::shared_ptr<std::atomic<int64_t>> shared_scan_limit

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants