[ https://issues.apache.org/jira/browse/LUCENE-1188?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
Chandan Raj Rupakheti updated LUCENE-1188: ------------------------------------------ Fix Version/s: (was: 2.3.1) (was: 2.3) (was: 2.2) Remaining Estimate: 0.5h Original Estimate: 0.5h > equals and hashCode implementation in org.apache.lucene.search.* package > ------------------------------------------------------------------------ > > Key: LUCENE-1188 > URL: https://issues.apache.org/jira/browse/LUCENE-1188 > Project: Lucene - Java > Issue Type: Improvement > Components: Search > Affects Versions: 2.2, 2.3, 2.3.1 > Environment: All > Reporter: Chandan Raj Rupakheti > Original Estimate: 0.5h > Remaining Estimate: 0.5h > > I would like to talk about the implementation of equals and hashCode method > in org.apache.lucene.search.* package. > Example One: > org.apache.lucene.search.spans.SpanTermQuery (Super Class) > <- org.apache.lucene.search.payloads.BoostingTermQuery (Sub Class) > Observation: > * BoostingTermQuery defines equals but inherits hashCode from SpanTermQuery. > Definition of equals is a code clone of SpanTermQuery with a change in class > name. > Intention: > I believe the intention of equals redefinition in BoostingTermQuery is not to > make the objects of SpanTermQuery and BoostingTermQuery comparable. ie. > spanTermQuery.equals(boostingTermQuery) == false && > boostingTermQuery.equals(spanTermQuery) == false. > Problem: > With current implementation, the intention might not be respected as a result > of symmetric property violation of equals contract i.e. > spanTermQuery.equals(boostingTermQuery) == true (can be) && > boostingTermQuery.equals(spanTermQuery) == false. (always) > (Note: Provided their state variables are equal) > Solution: > Change implementation of equals in SpanTermQuery from: > {code:title=SpanTermQuery.java|borderStyle=solid} > public boolean equals(Object o) { > if (!(o instanceof SpanTermQuery)) > return false; > SpanTermQuery other = (SpanTermQuery)o; > return (this.getBoost() == other.getBoost()) > && this.term.equals(other.term); > } > {code} > To: > {code:title=SpanTermQuery.java|borderStyle=solid} > public boolean equals(Object o) { > if(o == this) return true; > if(o == null || o.getClass() != this.getClass()) return false; > // if (!(o instanceof SpanTermQuery)) > // return false; > SpanTermQuery other = (SpanTermQuery)o; > return (this.getBoost() == other.getBoost()) > && this.term.equals(other.term); > } > {code} > Advantage: > * BoostingTermQuery.equals and BoostingTermQuery.hashCode is not needed while > still preserving the same intention as before. > > * Any further subclassing that does not add new state variables in the > extended classes of SpanTermQuery, does not have to redefine equals and > hashCode. > * Even if a new state variable is added in a subclass, the symmetric property > of equals contract will still be respected irrespective of implementation > (i.e. instanceof / getClass) of equals and hashCode in the subclasses. > Example Two: > org.apache.lucene.search.CachingWrapperFilter (Super Class) > <- org.apache.lucene.search.CachingWrapperFilterHelper (Sub Class) > Observation: > Same as Example One. > Problem: > Same as Example one. > Solution: > Change equals in CachingWrapperFilter from: > {code:title=CachingWrapperFilter.java|borderStyle=solid} > public boolean equals(Object o) { > if (!(o instanceof CachingWrapperFilter)) return false; > return this.filter.equals(((CachingWrapperFilter)o).filter); > } > {code} > To: > {code:title=CachingWrapperFilter.java|borderStyle=solid} > public boolean equals(Object o) { > // if (!(o instanceof CachingWrapperFilter)) return false; > if(o == this) return true; > if(o == null || o.getClass() != this.getClass()) return false; > return this.filter.equals(((CachingWrapperFilter)o).filter); > } > {code} > Advantage: > Same as Example One. Here, CachingWrapperFilterHelper.equals and > CachingWrapperFilterHelper.hashCode is not needed. > Example Three: > org.apache.lucene.search.MultiTermQuery (Abstract Parent) > <- org.apache.lucene.search.FuzzyQuery (Concrete Sub) > <- org.apache.lucene.search.WildcardQuery (Concrete Sub) > Observation (Not a problem): > * WildcardQuery defines equals but inherits hashCode from MultiTermQuery. > Definition of equals contains just super.equals invocation. > * FuzzyQuery has few state variables added that are referenced in its equals > and hashCode. > Intention: > I believe the intention here is not to make objects of FuzzyQuery and > WildcardQuery comparable. ie. fuzzyQuery.equals(wildCardQuery) == false && > wildCardQuery.equals(fuzzyQuery) == false. > Proposed Implementation: > How about changing the implementation of equals in MultiTermQuery from: > {code:title=MultiTermQuery.java|borderStyle=solid} > public boolean equals(Object o) { > if (this == o) return true; > if (!(o instanceof MultiTermQuery)) return false; > final MultiTermQuery multiTermQuery = (MultiTermQuery) o; > if (!term.equals(multiTermQuery.term)) return false; > return getBoost() == multiTermQuery.getBoost(); > } > {code} > To: > {code:title=MultiTermQuery.java|borderStyle=solid} > public boolean equals(Object o) { > if (this == o) return true; > // if (!(o instanceof MultiTermQuery)) return false; > if(o == null || o.getClass() != this.getClass()) return false; > final MultiTermQuery multiTermQuery = (MultiTermQuery) o; > if (!term.equals(multiTermQuery.term)) return false; > return getBoost() == multiTermQuery.getBoost(); > } > {code} > Advantage: > Same as above. Here, WildcardQuery.equals is not needed as it does not define > any new state. (FuzzyQuery.equals is still needed because FuzzyQuery defines > new state.) -- This message is automatically generated by JIRA. - You can reply to this email to add a comment to the issue online. --------------------------------------------------------------------- To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]