ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
Skip to content

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods - #9589

Closed
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t
Closed

ARROW-11797: [C++][Dataset] Provide batch stream Scanner methods#9589
bkietz wants to merge 3 commits into
apache:masterfrom
bkietz:11797-Provide-Scanner-methods-t

Conversation

@bkietz

Copy link
Copy Markdown
Member

No description provided.

@github-actions

Copy link
Copy Markdown

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Here's a quick look. I think my main concern is the potential race condition in Pop. The other comments are more of "I'm about to replace this with something else so lets not worry"

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll be replacing this with something better so I don't know how much we care to worry but this is not ideal. For example, with parquet, this would fetch metadata for every file in the scan before starting to read any individual file. It introduces more latency than necessary.

Also, I'm not sure how this will interact with parquet preloading.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Again, what I'm working on will work around this so maybe not stress at the moment but there's no back-pressure here. If the batch consumer is not fast enough and the dataset is larger than RAM the system will run out of RAM.

It's a bit odd because you are fixing ARROW-11800 here (though without pressure) and then I'll be breaking it again with my implementation (the first pass of my impl will have back pressure and parse loaded buffers a bit more serially)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Why both Scan(visitor) and ToBatches? Couldn't you just do ToBatches().Visit(visitor)?

Copy link
Copy Markdown
MemberAuthor

Choose a reason for hiding this comment

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

The difference is ToBatches().Visit(visitor) would invoke visitor exclusively on the thread which called Visit() whereas Scan(visitor) invokes visitor in the scan's thread pool. This method is speculative; I'm not sure we'd want to provide that but I included it as an example

@bkietz
bkietzforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 522aca4 to 08aec2fCompareMarch 1, 2021 20:36
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 90818b2 to ba8c952CompareApril 7, 2021 18:56
@lidavidm

lidavidm commented Apr 7, 2021

Copy link
Copy Markdown
Member

I've updated this in case we change how to proceed with ARROW-7001:

  • Rebased against master
  • Added Python/R deprecation warnings for Scan(), since either way, we're planning to remove ScanTask in 5.0
  • Changed the iterator so that scan tasks are materialized and executed iteratively, to better handle larger-than-memory datasets
  • Removed Scan(visitor) to reduce API surface (we can add it if the need comes up)

@westonpacewestonpace left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is very cool. Now I just need to provide the V2 :)

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Style nit: member variables should be at the bottom of a struct:

https://google.github.io/styleguide/cppguide.html#Declaration_Order

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'm not entirely certain it is safe to modify iteration_error outside the mutex. What happens if Pop is accessing it at the same time?

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is also not safe to do outside the mutex.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: best to relinquish the mutex before calling notify

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I think I'm just not seeing it but what causes the above loop to exit if there is an error scanning?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Eventually we'll run out of scan tasks/batches, since an error in getting the next scan task won't stop the current scan tasks from eventually completing. So really it's "all scan tasks drained (and maybe we didn't start all of them due to a failure)"

Comment threadcpp/src/arrow/dataset/scanner.h Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: If I see ToBatches I expect RecordBatchVector. I had named it ScanBatches but I don't feel too strongly on this point.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

You have a point. I didn't want to take ScanBatches since your method has a different signature. But maybe that could be ScanIndexedBatches or something.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, the issue I ran into was that ScanBatches was used by FileSystemDataset::Write and it needed the fragment info in order to have access to the fragment's partition expression. So at a minimum I needed to return "record batch & partition it came from".

I think there was some discussion (either on the ML or some JIRA/PR) about the benefit of keeping the fragment available as the user might want to know where the batch came from.

Can you modify the ScanBatches here to return a RecordBatch/Fragment pair? I could align my ScanBatches with that (PositionedRecordBatch is overkill).

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Consider making a parameterized test instead so it is easier to trace failures if needed?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is this just testing a scan of one scan task & one batch? It seems we would want to test more than that.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

MakeScanner generates a union dataset of 2 InMemoryDatasets each of which repeats the batch 16 times so we should have 32 scan tasks total.

Comment threadpython/pyarrow/tests/test_dataset.py Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

At the very least we should create a JIRA to migrate these over to the new scan. Although I'm wondering if we want to just do that now because that would give us a lot more coverage of the non-deprecated path.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I'll do it now.

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nit: Does this comment still make sense?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Nope! :)

Comment threadr/src/dataset.cpp Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Maybe this is a naive question but why are there two versions of TakeRows?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hmm, Ben split it into two functions (a pure-Arrow implementation, and the R binding) presumably for convenience. But maybe we can just port the implementation into the C++ library and expose it to Python as well?

Comment threadr/R/dataset-scan.R Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

This is nice but probably not necessary, this was a (de facto) internal method. If it were me I'd just delete it, but since you've already done this, might as well keep it. Can you please just make a JIRA to delete this so we don't forget to clean this up after the release?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

We've been using ARROW-11782 so I'll note that in this PR and update the issue.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 4 times, most recently from 8e494c9 to 52f146eCompareApril 9, 2021 21:44
@lidavidm

Copy link
Copy Markdown
Member

@westonpace@bkietz this should be ready now, if either of you wants to take another look.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 70c7bb8 to 5e885cdCompareApril 12, 2021 18:15
@lidavidm

Copy link
Copy Markdown
Member

I restored the Scan(Visitor) overload that Ben pointed out in ARROW-12288, updated to use TaggedRecordBatch.

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch 2 times, most recently from 2f09670 to 67ed5a8CompareApril 13, 2021 13:35
@lidavidm

Copy link
Copy Markdown
Member

Rebased (unfortunately, I had to squash all commits or else the rebase would've been a pain).

@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 67ed5a8 to dc97bb1CompareApril 13, 2021 14:22
Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Is there a JIRA for pushing down the index predicate into the scan?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

I filed ARROW-12369.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Would you not want to skip empty arrays (where length == 0)?

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Thanks, that also exposed a bug (or well, poor error message) if all indices were out-of-bounds.

Comment threadcpp/src/arrow/dataset/scanner.cc Outdated
@lidavidm
lidavidmforce-pushed the 11797-Provide-Scanner-methods-t branch from 65f72a2 to ad14ea5CompareApril 14, 2021 22:00
@lidavidm

Copy link
Copy Markdown
Member

I am not sure why the JNI test is having so much trouble but it passes locally under Docker.

@westonpace

Copy link
Copy Markdown
Member

FYI, there are probably some things we could do to improve the JNI build (ARROW-11633)

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants

@bkietz@lidavidm@westonpace@nealrichardson