blob: 6df98d78d90155c37e0aebd7fb16a176404767c0 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 Zend Technologies and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Zend Technologies - initial API and implementation
*******************************************************************************/
package org.eclipse.dltk.internal.core.index.lucene;
import java.io.IOException;
import java.text.MessageFormat;
import java.util.Set;
import org.apache.lucene.index.DocValues;
import org.apache.lucene.index.LeafReaderContext;
import org.apache.lucene.index.NumericDocValues;
import org.apache.lucene.index.Term;
import org.apache.lucene.search.ConstantScoreScorer;
import org.apache.lucene.search.DocIdSet;
import org.apache.lucene.search.DocIdSetIterator;
import org.apache.lucene.search.DocValuesDocIdSet;
import org.apache.lucene.search.Explanation;
import org.apache.lucene.search.IndexSearcher;
import org.apache.lucene.search.Query;
import org.apache.lucene.search.Scorer;
import org.apache.lucene.search.Weight;
import org.apache.lucene.util.Bits;
import org.eclipse.dltk.ast.Modifiers;
/**
* Query for scoring declaration modifiers represented by corresponding DLTK's
* modifiers bit flags {@link Modifiers}.
*
* @author Michal Niewrzal, Bartlomiej Laczkowski
*/
public class BitFlagsQuery extends Query {
private final int fTrueFlags;
private final int fFalseFlags;
public BitFlagsQuery(final int trueFlags, final int falseFlags) {
fTrueFlags = trueFlags;
fFalseFlags = falseFlags;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + fFalseFlags;
result = prime * result + fTrueFlags;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
BitFlagsQuery other = (BitFlagsQuery) obj;
if (fFalseFlags != other.fFalseFlags)
return false;
if (fTrueFlags != other.fTrueFlags)
return false;
return true;
}
@Override
public String toString(String input) {
return MessageFormat.format(
"BitFlagsQuery(Field: {0}, True Flags: {1}, False Flags: {2})", //$NON-NLS-1$
IndexFields.NDV_FLAGS, fTrueFlags, fFalseFlags);
}
@Override
public Weight createWeight(IndexSearcher searcher, boolean needsScores)
throws IOException {
return new Weight(this) {
@Override
public void extractTerms(Set<Term> terms) {
// Ignore
}
@Override
public void normalize(float norm, float topLevelBoost) {
// Ignore
}
@Override
public float getValueForNormalization() throws IOException {
return 0;
}
@Override
public Explanation explain(LeafReaderContext context, int doc)
throws IOException {
final Scorer scorer = scorer(context);
final boolean match = (scorer != null
&& scorer.iterator().advance(doc) == doc);
if (match) {
assert scorer.score() == 0;
return Explanation.match(0, "Match on id" + doc); //$NON-NLS-1$
} else {
return Explanation.match(0, "No match on id" + doc); //$NON-NLS-1$
}
}
@Override
public Scorer scorer(LeafReaderContext context) throws IOException {
final DocIdSet set = getDocIdSet(context,
context.reader().getLiveDocs());
if (set == null) {
return null;
}
final DocIdSetIterator iterator = set.iterator();
if (iterator == null) {
return null;
}
return new ConstantScoreScorer(this, 0, iterator);
}
};
}
/**
* Finds and returns matching doc ID set.
*
* @param context
* @param acceptDocs
* @return matching doc ID set
* @throws IOException
*/
protected DocIdSet getDocIdSet(final LeafReaderContext context,
Bits acceptDocs) throws IOException {
final NumericDocValues numDocValues = DocValues
.getNumeric(context.reader(), IndexFields.NDV_FLAGS);
return new DocValuesDocIdSet(context.reader().maxDoc(), acceptDocs) {
@Override
protected boolean matchDoc(int doc) {
long flags = numDocValues.get(doc);
if (fTrueFlags != 0) {
if ((flags & fTrueFlags) == 0) {
return false;
}
}
if (fFalseFlags != 0) {
if ((flags & fFalseFlags) != 0) {
return false;
}
}
return true;
}
};
}
}