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.sql.planner.optimizations;
 
 
 import java.util.List;
 import java.util.Map;
 
 import static com.google.common.base.Preconditions.checkArgument;
 import static com.google.common.base.Preconditions.checkNotNull;
 
 public class HashGenerationOptimizer
         extends PlanOptimizer
 {
     public static final int INITIAL_HASH_VALUE = 0;
     private static final String HASH_CODE = FunctionRegistry.mangleOperatorName("HASH_CODE");
     private final boolean optimizeHashGeneration;
 
     public HashGenerationOptimizer(boolean optimizeHashGeneration)
     {
         this. = optimizeHashGeneration;
     }
 
     @Override
     public PlanNode optimize(PlanNode planSession sessionMap<SymbolTypetypesSymbolAllocator symbolAllocatorPlanNodeIdAllocator idAllocator)
     {
         checkNotNull(plan"plan is null");
         checkNotNull(session"session is null");
         checkNotNull(types"types is null");
         checkNotNull(symbolAllocator"symbolAllocator is null");
         checkNotNull(idAllocator"idAllocator is null");
         if (SystemSessionProperties.isOptimizeHashGenerationEnabled(session)) {
             return PlanRewriter.rewriteWith(new Rewriter(idAllocatorsymbolAllocator), plannull);
         }
         return plan;
     }
 
     private static class Rewriter
             extends PlanRewriter<Void>
     {
         private final PlanNodeIdAllocator idAllocator;
         private final SymbolAllocator symbolAllocator;
 
         private Rewriter(PlanNodeIdAllocator idAllocatorSymbolAllocator symbolAllocator)
         {
             this. = checkNotNull(idAllocator"idAllocator is null");
             this. = checkNotNull(symbolAllocator"symbolAllocator is null");
         }
 
         @Override
         public PlanNode visitAggregation(AggregationNode nodeRewriteContext<Voidcontext)
         {
             PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
             if (rewrittenSource == node.getSource() && node.getGroupBy().isEmpty()) {
                 return node;
             }
             if (node.getGroupBy().isEmpty()) {
                return new AggregationNode(.getNextId(),
                        rewrittenSource,
                        node.getGroupBy(),
                        node.getAggregations(),
                        node.getFunctions(),
                        node.getMasks(),
                        node.getSampleWeight(),
                        node.getConfidence(),
                        Optional.empty());
            }
            Symbol hashSymbol = .newHashSymbol();
            PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getGroupBy());
            return new AggregationNode(.getNextId(),
                    hashProjectNode,
                    node.getGroupBy(),
                    node.getAggregations(),
                    node.getFunctions(),
                    node.getMasks(),
                    node.getSampleWeight(),
                    node.getConfidence(),
                    Optional.of(hashSymbol));
        }
        @Override
        public PlanNode visitDistinctLimit(DistinctLimitNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            Symbol hashSymbol = .newHashSymbol();
            PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getOutputSymbols());
            return new DistinctLimitNode(.getNextId(), hashProjectNodenode.getLimit(), Optional.of(hashSymbol));
        }
        @Override
        public PlanNode visitMarkDistinct(MarkDistinctNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            Symbol hashSymbol = .newHashSymbol();
            PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getDistinctSymbols());
            return new MarkDistinctNode(.getNextId(), hashProjectNodenode.getMarkerSymbol(), node.getDistinctSymbols(), Optional.of(hashSymbol));
        }
        @Override
        public PlanNode visitRowNumber(RowNumberNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            if (rewrittenSource == node.getSource() && node.getPartitionBy().isEmpty()) {
                return node;
            }
            if (!node.getPartitionBy().isEmpty()) {
                Symbol hashSymbol = .newHashSymbol();
                PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getPartitionBy());
                return new RowNumberNode(.getNextId(), hashProjectNodenode.getPartitionBy(), node.getRowNumberSymbol(), node.getMaxRowCountPerPartition(), Optional.of(hashSymbol));
            }
            return new RowNumberNode(.getNextId(), rewrittenSourcenode.getPartitionBy(), node.getRowNumberSymbol(), node.getMaxRowCountPerPartition(), node.getHashSymbol());
        }
        @Override
        public PlanNode visitTopNRowNumber(TopNRowNumberNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            if (rewrittenSource == node.getSource() && node.getPartitionBy().isEmpty()) {
                return node;
            }
            if (node.getPartitionBy().isEmpty()) {
                return new TopNRowNumberNode(.getNextId(),
                        rewrittenSource,
                        node.getPartitionBy(),
                        node.getOrderBy(),
                        node.getOrderings(),
                        node.getRowNumberSymbol(),
                        node.getMaxRowCountPerPartition(),
                        node.isPartial(),
                        node.getHashSymbol());
            }
            Symbol hashSymbol = .newHashSymbol();
            PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getPartitionBy());
            return new TopNRowNumberNode(.getNextId(),
                    hashProjectNode,
                    node.getPartitionBy(),
                    node.getOrderBy(),
                    node.getOrderings(),
                    node.getRowNumberSymbol(),
                    node.getMaxRowCountPerPartition(),
                    node.isPartial(),
                    Optional.of(hashSymbol));
        }
        @Override
        public PlanNode visitJoin(JoinNode nodeRewriteContext<Voidcontext)
        {
            List<JoinNode.EquiJoinClauseclauses = node.getCriteria();
            List<SymbolleftSymbols = Lists.transform(clauses, JoinNode.EquiJoinClause::getLeft);
            List<SymbolrightSymbols = Lists.transform(clauses, JoinNode.EquiJoinClause::getRight);
            PlanNode rewrittenLeft = context.rewrite(node.getLeft(), null);
            PlanNode rewrittenRight = context.rewrite(node.getRight(), null);
            Symbol leftHashSymbol = .newHashSymbol();
            Symbol rightHashSymbol = .newHashSymbol();
            PlanNode leftHashProjectNode = getHashProjectNode(rewrittenLeftleftHashSymbolleftSymbols);
            PlanNode rightHashProjectNode = getHashProjectNode(rewrittenRightrightHashSymbolrightSymbols);
            return new JoinNode(.getNextId(), node.getType(), leftHashProjectNoderightHashProjectNodenode.getCriteria(), Optional.of(leftHashSymbol), Optional.of(rightHashSymbol));
        }
        @Override
        public PlanNode visitSemiJoin(SemiJoinNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            PlanNode rewrittenFilteringSource = context.rewrite(node.getFilteringSource(), null);
            Symbol sourceHashSymbol = .newHashSymbol();
            Symbol filteringSourceHashSymbol = .newHashSymbol();
            PlanNode sourceHashProjectNode = getHashProjectNode(rewrittenSourcesourceHashSymbol, ImmutableList.of(node.getSourceJoinSymbol()));
            PlanNode filteringSourceHashProjectNode = getHashProjectNode(rewrittenFilteringSourcefilteringSourceHashSymbol, ImmutableList.of(node.getFilteringSourceJoinSymbol()));
            return new SemiJoinNode(.getNextId(),
                    sourceHashProjectNode,
                    filteringSourceHashProjectNode,
                    node.getSourceJoinSymbol(),
                    node.getFilteringSourceJoinSymbol(),
                    node.getSemiJoinOutput(),
                    Optional.of(sourceHashSymbol),
                    Optional.of(filteringSourceHashSymbol));
        }
        @Override
        public PlanNode visitIndexJoin(IndexJoinNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenIndex = context.rewrite(node.getIndexSource(), null);
            PlanNode rewrittenProbe = context.rewrite(node.getProbeSource(), null);
            Symbol indexHashSymbol = .newHashSymbol();
            Symbol probeHashSymbol = .newHashSymbol();
            List<IndexJoinNode.EquiJoinClauseclauses = node.getCriteria();
            List<SymbolindexSymbols = Lists.transform(clauses, IndexJoinNode.EquiJoinClause::getIndex);
            List<SymbolprobeSymbols = Lists.transform(clauses, IndexJoinNode.EquiJoinClause::getProbe);
            PlanNode indexHashProjectNode = getHashProjectNode(rewrittenIndexindexHashSymbolindexSymbols);
            PlanNode probeHashProjectNode = getHashProjectNode(rewrittenProbeprobeHashSymbolprobeSymbols);
            return new IndexJoinNode(.getNextId(),
                    node.getType(),
                    probeHashProjectNode,
                    indexHashProjectNode,
                    node.getCriteria(),
                    Optional.of(probeHashSymbol),
                    Optional.of(indexHashSymbol));
        }
        @Override
        public PlanNode visitWindow(WindowNode nodeRewriteContext<Voidcontext)
        {
            PlanNode rewrittenSource = context.rewrite(node.getSource(), null);
            if (rewrittenSource == node.getSource() && node.getPartitionBy().isEmpty()) {
                return node;
            }
            if (node.getPartitionBy().isEmpty()) {
                return new WindowNode(.getNextId(),
                        rewrittenSource,
                        node.getPartitionBy(),
                        node.getOrderBy(),
                        node.getOrderings(),
                        node.getFrame(),
                        node.getWindowFunctions(),
                        node.getSignatures(),
                        Optional.empty());
            }
            Symbol hashSymbol = .newHashSymbol();
            PlanNode hashProjectNode = getHashProjectNode(rewrittenSourcehashSymbolnode.getPartitionBy());
            return new WindowNode(.getNextId(),
                    hashProjectNode,
                    node.getPartitionBy(),
                    node.getOrderBy(),
                    node.getOrderings(),
                    node.getFrame(),
                    node.getWindowFunctions(),
                    node.getSignatures(),
                    Optional.of(hashSymbol));
        }
    }
    private static ProjectNode getHashProjectNode(PlanNodeIdAllocator idAllocatorPlanNode sourceSymbol hashSymbolList<SymbolpartitioningSymbols)
    {
        checkArgument(!partitioningSymbols.isEmpty(), "partitioningSymbols is empty");
        ImmutableMap.Builder<SymbolExpressionoutputSymbols = ImmutableMap.builder();
        for (Symbol symbol : source.getOutputSymbols()) {
            Expression expression = new QualifiedNameReference(symbol.toQualifiedName());
            outputSymbols.put(symbolexpression);
        }
        Expression hashExpression = getHashExpression(partitioningSymbols);
        outputSymbols.put(hashSymbolhashExpression);
        return new ProjectNode(idAllocator.getNextId(), sourceoutputSymbols.build());
    }
    private static Expression getHashExpression(List<SymbolpartitioningSymbols)
    {
        Expression hashExpression = new LongLiteral(String.valueOf());
        for (Symbol symbol : partitioningSymbols) {
            hashExpression = getHashFunctionCall(hashExpressionsymbol);
        }
        return hashExpression;
    }
    private static Expression getHashFunctionCall(Expression previousHashValueSymbol symbol)
    {
        FunctionCall functionCall = new FunctionCall(QualifiedName.of(), Optional.<Window>empty(), false, ImmutableList.<Expression>of(new QualifiedNameReference(symbol.toQualifiedName())));
        List<Expressionarguments = ImmutableList.of(previousHashValueorNullHashCode(functionCall));
        return new FunctionCall(QualifiedName.of("combine_hash"), arguments);
    }
    private static Expression orNullHashCode(Expression expression)
    {
        return new CoalesceExpression(expressionnew LongLiteral(String.valueOf(.)));
    }
New to GrepCode? Check out our FAQ X