/* * 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 java.util.Arrays; import java.util.List; import com.indeed.util.core.Pair; import com.indeed.flamdex.api.IntTermDocIterator; import com.indeed.flamdex.api.TermDocIterator; public class MergingIntTermDocIterator extends MergingTermDocIterator implements IntTermDocIterator { private final long[] nextTerms; private long currentTerm; @SuppressWarnings("unchecked") public MergingIntTermDocIterator(List<IntTermDocIterator> tdIters, int[] mapping, List<Integer> iterNumToDocOffset) { super((List<TermDocIterator>) (List<?>) tdIters, mapping, iterNumToDocOffset); this.nextTerms = new long[iters.size()]; currentTerm = Integer.MAX_VALUE; Arrays.fill(this.nextTerms, currentTerm); } @Override public boolean nextTerm() { /* * find smallest term from all the iterators */ /* first, update the list of next terms for all iterators */ for (int i = 0; i < nextTerms.length; i++) { if (currentTerm != nextTerms[i]) continue; IntTermDocIterator iter = (IntTermDocIterator) iters.get(i); if (iter.nextTerm()) nextTerms[i] = iter.term(); else nextTerms[i] = Integer.MAX_VALUE; } /* second find the smallest term */ long min = Integer.MAX_VALUE; for (int i = 0; i < nextTerms.length; i++) { if (nextTerms[i] == Integer.MAX_VALUE) continue; if (min > nextTerms[i]) min = nextTerms[i]; } currentTerm = min; /* check if all the iterators are done */ if (currentTerm == Integer.MAX_VALUE) return false; /* track which iterators have this terms */ itersAndOffsetsForTerm.clear(); for (int i = 0; i < nextTerms.length; i++) { if (nextTerms[i] == currentTerm) { int offset = iterNumToDocOffset.get(i); itersAndOffsetsForTerm .add(new Pair<Integer, TermDocIterator>(offset, iters.get(i))); } } return true; } @Override public int nextDocs(int[] docIdBuffer) { return fillDocIdBuffer(docIdBuffer); } @Override public long term() { return currentTerm; } }