-
Notifications
You must be signed in to change notification settings - Fork 1.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Implement fast path of with_new_children() in ExecutionPlan #2168
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this looks great @mingmwang -- thank you very much.
Another thing we might want to consider doing would be to change the signature of ExecutionPlan
trait to require an Arc
to call with_new_children
, like so:
fn with_new_children(
self: Arc<Self>,
children: Vec<Arc<dyn ExecutionPlan>>,
) -> Result<Arc<dyn ExecutionPlan>> {
// put with_new_children_if_necessary implementation here
...
}
That would ensure that we could always apply the with_new_children_if_necessary
logic
"TopKExec wrong number of children".to_string(), | ||
)), | ||
} | ||
Ok(Arc::new(TopKExec { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What would you think about adding an assert here such asassert_eq!(children.len(), 1)
on the theory it might catch bugs faster when making changes?
The same question applies to other with_new_children
implementations below
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I removed the length check in the with_new_children()
method and move the check to with_new_children_if_necessary()
so that we can avoid the duplicate logic in all the trait implementations. In future if someone misuse this and still call the with_new_children()
and pass the wrong children param, it will lose the check, but if this is the case, the real problem is he should not call with_new_children()
and everyone should call with_new_children_if_necessary()
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure in Rust whether I can declare a method in the Trait to protected
so that it can only be visible in this module and in the Trait implementations.
@@ -258,6 +258,32 @@ pub trait ExecutionPlan: Debug + Send + Sync { | |||
fn statistics(&self) -> Statistics; | |||
} | |||
|
|||
/// Returns a new plan where all children were replaced by new plans if the provided children |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍
Done. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM overall. Minor comments on the doc.
/// Returns a new plan where all children were replaced by new plans if the provided children | ||
/// do not share the same point references with the existing children. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/// Returns a new plan where all children were replaced by new plans if the provided children | |
/// do not share the same point references with the existing children. | |
/// Returns a copy of this plan if we change any child according to pointer comparison. | |
/// |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
/// do not share the same point references with the existing children. | ||
/// The size of `children` must be equal to the size of `ExecutionPlan::children()`. | ||
/// Allow the vtable address comparisons for ExecutionPlan Trait Objects,it is harmless even | ||
/// in the case of 'false-native'. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should be false-positive I think?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it should be 'false-native'(two expected equal things end up not comparing equal) for Trait objects.
https://stackoverflow.com/questions/67109860/how-to-compare-trait-objects-within-an-arc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since we are reporting two equal items to be non-equal, it results in making a copy, so I term it 'false-positive'.
It should be 'false negative' if you only mean data equality. 😆
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a step in the right direction -- thank you @mingmwang
Which issue does this PR close?
Closes #1965.
Rationale for this change
What changes are included in this PR?
Are there any user-facing changes?