/* * #%L * Alfresco Search Services * %% * Copyright (C) 2005 - 2020 Alfresco Software Limited * %% * This file is part of the Alfresco software. * If the software was purchased under a paid Alfresco license, the terms of * the paid license agreement will prevail. Otherwise, the software is * provided under the following open source license terms: * * Alfresco is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * Alfresco is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with Alfresco. If not, see <http://www.gnu.org/licenses/>. * #L% */ package org.alfresco.solr.query; import java.io.IOException; import java.util.stream.LongStream; import org.apache.lucene.index.LeafReaderContext; import org.apache.lucene.search.DocIdSetIterator; import org.apache.lucene.search.Scorer; import org.apache.lucene.search.Weight; import org.apache.lucene.util.FixedBitSet; import org.apache.solr.search.BitDocSet; import org.apache.solr.search.DocIterator; import org.apache.solr.search.DocSet; import org.apache.solr.search.SolrIndexSearcher; /** * @author Andy * */ public abstract class AbstractSolrCachingScorer extends Scorer { protected static class LongCache { private static int CACHE_SIZE = 1000000; private LongCache(){} static final long cache[] = LongStream.range(0, CACHE_SIZE).toArray(); } protected static Long getLong(long l) { if(l > LongCache.CACHE_SIZE) { return Long.valueOf(l); } else { return LongCache.cache[(int)l]; } } SolrCachingScorerDoIdSetIterator iterator; AbstractSolrCachingScorer(Weight weight, DocSet in, LeafReaderContext context, SolrIndexSearcher searcher) { super(weight); iterator = new SolrCachingScorerDoIdSetIterator(in, context, searcher); } @Override public float score() throws IOException { return 1.0f; } // TODO: implement @Override public int freq() throws IOException { return 1; } @Override public int docID() { return iterator.docID(); } @Override public DocIdSetIterator iterator() { return iterator; } private static class SolrCachingScorerDoIdSetIterator extends DocIdSetIterator { BitDocSet matches; int doc = -1; FixedBitSet bitSet; LeafReaderContext context; SolrCachingScorerDoIdSetIterator(DocSet in, LeafReaderContext context, SolrIndexSearcher searcher) { this.context = context; if (in instanceof BitDocSet) { matches = (BitDocSet) in; } else { this.matches = new BitDocSet(new FixedBitSet(searcher.maxDoc())); for (DocIterator it = in.iterator(); it.hasNext(); /* */) { matches.addUnique(it.nextDoc()); } } bitSet = matches.getBits(); doc = getBase() - 1; } private boolean next() { if(doc+1 < bitSet.length()) { doc = bitSet.nextSetBit(doc+1); return (doc != NO_MORE_DOCS) && (doc < (getBase() + context.reader().maxDoc())); } else { return false; } } private int getBase() { return context.docBase; } @Override public int nextDoc() throws IOException { while (next()) { return docID(); } return NO_MORE_DOCS; } @Override public int docID() { // TODO: check this expression as for next() if ((doc > -1) && (doc != NO_MORE_DOCS)) { return doc - getBase(); } return doc; } @Override public int advance(int target) throws IOException { while (next()) { final int current = docID(); if (current >= target) { return current; } } return NO_MORE_DOCS; } // TODO: implement @Override public long cost() { return 1; } } }