/* * Copyright (C) 2014 Indeed Inc. * * Licensed 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. */ package com.indeed.imhotep.local; import com.indeed.flamdex.api.DocIdStream; import com.indeed.flamdex.api.FlamdexReader; import com.indeed.flamdex.api.IntTermIterator; import com.indeed.flamdex.api.StringTermIterator; import com.indeed.util.core.Pair; import com.indeed.util.core.io.Closeables2; import com.indeed.util.core.reference.SharedReference; import java.util.Iterator; import java.util.Map; class FlamdexSubsetFTGSIterator extends AbstractFlamdexFTGSIterator { protected StringTermIterator stringTermIterator; protected IntTermIterator intTermIterator; private final DocIdStream docIdStream; private final Iterator<Map.Entry<String, long[]>> intFieldToTermsIterator; private final Iterator<Map.Entry<String, String[]>> stringFieldToTermsIterator; private long[] currentIntFieldTerms; private String[] currentStringFieldTerms; private int currentFieldTermPtr = -1; public FlamdexSubsetFTGSIterator(ImhotepLocalSession imhotepLocalSession, SharedReference<FlamdexReader> flamdexReader, Map<String, long[]> intFieldToTerms, Map<String, String[]> stringFieldToTerms) { super(imhotepLocalSession, flamdexReader); this.intFieldToTermsIterator = intFieldToTerms.entrySet().iterator(); this.stringFieldToTermsIterator = stringFieldToTerms.entrySet().iterator(); docIdStream = flamdexReader.get().getDocIdStream(); } @Override public final boolean nextField() { // todo: reset/cleanup term iterators etc that are in progress synchronized (session) { if (intFieldToTermsIterator.hasNext()) { final Map.Entry<String, long[]> entry = intFieldToTermsIterator.next(); currentField = entry.getKey(); currentIntFieldTerms = entry.getValue(); currentFieldTermPtr = -1; currentFieldIsIntType = true; if (intTermIterator != null) Closeables2.closeQuietly(intTermIterator, ImhotepLocalSession.log); intTermIterator = flamdexReader.get().getIntTermIterator(currentField); if (session.fieldZeroDocBitsets != null) { fieldZeroDocBitset = session.fieldZeroDocBitsets.get(Pair.of(currentField, currentFieldIsIntType)); } termIndex = 0; return true; } if (stringFieldToTermsIterator.hasNext()) { final Map.Entry<String, String[]> entry = stringFieldToTermsIterator.next(); currentField = entry.getKey(); currentStringFieldTerms = entry.getValue(); currentFieldTermPtr = -1; currentFieldIsIntType = false; if (stringTermIterator != null) Closeables2.closeQuietly(stringTermIterator, ImhotepLocalSession.log); stringTermIterator = flamdexReader.get().getStringTermIterator(currentField); if (session.fieldZeroDocBitsets != null) { fieldZeroDocBitset = session.fieldZeroDocBitsets.get(Pair.of(currentField, currentFieldIsIntType)); } termIndex = 0; return true; } currentField = null; close(); if (ImhotepLocalSession.logTiming) { ImhotepLocalSession.log.info("intTermsTime: "+intTermsTime/1000000d+" ms, stringTermsTime: "+stringTermsTime/1000000d+" ms, docsTime: "+docsTime/1000000d+" ms, lookupsTime: "+lookupsTime/1000000d+" ms, timingErrorTime: "+timingErrorTime/1000000d+" ms"); } return false; } } @Override public final void close() { synchronized (session) { if (docIdStream != null) { Closeables2.closeQuietly(docIdStream, ImhotepLocalSession.log); } if (intTermIterator != null) { Closeables2.closeQuietly(intTermIterator, ImhotepLocalSession.log); intTermIterator = null; } if (stringTermIterator != null) { Closeables2.closeQuietly(stringTermIterator, ImhotepLocalSession.log); stringTermIterator = null; } if (flamdexReader != null) { Closeables2.closeQuietly(flamdexReader, ImhotepLocalSession.log); flamdexReader = null; } } } @Override public final boolean nextTerm() { if (currentField == null) return false; resetGroupStats = true; if (currentFieldIsIntType) { if (ImhotepLocalSession.logTiming) intTermsTime -= System.nanoTime(); try { while (true) { if (currentFieldTermPtr + 1 >= currentIntFieldTerms.length) { return false; } currentFieldTermPtr++; intTermIterator.reset(currentIntFieldTerms[currentFieldTermPtr]); if (intTermIterator.next() && intTermIterator.term() == currentIntFieldTerms[currentFieldTermPtr]) { docIdStream.reset(intTermIterator); return true; } } } finally { if (ImhotepLocalSession.logTiming) intTermsTime += System.nanoTime(); } } else { if (ImhotepLocalSession.logTiming) stringTermsTime -= System.nanoTime(); try { while (true) { if (currentFieldTermPtr + 1 >= currentStringFieldTerms.length) { return false; } currentFieldTermPtr++; stringTermIterator.reset(currentStringFieldTerms[currentFieldTermPtr]); if (stringTermIterator.next() && stringTermIterator.term().equals(currentStringFieldTerms[currentFieldTermPtr])) { docIdStream.reset(stringTermIterator); return true; } } } finally { if (ImhotepLocalSession.logTiming) stringTermsTime += System.nanoTime(); } } } @Override public final long termDocFreq() { return currentFieldIsIntType ? intTermIterator.docFreq() : stringTermIterator.docFreq(); } @Override public final long termIntVal() { return intTermIterator.term(); } @Override public final String termStringVal() { return stringTermIterator.term(); } @Override protected int fillDocIdBuffer() { return docIdStream.fillDocIdBuffer(session.docIdBuf); } }