blob: b41b0d1b5375a33a311c53868ba76e0940ac1734 [file] [log] [blame]
/*
* Copyright 2009-2012 by The Regents of the University of California
* 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 from
*
* 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 edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk;
import edu.uci.ics.hyracks.api.exceptions.HyracksDataException;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.btree.impls.BTree;
import edu.uci.ics.hyracks.storage.am.btree.impls.RangePredicate;
import edu.uci.ics.hyracks.storage.am.common.api.ICursorInitialState;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexAccessor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexCursor;
import edu.uci.ics.hyracks.storage.am.common.api.IIndexOperationContext;
import edu.uci.ics.hyracks.storage.am.common.api.ISearchPredicate;
import edu.uci.ics.hyracks.storage.am.common.api.IndexException;
import edu.uci.ics.hyracks.storage.am.common.impls.NoOpOperationCallback;
import edu.uci.ics.hyracks.storage.am.common.tuples.ConcatenatingTupleReference;
import edu.uci.ics.hyracks.storage.am.common.tuples.PermutingTupleReference;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.api.IInvertedIndex;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.api.IInvertedListCursor;
/**
* Scans a range of tokens, returning tuples containing a token and an inverted-list element.
*/
public class OnDiskInvertedIndexRangeSearchCursor implements IIndexCursor {
private final BTree btree;
private final IIndexAccessor btreeAccessor;
private final IInvertedIndex invIndex;
private final IIndexOperationContext opCtx;
private final IInvertedListCursor invListCursor;
private boolean unpinNeeded;
private final IIndexCursor btreeCursor;
private RangePredicate btreePred;
private final PermutingTupleReference tokenTuple;
private ConcatenatingTupleReference concatTuple;
public OnDiskInvertedIndexRangeSearchCursor(IInvertedIndex invIndex, IIndexOperationContext opCtx) {
this.btree = ((OnDiskInvertedIndex) invIndex).getBTree();
this.btreeAccessor = btree.createAccessor(NoOpOperationCallback.INSTANCE, NoOpOperationCallback.INSTANCE);
this.invIndex = invIndex;
this.opCtx = opCtx;
// Project away non-token fields of the BTree tuples.
int[] fieldPermutation = new int[invIndex.getTokenTypeTraits().length];
for (int i = 0; i < invIndex.getTokenTypeTraits().length; i++) {
fieldPermutation[i] = i;
}
tokenTuple = new PermutingTupleReference(fieldPermutation);
btreeCursor = btreeAccessor.createSearchCursor();
concatTuple = new ConcatenatingTupleReference(2);
invListCursor = invIndex.createInvertedListCursor();
unpinNeeded = false;
}
@Override
public void open(ICursorInitialState initialState, ISearchPredicate searchPred) throws HyracksDataException, IndexException {
this.btreePred = (RangePredicate) searchPred;
try {
btreeAccessor.search(btreeCursor, btreePred);
} catch (IndexException e) {
throw new HyracksDataException(e);
}
invListCursor.pinPages();
unpinNeeded = true;
}
@Override
public boolean hasNext() throws HyracksDataException, IndexException {
if (invListCursor.hasNext()) {
return true;
}
if (unpinNeeded) {
invListCursor.unpinPages();
unpinNeeded = false;
}
if (!btreeCursor.hasNext()) {
return false;
}
btreeCursor.next();
tokenTuple.reset(btreeCursor.getTuple());
try {
invIndex.openInvertedListCursor(invListCursor, tokenTuple, opCtx);
} catch (IndexException e) {
throw new HyracksDataException(e);
}
invListCursor.pinPages();
invListCursor.hasNext();
unpinNeeded = true;
concatTuple.reset();
concatTuple.addTuple(tokenTuple);
return true;
}
@Override
public void next() throws HyracksDataException {
invListCursor.next();
if (concatTuple.hasMaxTuples()) {
concatTuple.removeLastTuple();
}
concatTuple.addTuple(invListCursor.getTuple());
}
@Override
public void close() throws HyracksDataException {
if (unpinNeeded) {
invListCursor.unpinPages();
unpinNeeded = false;
}
btreeCursor.close();
}
@Override
public void reset() throws HyracksDataException, IndexException {
if (unpinNeeded) {
invListCursor.unpinPages();
unpinNeeded = false;
}
btreeCursor.close();
}
@Override
public ITupleReference getTuple() {
return concatTuple;
}
}