blob: aa0d3f2b216cea4cf01e354cae87111ddac3d205 [file] [log] [blame]
/*
* Copyright 2009-2010 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.search;
import java.nio.ByteBuffer;
import java.util.ArrayList;
import edu.uci.ics.hyracks.api.context.IHyracksCommonContext;
import edu.uci.ics.hyracks.api.dataflow.value.ITypeTraits;
import edu.uci.ics.hyracks.data.std.primitive.IntegerPointable;
import edu.uci.ics.hyracks.dataflow.common.data.accessors.ITupleReference;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeFrameTupleAccessor;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeFrameTupleAppender;
import edu.uci.ics.hyracks.storage.am.lsm.invertedindex.ondisk.FixedSizeTupleReference;
/**
* Byte-buffer backed storage for intermediate and final results of inverted-index searches.
*/
// TODO: Rename members.
public class SearchResult {
protected final ArrayList<ByteBuffer> buffers = new ArrayList<ByteBuffer>();
protected final IHyracksCommonContext ctx;
protected final FixedSizeFrameTupleAppender appender;
protected final FixedSizeFrameTupleAccessor accessor;
protected final FixedSizeTupleReference tuple;
protected final ITypeTraits[] typeTraits;
protected final int invListElementSize;
protected int currBufIdx;
protected int numResults;
public SearchResult(ITypeTraits[] invListFields, IHyracksCommonContext ctx) {
typeTraits = new ITypeTraits[invListFields.length + 1];
int tmp = 0;
for (int i = 0; i < invListFields.length; i++) {
typeTraits[i] = invListFields[i];
tmp += invListFields[i].getFixedLength();
}
invListElementSize = tmp;
// Integer for counting occurrences.
typeTraits[invListFields.length] = IntegerPointable.TYPE_TRAITS;
this.ctx = ctx;
appender = new FixedSizeFrameTupleAppender(ctx.getFrameSize(), typeTraits);
accessor = new FixedSizeFrameTupleAccessor(ctx.getFrameSize(), typeTraits);
tuple = new FixedSizeTupleReference(typeTraits);
buffers.add(ctx.allocateFrame());
}
/**
* Initialize from other search-result object to share member instances except for result buffers.
*/
public SearchResult(SearchResult other) {
this.ctx = other.ctx;
this.appender = other.appender;
this.accessor = other.accessor;
this.tuple = other.tuple;
this.typeTraits = other.typeTraits;
this.invListElementSize = other.invListElementSize;
buffers.add(ctx.allocateFrame());
}
public FixedSizeFrameTupleAccessor getAccessor() {
return accessor;
}
public FixedSizeFrameTupleAppender getAppender() {
return appender;
}
public FixedSizeTupleReference getTuple() {
return tuple;
}
public ArrayList<ByteBuffer> getBuffers() {
return buffers;
}
public void reset() {
currBufIdx = 0;
numResults = 0;
appender.reset(buffers.get(0), true);
}
public void clear() {
currBufIdx = 0;
numResults = 0;
for (ByteBuffer buffer : buffers) {
appender.reset(buffer, true);
}
}
public void append(ITupleReference invListElement, int count) {
ByteBuffer currentBuffer = buffers.get(currBufIdx);
if (!appender.hasSpace()) {
currBufIdx++;
if (currBufIdx >= buffers.size()) {
buffers.add(ctx.allocateFrame());
}
currentBuffer = buffers.get(currBufIdx);
appender.reset(currentBuffer, true);
}
// Append inverted-list element.
if (!appender.append(invListElement.getFieldData(0), invListElement.getFieldStart(0), invListElementSize)) {
throw new IllegalStateException();
}
// Append count.
if (!appender.append(count)) {
throw new IllegalStateException();
}
appender.incrementTupleCount(1);
numResults++;
}
public int getCurrentBufferIndex() {
return currBufIdx;
}
public ITypeTraits[] getTypeTraits() {
return typeTraits;
}
public int getNumResults() {
return numResults;
}
// TODO: This code may help to clean up the core list-merging algorithms.
/*
public SearchResultCursor getCursor() {
cursor.reset();
return cursor;
}
public class SearchResultCursor {
private int bufferIndex;
private int resultIndex;
private int frameResultIndex;
private ByteBuffer currentBuffer;
public void reset() {
bufferIndex = 0;
resultIndex = 0;
frameResultIndex = 0;
currentBuffer = buffers.get(0);
resultFrameTupleAcc.reset(currentBuffer);
}
public boolean hasNext() {
return resultIndex < numResults;
}
public void next() {
resultTuple.reset(currentBuffer.array(), resultFrameTupleAcc.getTupleStartOffset(frameResultIndex));
if (frameResultIndex < resultFrameTupleAcc.getTupleCount()) {
frameResultIndex++;
} else {
bufferIndex++;
currentBuffer = buffers.get(bufferIndex);
resultFrameTupleAcc.reset(currentBuffer);
frameResultIndex = 0;
}
resultIndex++;
}
public ITupleReference getTuple() {
return resultTuple;
}
}
*/
}