Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* 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 io.trino.operator.join;
import com.google.errorprone.annotations.ThreadSafe;
import com.google.errorprone.annotations.concurrent.GuardedBy;
import io.trino.annotation.NotThreadSafe;
import io.trino.spi.Page;
import io.trino.spi.PageBuilder;
import java.util.function.Supplier;
import static com.google.common.base.Preconditions.checkArgument;
import static com.google.common.base.Verify.verify;
import static java.lang.Math.toIntExact;
import static java.util.Objects.requireNonNull;
@NotThreadSafe
public final class OuterLookupSource
implements LookupSource
{
public static TrackingLookupSourceSupplier createOuterLookupSourceSupplier(Supplier lookupSourceSupplier)
{
return new OuterLookupSourceSupplier(lookupSourceSupplier);
}
private final LookupSource lookupSource;
private final OuterPositionTracker outerPositionTracker;
private OuterLookupSource(LookupSource lookupSource, OuterPositionTracker outerPositionTracker)
{
this.lookupSource = requireNonNull(lookupSource, "lookupSource is null");
this.outerPositionTracker = requireNonNull(outerPositionTracker, "outerPositionTracker is null");
}
@Override
public boolean isEmpty()
{
return lookupSource.isEmpty();
}
@Override
public long getJoinPositionCount()
{
return lookupSource.getJoinPositionCount();
}
@Override
public long getInMemorySizeInBytes()
{
return lookupSource.getInMemorySizeInBytes();
}
@Override
public long joinPositionWithinPartition(long joinPosition)
{
return lookupSource.joinPositionWithinPartition(joinPosition);
}
@Override
public long getJoinPosition(int position, Page hashChannelsPage, Page allChannelsPage, long rawHash)
{
return lookupSource.getJoinPosition(position, hashChannelsPage, allChannelsPage, rawHash);
}
@Override
public long getJoinPosition(int position, Page hashChannelsPage, Page allChannelsPage)
{
return lookupSource.getJoinPosition(position, hashChannelsPage, allChannelsPage);
}
@Override
public long getNextJoinPosition(long currentJoinPosition, int probePosition, Page allProbeChannelsPage)
{
return lookupSource.getNextJoinPosition(currentJoinPosition, probePosition, allProbeChannelsPage);
}
@Override
public boolean isJoinPositionEligible(long currentJoinPosition, int probePosition, Page allProbeChannelsPage)
{
return lookupSource.isJoinPositionEligible(currentJoinPosition, probePosition, allProbeChannelsPage);
}
@Override
public void appendTo(long position, PageBuilder pageBuilder, int outputChannelOffset)
{
lookupSource.appendTo(position, pageBuilder, outputChannelOffset);
outerPositionTracker.positionVisited(position);
}
@Override
public void close()
{
lookupSource.close();
}
@ThreadSafe
private static class SharedLookupOuterPositionIterator
implements OuterPositionIterator
{
private final LookupSource lookupSource;
private final boolean[] visitedPositions;
@GuardedBy("this")
private int currentPosition;
public SharedLookupOuterPositionIterator(LookupSource lookupSource, boolean[] visitedPositions)
{
this.lookupSource = requireNonNull(lookupSource, "lookupSource is null");
this.visitedPositions = requireNonNull(visitedPositions, "visitedPositions is null");
checkArgument(lookupSource.getJoinPositionCount() == visitedPositions.length);
}
@Override
public synchronized boolean appendToNext(PageBuilder pageBuilder, int outputChannelOffset)
{
while (currentPosition < visitedPositions.length) {
if (!visitedPositions[currentPosition]) {
lookupSource.appendTo(currentPosition, pageBuilder, outputChannelOffset);
currentPosition++;
return true;
}
currentPosition++;
}
return false;
}
}
@ThreadSafe
private static class OuterLookupSourceSupplier
implements TrackingLookupSourceSupplier
{
private final Supplier lookupSourceSupplier;
private final OuterPositionTracker outerPositionTracker;
public OuterLookupSourceSupplier(Supplier lookupSourceSupplier)
{
this.lookupSourceSupplier = requireNonNull(lookupSourceSupplier, "lookupSourceSupplier is null");
this.outerPositionTracker = new OuterPositionTracker(lookupSourceSupplier);
}
@Override
public LookupSource getLookupSource()
{
return new OuterLookupSource(lookupSourceSupplier.get(), outerPositionTracker);
}
@Override
public OuterPositionIterator getOuterPositionIterator()
{
return outerPositionTracker.getOuterPositionIterator();
}
}
@ThreadSafe
private static class OuterPositionTracker
{
private final Supplier lookupSourceSupplier;
@GuardedBy("this")
private final boolean[] visitedPositions;
@GuardedBy("this")
private boolean finished;
public OuterPositionTracker(Supplier lookupSourceSupplier)
{
this.lookupSourceSupplier = lookupSourceSupplier;
try (LookupSource lookupSource = lookupSourceSupplier.get()) {
this.visitedPositions = new boolean[toIntExact(lookupSource.getJoinPositionCount())];
}
}
public synchronized void positionVisited(long position)
{
verify(!finished);
visitedPositions[toIntExact(position)] = true;
}
public synchronized OuterPositionIterator getOuterPositionIterator()
{
finished = true;
return new SharedLookupOuterPositionIterator(lookupSourceSupplier.get(), visitedPositions);
}
}
}