Java tutorial
/** * diqube: Distributed Query Base. * * Copyright (C) 2015 Bastian Gloeckle * * This file is part of diqube. * * diqube is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as * published by the Free Software Foundation, either version 3 of the * License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.diqube.plan.planner; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Map.Entry; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Collectors; import org.diqube.diql.request.FunctionRequest; import org.diqube.execution.consumers.ColumnBuiltConsumer; import org.diqube.execution.consumers.GroupDeltaConsumer; import org.diqube.plan.PlannerColumnInfo; import org.diqube.plan.RemoteExecutionPlanFactory; import org.diqube.remote.cluster.thrift.RExecutionPlanStep; import org.diqube.remote.cluster.thrift.RExecutionPlanStepType; import com.google.common.collect.Iterables; /** * Manages the creation of columns on the cluster nodes. * * @author Bastian Gloeckle */ public class RemoteColumnManager implements ColumnManager<RExecutionPlanStep> { private Map<String, List<RExecutionPlanStep>> functionRemoteSteps = new HashMap<>(); private Supplier<Integer> nextRemoteStepIdSupplier; private RemoteExecutionPlanFactory remoteExecutionPlanFactory; private Map<String, PlannerColumnInfo> columnInfo; private RemoteWireManager remoteWireManager; public RemoteColumnManager(Supplier<Integer> nextRemoteStepIdSupplier, RemoteExecutionPlanFactory remoteExecutionPlanFactory, Map<String, PlannerColumnInfo> columnInfo, RemoteWireManager remoteWireManager) { this.nextRemoteStepIdSupplier = nextRemoteStepIdSupplier; this.remoteExecutionPlanFactory = remoteExecutionPlanFactory; this.columnInfo = columnInfo; this.remoteWireManager = remoteWireManager; } @Override public void produceColumn(FunctionRequest fnReq) { if (fnReq.getType().equals(FunctionRequest.Type.AGGREGATION_ROW)) { RExecutionPlanStep intermediaryStep = remoteExecutionPlanFactory .createGroupIntermediaryAggregateStep(fnReq, nextRemoteStepIdSupplier.get()); functionRemoteSteps.put(fnReq.getOutputColumn(), new ArrayList<>(Arrays.asList(new RExecutionPlanStep[] { intermediaryStep }))); } else if (fnReq.getType().equals(FunctionRequest.Type.AGGREGATION_COL)) { RExecutionPlanStep colAggStep = remoteExecutionPlanFactory.createColumnAggregateStep(fnReq, nextRemoteStepIdSupplier.get()); functionRemoteSteps.put(fnReq.getOutputColumn(), new ArrayList<>(Arrays.asList(colAggStep))); } else if (fnReq.getType().equals(FunctionRequest.Type.PROJECTION)) { RExecutionPlanStep projectStep = remoteExecutionPlanFactory.createProjectStep(fnReq, nextRemoteStepIdSupplier.get()); functionRemoteSteps.put(fnReq.getOutputColumn(), new ArrayList<>(Arrays.asList(new RExecutionPlanStep[] { projectStep }))); } else if (fnReq.getType().equals(FunctionRequest.Type.REPEATED_PROJECTION)) { RExecutionPlanStep repeatedProjectStep = remoteExecutionPlanFactory.createRepeatedProjectStep(fnReq, nextRemoteStepIdSupplier.get()); functionRemoteSteps.put(fnReq.getOutputColumn(), new ArrayList<>(Arrays.asList(new RExecutionPlanStep[] { repeatedProjectStep }))); } } @Override public void ensureColumnAvailable(String colName) { // noop in remote. } @Override public void wireOutputOfColumnIfAvailable(String colName, RExecutionPlanStep targetStep) { if (functionRemoteSteps.containsKey(colName)) { RExecutionPlanStep previousStep = Iterables.getLast(functionRemoteSteps.get(colName)); remoteWireManager.wire(ColumnBuiltConsumer.class, previousStep, targetStep); } } @Override public void wireGroupInput(RExecutionPlanStep groupStep) { // wire group step as input to all Group intermediate Aggregate functions - they need the grouping information to // execute on. functionRemoteSteps.values().stream().flatMap(v -> v.stream()).forEach(new Consumer<RExecutionPlanStep>() { @Override public void accept(RExecutionPlanStep step) { if (step.getType().equals(RExecutionPlanStepType.GROUP_INTERMEDIATE_AGGREGATE)) remoteWireManager.wire(GroupDeltaConsumer.class, groupStep, step); } }); } @Override public void prepareBuild() { // noop } @Override public List<RExecutionPlanStep> build() { // columnValuesProvidingStep is ignored. for (Entry<String, List<RExecutionPlanStep>> remoteEntry : functionRemoteSteps.entrySet()) { PlannerColumnInfo colInfo = columnInfo.get(remoteEntry.getKey()); RExecutionPlanStep inputStep = Iterables.getFirst(remoteEntry.getValue(), null); for (String prevColumnName : colInfo.getDependsOnColumns()) wireOutputOfColumnIfAvailable(prevColumnName, inputStep); } List<RExecutionPlanStep> allSteps = functionRemoteSteps.values().stream().flatMap(lst -> lst.stream()) .collect(Collectors.toList()); return allSteps; } @Override public boolean isColumnProduced(String colName) { return functionRemoteSteps.containsKey(colName); } }