http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/analysis/LongAnalyzerReal.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/analysis/LongAnalyzerReal.java b/src/blur-core/src/main/java/org/apache/blur/analysis/LongAnalyzerReal.java new file mode 100644 index 0000000..5eb4c7e --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/analysis/LongAnalyzerReal.java @@ -0,0 +1,77 @@ +package org.apache.blur.analysis; +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.analysis.NumericTokenStream; +import org.apache.lucene.analysis.TokenStream; +import org.apache.lucene.util.NumericUtils; + +public class LongAnalyzerReal extends Analyzer { + + private static final String TYPE = "long"; + private int precisionStepDefault = NumericUtils.PRECISION_STEP_DEFAULT; + private int radix = 10; + + public LongAnalyzerReal(String typeStr) { + if (typeStr.startsWith(TYPE)) { + int index = typeStr.indexOf(','); + if (index > 0) { + String[] s = typeStr.split(","); + if (s.length > 1) { + try { + precisionStepDefault = Integer.parseInt(s[1]); + } catch (NumberFormatException e) { + throw new RuntimeException("Can not parser [" + s[1] + "] into an integer for the precisionStepDefault."); + } + } + if (s.length > 2) { + try { + precisionStepDefault = Integer.parseInt(s[2]); + } catch (NumberFormatException e) { + throw new RuntimeException("Can not parser [" + s[2] + "] into an integer for the radix."); + } + } + } + } else { + throw new RuntimeException("Long type can not parser [" + typeStr + "]"); + } + } + + @Override + public TokenStream tokenStream(String fieldName, Reader reader) { + NumericTokenStream numericTokenStream = new NumericTokenStream(precisionStepDefault); + try { + numericTokenStream.setLongValue(toLong(reader)); + } catch (IOException e) { + throw new RuntimeException(e); + } + return numericTokenStream; + } + + private long toLong(Reader reader) throws IOException { + StringBuilder builder = new StringBuilder(20); + int read; + while ((read = reader.read()) != -1) { + builder.append((char) read); + } + return Long.parseLong(builder.toString(), radix); + } + +}
http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/AbstractWrapperQuery.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/AbstractWrapperQuery.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/AbstractWrapperQuery.java new file mode 100644 index 0000000..5fa4116 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/AbstractWrapperQuery.java @@ -0,0 +1,82 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; +import java.util.Set; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.index.Term; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.Similarity; +import org.apache.lucene.search.Weight; + +@SuppressWarnings("deprecation") +public abstract class AbstractWrapperQuery extends Query { + private static final long serialVersionUID = -4512813621542220044L; + protected Query _query; + protected boolean _rewritten; + + public AbstractWrapperQuery(Query query) { + this(query, false); + } + + public AbstractWrapperQuery(Query query, boolean rewritten) { + this._query = query; + this._rewritten = rewritten; + } + + public abstract Object clone(); + + public Query combine(Query[] queries) { + return _query.combine(queries); + } + + public abstract Weight createWeight(Searcher searcher) throws IOException; + + public boolean equals(Object obj) { + return _query.equals(obj); + } + + public void extractTerms(Set<Term> terms) { + _query.extractTerms(terms); + } + + public float getBoost() { + return _query.getBoost(); + } + + public Similarity getSimilarity(Searcher searcher) { + return _query.getSimilarity(searcher); + } + + public int hashCode() { + return _query.hashCode(); + } + + public abstract Query rewrite(IndexReader reader) throws IOException; + + public void setBoost(float b) { + _query.setBoost(b); + } + + public abstract String toString(); + + public abstract String toString(String field); + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/FacetQuery.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/FacetQuery.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/FacetQuery.java new file mode 100644 index 0000000..980493c --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/FacetQuery.java @@ -0,0 +1,201 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; +import java.util.concurrent.atomic.AtomicLongArray; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.Explanation; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Scorer; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.Weight; + +@SuppressWarnings("deprecation") +public class FacetQuery extends AbstractWrapperQuery { + + private static final long serialVersionUID = -9131606859383383004L; + private Query[] facets; + private AtomicLongArray counts; + + public FacetQuery(Query query, Query[] facets, AtomicLongArray counts) { + super(query, false); + this.facets = facets; + this.counts = counts; + } + + public FacetQuery(Query query, Query[] facets, AtomicLongArray counts, boolean rewritten) { + super(query, rewritten); + this.facets = facets; + this.counts = counts; + } + + public String toString() { + return "facet:{" + _query.toString() + "}"; + } + + public String toString(String field) { + return "facet:{" + _query.toString(field) + "}"; + } + + @Override + public Object clone() { + return new FacetQuery((Query) _query.clone(), facets, counts, _rewritten); + } + + @Override + public Query rewrite(IndexReader reader) throws IOException { + if (_rewritten) { + return this; + } + for (int i = 0; i < facets.length; i++) { + facets[i] = facets[i].rewrite(reader); + } + return new FacetQuery(_query.rewrite(reader), facets, counts, true); + } + + @Override + public Weight createWeight(Searcher searcher) throws IOException { + Weight weight = _query.createWeight(searcher); + return new FacetWeight(weight, getWeights(searcher), counts); + } + + private Weight[] getWeights(Searcher searcher) throws IOException { + Weight[] weights = new Weight[facets.length]; + for (int i = 0; i < weights.length; i++) { + weights[i] = facets[i].createWeight(searcher); + } + return weights; + } + + public static class FacetWeight extends Weight { + + private static final long serialVersionUID = -5649908738708119094L; + private Weight weight; + private Weight[] facets; + private AtomicLongArray counts; + + public FacetWeight(Weight weight, Weight[] facets, AtomicLongArray counts) { + this.weight = weight; + this.facets = facets; + this.counts = counts; + } + + @Override + public Explanation explain(IndexReader reader, int doc) throws IOException { + return weight.explain(reader, doc); + } + + @Override + public Query getQuery() { + return weight.getQuery(); + } + + @Override + public float getValue() { + return weight.getValue(); + } + + @Override + public void normalize(float norm) { + weight.normalize(norm); + } + + @Override + public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + Scorer scorer = weight.scorer(reader, true, topScorer); + if (scorer == null) { + return null; + } + return new FacetScorer(scorer, getScorers(reader, true, topScorer), counts); + } + + private Scorer[] getScorers(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + Scorer[] scorers = new Scorer[facets.length]; + for (int i = 0; i < scorers.length; i++) { + scorers[i] = facets[i].scorer(reader, scoreDocsInOrder, topScorer); + } + return scorers; + } + + @Override + public float sumOfSquaredWeights() throws IOException { + return weight.sumOfSquaredWeights(); + } + } + + public static class FacetScorer extends Scorer { + + private Scorer baseScorer; + private Scorer[] facets; + private AtomicLongArray counts; + private int facetLength; + + public FacetScorer(Scorer scorer, Scorer[] facets, AtomicLongArray counts) { + super(scorer.getSimilarity()); + this.baseScorer = scorer; + this.facets = facets; + this.counts = counts; + this.facetLength = facets.length; + } + + private int processFacets(int doc) throws IOException { + if (doc == NO_MORE_DOCS) { + return doc; + } + for (int i = 0; i < facetLength; i++) { + Scorer facet = facets[i]; + if (facet == null) { + continue; + } + int docID = facet.docID(); + if (docID == NO_MORE_DOCS) { + continue; + } + if (docID == doc) { + counts.incrementAndGet(i); + } else if (docID < doc) { + if (facet.advance(doc) == doc) { + counts.incrementAndGet(i); + } + } + } + return doc; + } + + @Override + public float score() throws IOException { + return baseScorer.score(); + } + + @Override + public int advance(int target) throws IOException { + return processFacets(baseScorer.advance(target)); + } + + @Override + public int docID() { + return baseScorer.docID(); + } + + @Override + public int nextDoc() throws IOException { + return processFacets(baseScorer.nextDoc()); + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/FairSimilarity.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/FairSimilarity.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/FairSimilarity.java new file mode 100644 index 0000000..f0203d1 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/FairSimilarity.java @@ -0,0 +1,56 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.lucene.index.FieldInvertState; +import org.apache.lucene.search.Similarity; + +public class FairSimilarity extends Similarity { + + private static final long serialVersionUID = 8819964136561756067L; + + @Override + public float coord(int overlap, int maxOverlap) { + return 1; + } + + @Override + public float idf(int docFreq, int numDocs) { + return 1; + } + + @Override + public float queryNorm(float sumOfSquaredWeights) { + return 1; + } + + @Override + public float sloppyFreq(int distance) { + return 1; + } + + @Override + public float tf(float freq) { + return 1; + } + + @Override + public float computeNorm(String field, FieldInvertState state) { + return 1; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/IterablePaging.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/IterablePaging.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/IterablePaging.java new file mode 100644 index 0000000..06a106b --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/IterablePaging.java @@ -0,0 +1,232 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; +import java.util.Iterator; +import java.util.concurrent.atomic.AtomicBoolean; +import java.util.concurrent.atomic.AtomicInteger; +import java.util.concurrent.atomic.AtomicLong; + +import org.apache.lucene.search.IndexSearcher; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.ScoreDoc; + +/** + * The {@link IterablePaging} class allows for easy paging through lucene hits. + */ +public class IterablePaging implements Iterable<ScoreDoc> { + + private static int DEFAULT_NUMBER_OF_HITS_TO_COLLECT = 1000; + private IndexSearcher searcher; + private Query query; + private TotalHitsRef totalHitsRef = new TotalHitsRef(); + private ProgressRef progressRef = new ProgressRef(); + private int skipTo; + private int numHitsToCollect = DEFAULT_NUMBER_OF_HITS_TO_COLLECT; + private int gather = -1; + private AtomicBoolean running; + + public IterablePaging(AtomicBoolean running, IndexSearcher searcher, Query query) throws IOException { + this(running, searcher, query, DEFAULT_NUMBER_OF_HITS_TO_COLLECT, null, null); + } + + public IterablePaging(AtomicBoolean running, IndexSearcher searcher, Query query, int numHitsToCollect) throws IOException { + this(running, searcher, query, numHitsToCollect, null, null); + } + + public IterablePaging(AtomicBoolean running, IndexSearcher searcher, Query query, int numHitsToCollect, TotalHitsRef totalHitsRef, ProgressRef progressRef) throws IOException { + this.running = running; + this.query = searcher.rewrite(query); + this.searcher = searcher; + this.numHitsToCollect = numHitsToCollect; + this.totalHitsRef = totalHitsRef == null ? this.totalHitsRef : totalHitsRef; + this.progressRef = progressRef == null ? this.progressRef : progressRef; + } + + public static class TotalHitsRef { + // This is an atomic integer because more than likely if there is + // any status sent to the user, it will be done in another thread. + protected AtomicInteger totalHits = new AtomicInteger(0); + + public int totalHits() { + return totalHits.get(); + } + } + + public static class ProgressRef { + // These are atomic integers because more than likely if there is + // any status sent to the user, it will be done in another thread. + protected AtomicInteger skipTo = new AtomicInteger(0); + protected AtomicInteger currentHitPosition = new AtomicInteger(0); + protected AtomicInteger searchesPerformed = new AtomicInteger(0); + protected AtomicLong queryTime = new AtomicLong(0); + + public int skipTo() { + return skipTo.get(); + } + + public int currentHitPosition() { + return currentHitPosition.get(); + } + + public int searchesPerformed() { + return searchesPerformed.get(); + } + + public long queryTime() { + return queryTime.get(); + } + } + + /** + * Gets the total hits of the search. + * + * @return the total hits. + */ + public int getTotalHits() { + return totalHitsRef.totalHits(); + } + + /** + * Allows for gathering of the total hits of this search. + * + * @param ref + * {@link TotalHitsRef}. + * @return this. + */ + public IterablePaging totalHits(TotalHitsRef ref) { + totalHitsRef = ref; + return this; + } + + /** + * Skips the first x number of hits. + * + * @param skipTo + * the number hits to skip. + * @return this. + */ + public IterablePaging skipTo(int skipTo) { + this.skipTo = skipTo; + return this; + } + + /** + * Only gather up to x number of hits. + * + * @param gather + * the number of hits to gather. + * @return this. + */ + public IterablePaging gather(int gather) { + this.gather = gather; + return this; + } + + /** + * Allows for gathering the progress of the paging. + * + * @param ref + * the {@link ProgressRef}. + * @return this. + */ + public IterablePaging progress(ProgressRef ref) { + this.progressRef = ref; + return this; + } + + /** + * The {@link ScoreDoc} iterator. + */ + @Override + public Iterator<ScoreDoc> iterator() { + return skipHits(new PagingIterator()); + } + + class PagingIterator implements Iterator<ScoreDoc> { + private PagingCollector collector; + private ScoreDoc[] scoreDocs; + private int counter = 0; + private int offset = 0; + private int endPosition = gather == -1 ? Integer.MAX_VALUE : skipTo + gather; + + PagingIterator() { + search(); + } + + void search() { + long s = System.currentTimeMillis(); + progressRef.searchesPerformed.incrementAndGet(); + if (collector == null) { + collector = new PagingCollector(numHitsToCollect); + } else { + collector = new PagingCollector(numHitsToCollect, scoreDocs[scoreDocs.length - 1]); + } + try { + StopExecutionCollector stopExecutionCollector = new StopExecutionCollector(collector, running); + searcher.search(query, stopExecutionCollector); + } catch (IOException e) { + throw new RuntimeException(e); + } + + totalHitsRef.totalHits.set(collector.getTotalHits()); + scoreDocs = collector.topDocs().scoreDocs; + long e = System.currentTimeMillis(); + progressRef.queryTime.addAndGet(e - s); + } + + @Override + public boolean hasNext() { + return counter < totalHitsRef.totalHits() && counter < endPosition ? true : false; + } + + @Override + public ScoreDoc next() { + if (isCurrentCollectorExhausted()) { + search(); + offset = 0; + } + progressRef.currentHitPosition.set(counter); + counter++; + return scoreDocs[offset++]; + } + + private boolean isCurrentCollectorExhausted() { + return offset < scoreDocs.length ? false : true; + } + + @Override + public void remove() { + throw new RuntimeException("read only"); + } + } + + private Iterator<ScoreDoc> skipHits(Iterator<ScoreDoc> iterator) { + progressRef.skipTo.set(skipTo); + for (int i = 0; i < skipTo && iterator.hasNext(); i++) { + // eats the hits, and moves the iterator to the desired skip to position. + progressRef.currentHitPosition.set(i); + iterator.next(); + } + return iterator; + } + + public static void setDefaultNumberOfHitsToCollect(int num) { + DEFAULT_NUMBER_OF_HITS_TO_COLLECT = num; + } +} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/PagingCollector.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/PagingCollector.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/PagingCollector.java new file mode 100644 index 0000000..2bead97 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/PagingCollector.java @@ -0,0 +1,119 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.ScoreDoc; +import org.apache.lucene.search.Scorer; +import org.apache.lucene.search.TopDocs; +import org.apache.lucene.search.TopDocsCollector; +import org.apache.lucene.util.PriorityQueue; + +/** + * The {@link PagingCollector} allows for paging through lucene hits. + */ +public class PagingCollector extends TopDocsCollector<ScoreDoc> { + + private ScoreDoc pqTop; + private int docBase; + private Scorer scorer; + private ScoreDoc previousPassLowest; + private int numHits; + + public PagingCollector(int numHits) { + // creates an empty score doc so that i don't have to check for null + // each time. + this(numHits, new ScoreDoc(-1, Float.MAX_VALUE)); + } + + public PagingCollector(int numHits, ScoreDoc previousPassLowest) { + super(new HitQueue(numHits, true)); + this.pqTop = pq.top(); + this.numHits = numHits; + this.previousPassLowest = previousPassLowest; + } + + @Override + public boolean acceptsDocsOutOfOrder() { + return true; + } + + @Override + public void collect(int doc) throws IOException { + float score = scorer.score(); + totalHits++; + doc += docBase; + if (score > previousPassLowest.score) { + // this hit was gathered on a previous page. + return; + } else if (score == previousPassLowest.score && doc <= previousPassLowest.doc) { + // if the scores are the same and the doc is less than or equal to the + // previous pass lowest hit doc then skip because this collector favors + // lower number documents. + return; + } else if (score < pqTop.score || (score == pqTop.score && doc > pqTop.doc)) { + return; + } + pqTop.doc = doc; + pqTop.score = score; + pqTop = pq.updateTop(); + } + + @Override + public void setNextReader(IndexReader reader, int docBase) throws IOException { + this.docBase = docBase; + } + + @Override + public void setScorer(Scorer scorer) throws IOException { + this.scorer = scorer; + } + + public ScoreDoc getLastScoreDoc(TopDocs topDocs) { + return topDocs.scoreDocs[(totalHits < numHits ? totalHits : numHits) - 1]; + } + + public ScoreDoc getLastScoreDoc(ScoreDoc[] scoreDocs) { + return scoreDocs[(totalHits < numHits ? totalHits : numHits) - 1]; + } + + public static class HitQueue extends PriorityQueue<ScoreDoc> { + + private boolean prePopulate; + + HitQueue(int size, boolean prePopulate) { + this.prePopulate = prePopulate; + initialize(size); + } + + @Override + protected ScoreDoc getSentinelObject() { + return !prePopulate ? null : new ScoreDoc(Integer.MAX_VALUE, Float.NEGATIVE_INFINITY); + } + + @Override + protected final boolean lessThan(ScoreDoc hitA, ScoreDoc hitB) { + if (hitA.score == hitB.score) { + return hitA.doc > hitB.doc; + } else { + return hitA.score < hitB.score; + } + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/StopExecutionCollector.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/StopExecutionCollector.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/StopExecutionCollector.java new file mode 100644 index 0000000..7a8eebe --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/StopExecutionCollector.java @@ -0,0 +1,67 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicBoolean; + +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.Collector; +import org.apache.lucene.search.Scorer; + +public class StopExecutionCollector extends Collector { + + private static final long _5MS = TimeUnit.MILLISECONDS.toNanos(5); + + private Collector _collector; + private AtomicBoolean _running; + private long last; + + public StopExecutionCollector(Collector collector, AtomicBoolean running) { + _collector = collector; + _running = running; + } + + public static class StopExecutionCollectorException extends RuntimeException { + private static final long serialVersionUID = 5753875017543945163L; + } + + public boolean acceptsDocsOutOfOrder() { + return _collector.acceptsDocsOutOfOrder(); + } + + public void collect(int doc) throws IOException { + long now = System.nanoTime(); + if (last + _5MS < now) { + if (!_running.get()) { + throw new StopExecutionCollectorException(); + } + last = now; + } + _collector.collect(doc); + } + + public void setNextReader(IndexReader reader, int docBase) throws IOException { + _collector.setNextReader(reader, docBase); + } + + public void setScorer(Scorer scorer) throws IOException { + _collector.setScorer(scorer); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperParser.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperParser.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperParser.java new file mode 100644 index 0000000..124229b --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperParser.java @@ -0,0 +1,215 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import static org.apache.blur.utils.BlurConstants.SEP; +import static org.apache.blur.utils.BlurConstants.SUPER; + +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +import org.apache.blur.thrift.generated.ScoreType; +import org.apache.lucene.analysis.Analyzer; +import org.apache.lucene.index.Term; +import org.apache.lucene.queryParser.ParseException; +import org.apache.lucene.queryParser.QueryParser; +import org.apache.lucene.search.BooleanClause; +import org.apache.lucene.search.BooleanQuery; +import org.apache.lucene.search.Filter; +import org.apache.lucene.search.FilteredQuery; +import org.apache.lucene.search.MatchAllDocsQuery; +import org.apache.lucene.search.MultiPhraseQuery; +import org.apache.lucene.search.PhraseQuery; +import org.apache.lucene.search.Query; +import org.apache.lucene.util.Version; + + +public class SuperParser extends QueryParser { + + private Map<Query, String> fieldNames = new HashMap<Query, String>(); + private boolean superSearch = true; + private Filter queryFilter; + private final ScoreType scoreType; + + public SuperParser(Version matchVersion, Analyzer a, boolean superSearch, Filter queryFilter, ScoreType scoreType) { + super(matchVersion, SUPER, a); + this.setAutoGeneratePhraseQueries(true); + this.setAllowLeadingWildcard(true); + this.superSearch = superSearch; + this.queryFilter = queryFilter; + this.scoreType = scoreType; + } + + @Override + public Query parse(String query) throws ParseException { + return reprocess(super.parse(query)); + } + + @Override + protected Query newFuzzyQuery(Term term, float minimumSimilarity, int prefixLength) { + return addField(super.newFuzzyQuery(term, minimumSimilarity, prefixLength), term.field()); + } + + @Override + protected Query newMatchAllDocsQuery() { + return addField(super.newMatchAllDocsQuery(), UUID.randomUUID().toString()); + } + + @Override + protected MultiPhraseQuery newMultiPhraseQuery() { + return new MultiPhraseQuery() { + private static final long serialVersionUID = 2743009696906520410L; + + @Override + public void add(Term[] terms, int position) { + super.add(terms, position); + for (Term term : terms) { + addField(this, term.field()); + } + } + }; + } + + @Override + protected PhraseQuery newPhraseQuery() { + return new PhraseQuery() { + private static final long serialVersionUID = 1927750709523859808L; + + @Override + public void add(Term term, int position) { + super.add(term, position); + addField(this, term.field()); + } + }; + } + + @Override + protected Query newPrefixQuery(Term prefix) { + return addField(super.newPrefixQuery(prefix), prefix.field()); + } + + @Override + protected Query newRangeQuery(String field, String part1, String part2, boolean inclusive) { + return addField(super.newRangeQuery(field, part1, part2, inclusive), field); + } + + @Override + protected Query newTermQuery(Term term) { + return addField(super.newTermQuery(term), term.field()); + } + + @Override + protected Query newWildcardQuery(Term t) { + if (SUPER.equals(t.field()) && "*".equals(t.text())) { + return new MatchAllDocsQuery(); + } + return addField(super.newWildcardQuery(t), t.field()); + } + + private Query reprocess(Query query) { + if (query == null || !isSuperSearch()) { + return wrapFilter(query); + } + if (query instanceof BooleanQuery) { + BooleanQuery booleanQuery = (BooleanQuery) query; + if (isSameGroupName(booleanQuery)) { + return newSuperQuery(query); + } else { + List<BooleanClause> clauses = booleanQuery.clauses(); + for (BooleanClause clause : clauses) { + clause.setQuery(reprocess(clause.getQuery())); + } + return booleanQuery; + } + } else { + return newSuperQuery(query); + } + } + + private SuperQuery newSuperQuery(Query query) { + return new SuperQuery(wrapFilter(query), scoreType); + } + + private Query wrapFilter(Query query) { + if (queryFilter == null) { + return query; + } + return new FilteredQuery(query, queryFilter); + } + + private boolean isSameGroupName(BooleanQuery booleanQuery) { + String groupName = findFirstGroupName(booleanQuery); + if (groupName == null) { + return false; + } + return isSameGroupName(booleanQuery, groupName); + } + + private boolean isSameGroupName(Query query, String groupName) { + if (query instanceof BooleanQuery) { + BooleanQuery booleanQuery = (BooleanQuery) query; + for (BooleanClause clause : booleanQuery.clauses()) { + if (!isSameGroupName(clause.getQuery(), groupName)) { + return false; + } + } + return true; + } else { + String fieldName = fieldNames.get(query); + String currentGroupName = getGroupName(fieldName); + if (groupName.equals(currentGroupName)) { + return true; + } + return false; + } + } + + private String getGroupName(String fieldName) { + if (fieldName == null) { + return null; + } + int index = fieldName.indexOf(SEP); + if (index < 0) { + return null; + } + return fieldName.substring(0, index); + } + + private String findFirstGroupName(Query query) { + if (query instanceof BooleanQuery) { + BooleanQuery booleanQuery = (BooleanQuery) query; + for (BooleanClause clause : booleanQuery.clauses()) { + return findFirstGroupName(clause.getQuery()); + } + return null; + } else { + String fieldName = fieldNames.get(query); + return getGroupName(fieldName); + } + } + + private Query addField(Query q, String field) { + fieldNames.put(q, field); + return q; + } + + public boolean isSuperSearch() { + return superSearch; + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperQuery.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperQuery.java b/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperQuery.java new file mode 100644 index 0000000..ef24626 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/lucene/search/SuperQuery.java @@ -0,0 +1,267 @@ +package org.apache.blur.lucene.search; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import java.io.IOException; + +import org.apache.blur.thrift.generated.ScoreType; +import org.apache.blur.utils.PrimeDocCache; +import org.apache.lucene.index.IndexReader; +import org.apache.lucene.search.Explanation; +import org.apache.lucene.search.Query; +import org.apache.lucene.search.Scorer; +import org.apache.lucene.search.Searcher; +import org.apache.lucene.search.Weight; +import org.apache.lucene.util.OpenBitSet; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + + +@SuppressWarnings("deprecation") +public class SuperQuery extends AbstractWrapperQuery { + + private static final long serialVersionUID = -5901574044714034398L; + private ScoreType scoreType; + + public SuperQuery(Query query, ScoreType scoreType) { + super(query, false); + this.scoreType = scoreType; + } + + public SuperQuery(Query query, ScoreType scoreType, boolean rewritten) { + super(query, rewritten); + this.scoreType = scoreType; + } + + public Object clone() { + return new SuperQuery((Query) _query.clone(), scoreType, _rewritten); + } + + public Weight createWeight(Searcher searcher) throws IOException { + Weight weight = _query.createWeight(searcher); + return new SuperWeight(weight, _query.toString(), this, scoreType); + } + + public Query rewrite(IndexReader reader) throws IOException { + if (_rewritten) { + return this; + } + return new SuperQuery(_query.rewrite(reader), scoreType, true); + } + + public String toString() { + return "super:{" + _query.toString() + "}"; + } + + public String toString(String field) { + return "super:{" + _query.toString(field) + "}"; + } + + public static class SuperWeight extends Weight { + + private static final long serialVersionUID = -4832849792097064960L; + + private Weight weight; + private String originalQueryStr; + private Query query; + private ScoreType scoreType; + + public SuperWeight(Weight weight, String originalQueryStr, Query query, ScoreType scoreType) { + this.weight = weight; + this.originalQueryStr = originalQueryStr; + this.query = query; + this.scoreType = scoreType; + } + + @Override + public Explanation explain(IndexReader reader, int doc) throws IOException { + throw new RuntimeException("not supported"); + } + + @Override + public Query getQuery() { + return query; + } + + @Override + public float getValue() { + return weight.getValue(); + } + + @Override + public void normalize(float norm) { + weight.normalize(norm); + } + + @Override + public Scorer scorer(IndexReader reader, boolean scoreDocsInOrder, boolean topScorer) throws IOException { + Scorer scorer = weight.scorer(reader, true, topScorer); + if (scorer == null) { + return null; + } + OpenBitSet primeDocBitSet = PrimeDocCache.getPrimeDocBitSet(reader); + return new SuperScorer(scorer, primeDocBitSet, originalQueryStr, scoreType); + } + + @Override + public float sumOfSquaredWeights() throws IOException { + return weight.sumOfSquaredWeights(); + } + } + + @SuppressWarnings("unused") + public static class SuperScorer extends Scorer { + + private static final Logger LOG = LoggerFactory.getLogger(SuperScorer.class); + + private static final String DOC_ID = "docId"; + private static final String NEXT_DOC = "nextDoc"; + private static final String ADVANCE = "advance"; + private static final double SUPER_POWER_CONSTANT = 2; + private static final boolean debug = false; + private Scorer scorer; + private OpenBitSet bitSet; + private int nextPrimeDoc; + private int primeDoc = -1; + private String originalQueryStr; + private ScoreType scoreType; + + private int numDocs; + private float bestScore; + private float aggregateScore; + private int hitsInEntity; + + protected SuperScorer(Scorer scorer, OpenBitSet bitSet, String originalQueryStr, ScoreType scoreType) { + super(scorer.getSimilarity()); + this.scorer = scorer; + this.bitSet = bitSet; + this.originalQueryStr = originalQueryStr; + this.scoreType = scoreType; + } + + @Override + public float score() throws IOException { + switch (scoreType) { + case AGGREGATE: + return aggregateScore; + case BEST: + return bestScore; + case CONSTANT: + return 1; + case SUPER: + double log = Math.log10(aggregateScore) + 1.0; + double avg = aggregateScore / hitsInEntity; + double pow = Math.pow(avg, SUPER_POWER_CONSTANT); + return (float) Math.pow(log + pow, 1.0 / SUPER_POWER_CONSTANT); + } + throw new RuntimeException("Unknown Score type[" + scoreType + "]"); + } + + @Override + public int docID() { + return print(DOC_ID, primeDoc); + } + + @Override + public int advance(int target) throws IOException { + if (target == NO_MORE_DOCS) { + return print(ADVANCE, primeDoc = scorer.advance(NO_MORE_DOCS)); + } + int doc = scorer.docID(); + int odoc = doc; + if (isScorerExhausted(doc)) { + return print(ADVANCE, primeDoc = doc); + } + if (target > doc || doc == -1) { + doc = scorer.advance(target); + if (isScorerExhausted(doc)) { + return print(ADVANCE, primeDoc = doc); + } + } else if (isScorerExhausted(doc)) { + return print(ADVANCE, primeDoc == -1 ? primeDoc = doc : primeDoc); + } + return print(ADVANCE, gatherAllHitsSuperDoc(doc)); + } + + private int print(String message, int i) { + if (debug) { + System.out.println(message + " [" + i + "] " + originalQueryStr); + } + return i; + } + + @Override + public int nextDoc() throws IOException { + int doc = scorer.docID(); + int odoc = doc; + if (isScorerExhausted(doc)) { + return primeDoc = doc; + } + if (doc == -1) { + doc = scorer.nextDoc(); + if (isScorerExhausted(doc)) { + return print(NEXT_DOC, primeDoc = doc); + } + } else if (isScorerExhausted(doc)) { + return print(NEXT_DOC, primeDoc == -1 ? primeDoc = doc : primeDoc); + } + + return print(NEXT_DOC, gatherAllHitsSuperDoc(doc)); + } + + private int gatherAllHitsSuperDoc(int doc) throws IOException { + reset(); + primeDoc = getPrimeDoc(doc); + nextPrimeDoc = getNextPrimeDoc(doc); + numDocs = nextPrimeDoc - primeDoc; + float currentDocScore = 0; + while (doc < nextPrimeDoc) { + currentDocScore = scorer.score(); + aggregateScore += currentDocScore; + if (currentDocScore > bestScore) { + bestScore = currentDocScore; + } + hitsInEntity++; + doc = scorer.nextDoc(); + } + return primeDoc; + } + + private void reset() { + numDocs = 0; + bestScore = 0; + aggregateScore = 0; + hitsInEntity = 0; + } + + private int getNextPrimeDoc(int doc) { + int nextSetBit = bitSet.nextSetBit(doc + 1); + return nextSetBit == -1 ? NO_MORE_DOCS : nextSetBit; + } + + private int getPrimeDoc(int doc) { + if (bitSet.fastGet(doc)) { + return doc; + } + return bitSet.prevSetBit(doc); + } + + private boolean isScorerExhausted(int doc) { + return doc == NO_MORE_DOCS ? true : false; + } + } +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/manager/BlurFilterCache.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/BlurFilterCache.java b/src/blur-core/src/main/java/org/apache/blur/manager/BlurFilterCache.java new file mode 100644 index 0000000..83f39ab --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/manager/BlurFilterCache.java @@ -0,0 +1,37 @@ +package org.apache.blur.manager; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.blur.manager.writer.BlurIndex; +import org.apache.lucene.search.Filter; + + +public abstract class BlurFilterCache { + + public abstract Filter fetchPreFilter(String table, String filterStr); + + public abstract Filter fetchPostFilter(String table, String filterStr); + + public abstract Filter storePreFilter(String table, String filterStr, Filter filter); + + public abstract Filter storePostFilter(String table, String filterStr, Filter filter); + + public abstract void closing(String table, String shard, BlurIndex index); + + public abstract void opening(String table, String shard, BlurIndex index); + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/manager/BlurPartitioner.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/BlurPartitioner.java b/src/blur-core/src/main/java/org/apache/blur/manager/BlurPartitioner.java new file mode 100644 index 0000000..9ca3a9a --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/manager/BlurPartitioner.java @@ -0,0 +1,27 @@ +package org.apache.blur.manager; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.hadoop.mapreduce.Partitioner; + +public class BlurPartitioner<BytesWritable, V> extends Partitioner<BytesWritable, V> { + + public int getPartition(BytesWritable key, V value, int numReduceTasks) { + return (key.hashCode() & Integer.MAX_VALUE) % numReduceTasks; + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/manager/BlurQueryChecker.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/BlurQueryChecker.java b/src/blur-core/src/main/java/org/apache/blur/manager/BlurQueryChecker.java new file mode 100644 index 0000000..2676d21 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/manager/BlurQueryChecker.java @@ -0,0 +1,66 @@ +package org.apache.blur.manager; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.blur.BlurConfiguration; +import org.apache.blur.log.Log; +import org.apache.blur.log.LogFactory; +import org.apache.blur.thrift.generated.BlurException; +import org.apache.blur.thrift.generated.BlurQuery; + + +import static org.apache.blur.utils.BlurConstants.*; + +public class BlurQueryChecker { + + private static final Log LOG = LogFactory.getLog(BlurQueryChecker.class); + + private int _maxQueryRowFetch; + private int _maxQueryRecordFetch; + private int _maxQueryResultsFetch; + + public BlurQueryChecker(BlurConfiguration configuration) { + _maxQueryResultsFetch = configuration.getInt(BLUR_QUERY_MAX_RESULTS_FETCH, 100); + _maxQueryRowFetch = configuration.getInt(BLUR_QUERY_MAX_ROW_FETCH, 100); + _maxQueryRecordFetch = configuration.getInt(BLUR_QUERY_MAX_RECORD_FETCH, 100); + } + + public void checkQuery(BlurQuery blurQuery) throws BlurException { + if (blurQuery.selector != null) { + if (blurQuery.selector.recordOnly) { + if (blurQuery.fetch > _maxQueryRecordFetch) { + LOG.warn("Number of records requested to be fetched [{0}] is greater than the max allowed [{1}]", _maxQueryRecordFetch); + blurQuery.fetch = (int) blurQuery.minimumNumberOfResults; + } + } else { + if (blurQuery.fetch > _maxQueryRowFetch) { + LOG.warn("Number of rows requested to be fetched [{0}] is greater than the max allowed [{1}]", _maxQueryRowFetch); + blurQuery.fetch = (int) blurQuery.minimumNumberOfResults; + } + } + } + if (blurQuery.fetch > _maxQueryResultsFetch) { + LOG.warn("Number of results requested to be fetched [{0}] is greater than the max allowed [{1}]", _maxQueryResultsFetch); + blurQuery.fetch = (int) blurQuery.minimumNumberOfResults; + } + if (blurQuery.fetch > blurQuery.minimumNumberOfResults) { + LOG.warn("Number of rows/records requested to be fetched [{0}] is greater than the minimum number of results [{1}]", blurQuery.fetch, blurQuery.minimumNumberOfResults); + blurQuery.fetch = (int) blurQuery.minimumNumberOfResults; + } + } + +} http://git-wip-us.apache.org/repos/asf/incubator-blur/blob/33df9310/src/blur-core/src/main/java/org/apache/blur/manager/DefaultBlurFilterCache.java ---------------------------------------------------------------------- diff --git a/src/blur-core/src/main/java/org/apache/blur/manager/DefaultBlurFilterCache.java b/src/blur-core/src/main/java/org/apache/blur/manager/DefaultBlurFilterCache.java new file mode 100644 index 0000000..ef46895 --- /dev/null +++ b/src/blur-core/src/main/java/org/apache/blur/manager/DefaultBlurFilterCache.java @@ -0,0 +1,54 @@ +package org.apache.blur.manager; + +/** + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +import org.apache.blur.manager.writer.BlurIndex; +import org.apache.lucene.search.Filter; + + +public class DefaultBlurFilterCache extends BlurFilterCache { + + @Override + public Filter storePreFilter(String table, String filterStr, Filter filter) { + return filter; + } + + @Override + public Filter storePostFilter(String table, String filterStr, Filter filter) { + return filter; + } + + @Override + public Filter fetchPreFilter(String table, String filterStr) { + return null; + } + + @Override + public Filter fetchPostFilter(String table, String filterStr) { + return null; + } + + @Override + public void closing(String table, String shard, BlurIndex index) { + + } + + @Override + public void opening(String table, String shard, BlurIndex index) { + + } +} \ No newline at end of file
