Ensure that FilterXxx properly delegate to the decorated instances#15469
Ensure that FilterXxx properly delegate to the decorated instances#15469dweiss merged 8 commits intoapache:mainfrom
Conversation
|
This PR has not had activity in the past 2 weeks, labeling it as stale. If the PR is waiting for review, notify the dev@lucene.apache.org list. Thank you for your contribution! |
The patch introduce a new assertion method in LuceneTestCase that verify that a given base decorator class (Filter) properly delegate all methods calls to the wrapped instance. The patch add the missing delegation methods. Closes apache#15452
dweiss
left a comment
There was a problem hiding this comment.
I like it very much. Especially the tests that get simplified. I've noticed a few things that seem odd to me but I'll need to understand what's going on better. Please give me some time to dive deeper into it. Looks great though.
…n FilterIndexInput subclasses as it's a mistake if they're cloned without the delegate also cloned.
dweiss
left a comment
There was a problem hiding this comment.
I like it really much - I think it makes those Filter* classes truly more transparent to use. I would really like to get down to why those few methods have to be added so that tests can pass. It seems like it should be the other way around - we should fix tests if they're relying on incorrect workings of previous filter implementations instead of patching those implementations in the code.
I'll try to return to it, time permitting, but it'd be good if somebody with more knowledge of the scoring system looked into it.
|
LGTM. It would be good to run luceneutil benchmarks to see if we're not adding any regressions here, would you have the time to run them, @blerer ? |
|
I will try to find some time for it next week. Thanks for the review. |
|
No, thank you for doing the heavy lifting! It really is a nice cleanup. |
|
I've ran luceneutil benchmarks locally but I don't see much deviation other than noise. I'll merge it in. |
|
We've seen some CI failures after this merged - reproduce with The root of the problem is |
|
I'll have to look into this to understand exactly what's happening but in general I think this patch reveals existing problems rather than causes them... It really is conceptually better if those filters delegate consistently to subclasses instead of partially reverting the default implementation. Should we revert until this is sorted out? |
|
It's tricky, as delegation really does break if you have methods that depend on each other for default implementations. Yes, let's revert for now and see if there's a better way of doing this. |
This means the design is somehow screwed - if they depend on a particular implementation of a method in a superclass then either something is missing (an override modifying the behavior consistently in a subclass) or the contract is broken somewhere and makes those classes inconsistent... I'll revert but I think it'd be good to understand and fix this. |
|
Ok, I see what you mean. I'll give it some thought. |
…tances (apache#15469)" This reverts commit 3eb7ea9.
|
Right. I've mentioned it before but the decorator pattern is basically always prone to braking something. The thing we missed here is indeed the strong relationship between nextDoc and intoBitSet. Basically, whenever there is a class that wraps another one, it should provide these two methods consistently - either it knows how to implement them in the filter subclass or it shouldn't touch them at all. TestFilterLeafReader has a nice example where it implements this: This will clearly result in a different set of bits if intoBitSet stays delegated. It is possible to automatically detect and enforce such tightly coupled overrides - I've written a quick example here using archunit - this only checks subclasses of FilterPostingsEnum but it immediately fails with the offender: There doesn't seem to be the right way to do it or at least I can't think of any. |
I mean this in terms of the original problem of whether to delegate everything consistently or not. Both ways have their issues. Maybe we can cherry pick just parts of the patch or identify if this particular method pair is the only problem and write archunit tests around this? I don't know. |
|
From an API point of view, I feel that |
|
I agree. The question remains if it's the only thing lurking there that can go wrong... I thought about just ignoring this particular method in delegation checks but had a reflection that maybe we're trying to fix a can of worms that should be left unopened... Please don't let it discourage you patches welcome! :) |
|
The "existing" behavior (where some stuff is delegated but others are not) does (I think) a pretty good job of satisfying functional correctness while missing out on potential optimizations. The It's still super trappy in terms of knowing what gets delegated and what doesn't, though. Another pair of methods whose behavior depend on each other: |
…pache#15469) * Ensure that Filter classes properly delegate to the decorated instances The patch introduce a new assertion method in LuceneTestCase that verify that a given base decorator class (Filter) properly delegate all methods calls to the wrapped instance. The patch add the missing delegation methods. Closes apache#15452 * Fix delegation from super.slice to in.slice in FilterIndexInput. * Revert API change and delegate getName properly. * Simplify the code slightly. Throw RuntimeException on clone() calls on FilterIndexInput subclasses as it's a mistake if they're cloned without the delegate also cloned. * Add explicit comment where count cannot be approximated in filter subclasses. * Add a clarification to BooleanScorerSupplier.advanceShallow. --------- Co-authored-by: Dawid Weiss <dawid.weiss@carrotsearch.com>
…ances (apache#15469)" This reverts commit 6af9e96.
This is an initial version of the patch as I am waiting for the result of the discussion on the mailing list.
The patch introduce a new assertion method in LuceneTestCase that verify that a given Decorator class (FilterXxx) properly delegate all methods calls to the wrapped instance. The patch add the missing delegation methods.
Closes #15452
Description