/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you 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 org.apache.tajo.plan.joinorder; import org.apache.commons.collections.map.LRUMap; import org.apache.tajo.plan.expr.EvalNode; import org.apache.tajo.plan.logical.JoinSpec; import org.apache.tajo.util.Pair; import java.util.Collection; import java.util.HashSet; import java.util.Set; public class JoinGraphContext { private Set<JoinVertex> rootVertexes = new HashSet<>(); // most left vertex in the join plan private JoinGraph joinGraph = new JoinGraph(); // New join edges are frequently created during join order optimization. // This cache is to reduce such overhead. private LRUMap edgeCache = new LRUMap(10000); // candidate predicates contain the predicates which are not pushed to any join nodes yet. // evaluated predicates contain the predicates which are already pushed to some join nodes. private Set<EvalNode> candidateJoinConditions = new HashSet<>(); // predicates from the on clause private Set<EvalNode> candidateJoinFilters = new HashSet<>(); // predicates from the where clause private Set<EvalNode> evaluatedJoinConditions = new HashSet<>(); // predicates from the on clause private Set<EvalNode> evaluatedJoinFilters = new HashSet<>(); // predicates from the where clause public JoinGraph getJoinGraph() { return joinGraph; } public void addCandidateJoinConditions(Collection<EvalNode> candidates) { for (EvalNode eachCandidate : candidates) { if (!evaluatedJoinConditions.contains(eachCandidate)) { candidateJoinConditions.add(eachCandidate); } } } public void addCandidateJoinFilters(Collection<EvalNode> candidates) { for (EvalNode eachCandidate : candidates) { if (!evaluatedJoinFilters.contains(eachCandidate)) { candidateJoinFilters.add(eachCandidate); } } } public void removeCandidateJoinConditions(Collection<EvalNode> willBeRemoved) { candidateJoinConditions.remove(willBeRemoved); } public void removeCandidateJoinFilters(Collection<EvalNode> willBeRemoved) { candidateJoinFilters.remove(willBeRemoved); } public void markAsEvaluatedJoinConditions(Collection<EvalNode> willBeMarked) { for (EvalNode eachEval : willBeMarked) { if (candidateJoinConditions.contains(eachEval)) { candidateJoinConditions.remove(eachEval); evaluatedJoinConditions.add(eachEval); } } } public void markAsEvaluatedJoinFilters(Collection<EvalNode> willBeMarked) { for (EvalNode eachEval : willBeMarked) { if (candidateJoinFilters.contains(eachEval)) { candidateJoinFilters.remove(eachEval); evaluatedJoinFilters.add(eachEval); } } } public Set<EvalNode> getCandidateJoinConditions() { return candidateJoinConditions; } public Set<EvalNode> getCandidateJoinFilters() { return candidateJoinFilters; } public Set<EvalNode> getEvaluatedJoinConditions() { return evaluatedJoinConditions; } public Set<EvalNode> getEvaluatedJoinFilters() { return evaluatedJoinFilters; } public Set<JoinVertex> getRootVertexes() { return rootVertexes; } public void addRootVertexes(JoinVertex rootVertex) { this.rootVertexes.add(rootVertex); } public boolean removeRootVertexes(JoinVertex rootVertex) { return this.rootVertexes.remove(rootVertex); } public void replaceRootVertexes(JoinVertex oldRoot, JoinVertex newRoot) { removeRootVertexes(oldRoot); addRootVertexes(newRoot); } public JoinEdge cacheEdge(JoinEdge edge) { edgeCache.put(new Pair<>(edge.getLeftVertex(), edge.getRightVertex()), edge); return edge; } public JoinEdge getCachedOrNewJoinEdge(JoinSpec joinSpec, JoinVertex left, JoinVertex right) { Pair<JoinVertex,JoinVertex> cacheKey = new Pair<>(left, right); if (edgeCache.containsKey(cacheKey)) { return (JoinEdge) edgeCache.get(cacheKey); } else { return cacheEdge(new JoinEdge(joinSpec, left, right)); } } public void clear() { rootVertexes.clear(); candidateJoinConditions.clear(); candidateJoinFilters.clear(); evaluatedJoinConditions.clear(); evaluatedJoinFilters.clear(); edgeCache.clear(); joinGraph.clear(); rootVertexes = null; candidateJoinConditions = null; candidateJoinFilters = null; evaluatedJoinConditions = null; evaluatedJoinFilters = null; edgeCache = null; joinGraph = null; } }