/*
* 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.facebook.presto.operator.index;
import com.facebook.presto.operator.LookupSource;
import com.facebook.presto.spi.Page;
import com.facebook.presto.spi.PageBuilder;
import com.facebook.presto.spi.block.Block;
import javax.annotation.concurrent.NotThreadSafe;
import static com.facebook.presto.operator.index.IndexSnapshot.UNLOADED_INDEX_KEY;
import static com.google.common.base.Preconditions.checkState;
import static java.util.Objects.requireNonNull;
@NotThreadSafe
public class IndexLookupSource
implements LookupSource
{
private final IndexLoader indexLoader;
private IndexedData indexedData;
public IndexLookupSource(IndexLoader indexLoader)
{
this.indexLoader = requireNonNull(indexLoader, "indexLoader is null");
this.indexedData = indexLoader.getIndexSnapshot();
}
@Override
public int getChannelCount()
{
return indexLoader.getChannelCount();
}
@Override
public int getJoinPositionCount()
{
throw new UnsupportedOperationException("Index can not be used in a RIGHT or FULL outer join");
}
@Override
public long getInMemorySizeInBytes()
{
return 0;
}
@Override
public long getJoinPosition(int position, Page hashChannelsPage, Page allChannelsPage, long rawHash)
{
// TODO update to take advantage of precomputed hash
return getJoinPosition(position, hashChannelsPage, allChannelsPage);
}
@Override
public long getJoinPosition(int position, Page hashChannelsPage, Page allChannelsPage)
{
Block[] blocks = hashChannelsPage.getBlocks();
long joinPosition = indexedData.getJoinPosition(position, hashChannelsPage);
if (joinPosition == UNLOADED_INDEX_KEY) {
indexedData.close(); // Close out the old indexedData
indexedData = indexLoader.getIndexedDataForKeys(position, blocks);
joinPosition = indexedData.getJoinPosition(position, hashChannelsPage);
checkState(joinPosition != UNLOADED_INDEX_KEY);
}
// INVARIANT: position is -1 or a valid position greater than or equal to zero
return joinPosition;
}
@Override
public long getNextJoinPosition(long currentJoinPosition, int probePosition, Page allProbeChannelsPage)
{
long nextPosition = indexedData.getNextJoinPosition(currentJoinPosition);
checkState(nextPosition != UNLOADED_INDEX_KEY);
// INVARIANT: currentPosition is -1 or a valid currentPosition greater than or equal to zero
return nextPosition;
}
@Override
public boolean isJoinPositionEligible(long currentJoinPosition, int probePosition, Page allProbeChannelsPage)
{
return true;
}
@Override
public void appendTo(long position, PageBuilder pageBuilder, int outputChannelOffset)
{
indexedData.appendTo(position, pageBuilder, outputChannelOffset);
}
@Override
public void close()
{
indexedData.close();
}
}