Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * 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;
 
 
 import java.util.List;
 
 import static com.facebook.presto.spi.type.BigintType.BIGINT;
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 import static com.google.common.base.Preconditions.checkState;
 
 public class UnnestOperator
         implements Operator
 {
     public static class UnnestOperatorFactory
             implements OperatorFactory
     {
         private final int operatorId;
         private final List<IntegerreplicateChannels;
         private final List<TypereplicateTypes;
         private final List<IntegerunnestChannels;
         private final List<TypeunnestTypes;
         private final boolean withOrdinality;
         private boolean closed;
         private final ImmutableList<Typetypes;
 
         public UnnestOperatorFactory(int operatorIdList<IntegerreplicateChannelsList<TypereplicateTypesList<IntegerunnestChannelsList<TypeunnestTypesboolean withOrdinality)
         {
             this. = operatorId;
             this. = ImmutableList.copyOf(checkNotNull(replicateChannels"replicateChannels is null"));
             this. = ImmutableList.copyOf(checkNotNull(replicateTypes"replicateTypes is null"));
             checkArgument(replicateChannels.size() == replicateTypes.size(), "replicateChannels and replicateTypes do not match");
             this. = ImmutableList.copyOf(checkNotNull(unnestChannels"unnestChannels is null"));
             this. = ImmutableList.copyOf(checkNotNull(unnestTypes"unnestTypes is null"));
             checkArgument(unnestChannels.size() == unnestTypes.size(), "unnestChannels and unnestTypes do not match");
             this. = withOrdinality;
             ImmutableList.Builder<TypetypesBuilder = ImmutableList.<Type>builder()
                     .addAll(replicateTypes)
                     .addAll(getUnnestedTypes(unnestTypes));
             if (withOrdinality) {
                 typesBuilder.add();
             }
             this. = typesBuilder.build();
         }
 
         @Override
         public List<TypegetTypes()
         {
             return ;
         }
 
         @Override
         public Operator createOperator(DriverContext driverContext)
         {
             checkState(!"Factory is already closed");
             OperatorContext operatorContext = driverContext.addOperatorContext(UnnestOperator.class.getSimpleName());
             return new UnnestOperator(operatorContext);
         }
 
         @Override
         public void close()
         {
              = true;
         }
     }
 
     private final OperatorContext operatorContext;
     private final List<IntegerreplicateChannels;
     private final List<TypereplicateTypes;
     private final List<IntegerunnestChannels;
     private final List<TypeunnestTypes;
     private final boolean withOrdinality;
     private final List<TypeoutputTypes;
     private final PageBuilder pageBuilder;
     private final List<Unnesterunnesters;
     private boolean finishing;
     private Page currentPage;
     private int currentPosition;
     private int ordinalityCount;
    public UnnestOperator(OperatorContext operatorContextList<IntegerreplicateChannelsList<TypereplicateTypesList<IntegerunnestChannelsList<TypeunnestTypesboolean withOrdinality)
    {
        this. = checkNotNull(operatorContext"operatorContext is null");
        this. = ImmutableList.copyOf(checkNotNull(replicateChannels"replicateChannels is null"));
        this. = ImmutableList.copyOf(checkNotNull(replicateTypes"replicateTypes is null"));
        this. = ImmutableList.copyOf(checkNotNull(unnestChannels"unnestChannels is null"));
        this. = ImmutableList.copyOf(checkNotNull(unnestTypes"unnestTypes is null"));
        this. = withOrdinality;
        checkArgument(replicateChannels.size() == replicateTypes.size(), "replicate channels or types has wrong size");
        checkArgument(unnestChannels.size() == unnestTypes.size(), "unnest channels or types has wrong size");
        ImmutableList.Builder<TypeoutputTypesBuilder = ImmutableList.<Type>builder()
                .addAll(replicateTypes)
                .addAll(getUnnestedTypes(unnestTypes));
        if (withOrdinality) {
            outputTypesBuilder.add();
        }
        this. = outputTypesBuilder.build();
        this. = new PageBuilder();
        this. = new ArrayList<>();
    }
    private static List<TypegetUnnestedTypes(List<Typetypes)
    {
        ImmutableList.Builder<Typebuilder = ImmutableList.builder();
        for (Type type : types) {
            checkArgument(type instanceof ArrayType || type instanceof MapType"Can only unnest map and array types");
            builder.addAll(type.getTypeParameters());
        }
        return builder.build();
    }
    @Override
    {
        return ;
    }
    @Override
    public final List<TypegetTypes()
    {
        return ;
    }
    @Override
    public void finish()
    {
         = true;
    }
    @Override
    public boolean isFinished()
    {
        return  && .isEmpty() &&  == null;
    }
    @Override
    public boolean needsInput()
    {
        return ! && !.isFull() &&  == null;
    }
    @Override
    public void addInput(Page page)
    {
        checkState(!"Operator is already finishing");
        checkNotNull(page"page is null");
        checkState( == null"currentPage is not null");
        checkState(!.isFull(), "Page buffer is full");
         = page;
         = 0;
        initializeUnnesters();
    }
    private void initializeUnnesters()
    {
        .clear();
        for (int i = 0; i < .size(); i++) {
            Type type = .get(i);
            int channel = .get(i);
            Slice slice = null;
            if (!.getBlock(channel).isNull()) {
                slice = type.getSlice(.getBlock(channel), );
            }
            if (type instanceof ArrayType) {
                .add(new ArrayUnnester((ArrayTypetypeslice));
            }
            else if (type instanceof MapType) {
                .add(new MapUnnester((MapTypetypeslice));
            }
            else {
                throw new IllegalArgumentException("Cannot unnest type: " + type);
            }
        }
         = 0;
    }
    private boolean anyUnnesterHasData()
    {
        for (Unnester unnester : ) {
            if (unnester.hasNext()) {
                return true;
            }
        }
        return false;
    }
    @Override
    public Page getOutput()
    {
        while (!.isFull() &&  != null) {
            // Advance until we find data to unnest
            while (!anyUnnesterHasData()) {
                ++;
                if ( == .getPositionCount()) {
                     = null;
                     = 0;
                    break;
                }
                initializeUnnesters();
            }
            while (!.isFull() && anyUnnesterHasData()) {
                // Copy all the channels marked for replication
                for (int replicateChannel = 0; replicateChannel < .size(); replicateChannel++) {
                    Type type = .get(replicateChannel);
                    int channel = .get(replicateChannel);
                    type.appendTo(.getBlock(channel), .getBlockBuilder(replicateChannel));
                }
                int offset = .size();
                .declarePosition();
                for (Unnester unnester : ) {
                    if (unnester.hasNext()) {
                        unnester.appendNext(offset);
                    }
                    else {
                        for (int unnesterChannelIndex = 0; unnesterChannelIndex < unnester.getChannelCount(); unnesterChannelIndex++) {
                            .getBlockBuilder(offset + unnesterChannelIndex).appendNull();
                        }
                    }
                    offset += unnester.getChannelCount();
                }
                if () {
                    ++;
                    .writeLong(.getBlockBuilder(offset), );
                }
            }
        }
        if ((! && !.isFull()) || .isEmpty()) {
            return null;
        }
        Page page = .build();
        .reset();
        return page;
    }
New to GrepCode? Check out our FAQ X