blob: 3e6e6bf9f1a4225c5cec3707fe8e868bd399b1a6 [file] [log] [blame]
/**
* 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.engine.planner.global;
import com.google.common.base.Preconditions;
import org.apache.tajo.BuiltinStorages;
import org.apache.tajo.ExecutionBlockId;
import org.apache.tajo.catalog.Column;
import org.apache.tajo.catalog.Schema;
import org.apache.tajo.catalog.SchemaFactory;
import org.apache.tajo.catalog.SchemaUtil;
import org.apache.tajo.util.StringUtils;
import static org.apache.tajo.plan.serder.PlanProto.DataChannelProto;
import static org.apache.tajo.plan.serder.PlanProto.ShuffleType;
import static org.apache.tajo.plan.serder.PlanProto.TransmitType;
public class DataChannel {
private ExecutionBlockId srcId;
private ExecutionBlockId targetId;
private TransmitType transmitType = TransmitType.PULL_TRANSMIT;
private ShuffleType shuffleType;
private Integer numOutputs = 1;
private Column[] shuffleKeys;
private Schema schema;
private String dataFormat = BuiltinStorages.RAW;
public DataChannel(ExecutionBlockId srcId, ExecutionBlockId targetId) {
this.srcId = srcId;
this.targetId = targetId;
}
public DataChannel(ExecutionBlockId srcId, ExecutionBlockId targetId, ShuffleType shuffleType) {
this(srcId, targetId);
this.shuffleType = shuffleType;
}
public DataChannel(ExecutionBlock src, ExecutionBlock target, ShuffleType shuffleType, int numOutput) {
this(src.getId(), target.getId(), shuffleType, numOutput);
setSchema(src.getPlan().getOutSchema());
}
public DataChannel(ExecutionBlockId srcId, ExecutionBlockId targetId, ShuffleType shuffleType, int numOutputs) {
this(srcId, targetId, shuffleType);
this.numOutputs = numOutputs;
}
public DataChannel(DataChannelProto proto) {
this.srcId = new ExecutionBlockId(proto.getSrcId());
this.targetId = new ExecutionBlockId(proto.getTargetId());
this.transmitType = proto.getTransmitType();
this.shuffleType = proto.getShuffleType();
if (proto.hasSchema()) {
this.setSchema(SchemaFactory.newV1(proto.getSchema()));
}
if (proto.getShuffleKeysCount() > 0) {
shuffleKeys = new Column[proto.getShuffleKeysCount()];
for (int i = 0; i < proto.getShuffleKeysCount(); i++) {
shuffleKeys[i] = new Column(proto.getShuffleKeys(i));
}
} else {
shuffleKeys = new Column[] {};
}
if (proto.hasNumOutputs()) {
this.numOutputs = proto.getNumOutputs();
}
if (proto.hasDataFormat()) {
this.dataFormat = proto.getDataFormat();
}
}
public ExecutionBlockId getSrcId() {
return srcId;
}
public ExecutionBlockId getTargetId() {
return targetId;
}
public ShuffleType getShuffleType() {
return shuffleType;
}
public boolean isHashShuffle() {
return shuffleType == ShuffleType.HASH_SHUFFLE || shuffleType == ShuffleType.SCATTERED_HASH_SHUFFLE;
}
public boolean isRangeShuffle() {
return shuffleType == ShuffleType.RANGE_SHUFFLE;
}
public boolean needShuffle() {
return shuffleType != ShuffleType.NONE_SHUFFLE;
}
public TransmitType getTransmitType() {
return this.transmitType;
}
public void setTransmitType(TransmitType transmitType) {
this.transmitType = transmitType;
}
public void setShuffle(ShuffleType shuffleType, Column[] keys, int numOutputs) {
Preconditions.checkArgument(keys.length >= 0, "At least one shuffle key must be specified.");
Preconditions.checkArgument(numOutputs > 0, "The number of outputs must be positive: %s", numOutputs);
this.shuffleType = shuffleType;
this.shuffleKeys = keys;
this.numOutputs = numOutputs;
}
public void setShuffleType(ShuffleType shuffleType) {
this.shuffleType = shuffleType;
}
public boolean hasShuffleKeys() {
return shuffleKeys != null;
}
public void setShuffleKeys(Column[] key) {
this.shuffleKeys = key;
}
public Column [] getShuffleKeys() {
return this.shuffleKeys;
}
public void setShuffleOutputNum(int partNum) {
this.numOutputs = partNum;
}
public int getShuffleOutputNum() {
return numOutputs;
}
public boolean hasDataFormat() {
return this.dataFormat != null;
}
public void setDataFormat(String dataFormat) {
this.dataFormat = dataFormat;
}
public String getDataFormat() {
return dataFormat;
}
public DataChannelProto getProto() {
DataChannelProto.Builder builder = DataChannelProto.newBuilder();
builder.setSrcId(srcId.getProto());
builder.setTargetId(targetId.getProto());
if (transmitType != null) {
builder.setTransmitType(transmitType);
}
builder.setShuffleType(shuffleType);
if (schema != null) {
builder.setSchema(schema.getProto());
}
if (shuffleKeys != null) {
for (Column column : shuffleKeys) {
builder.addShuffleKeys(column.getProto());
}
}
if (numOutputs != null) {
builder.setNumOutputs(numOutputs);
}
if(dataFormat != null){
builder.setDataFormat(dataFormat);
}
return builder.build();
}
public void setSchema(Schema schema) {
this.schema = SchemaUtil.clone(schema);
}
public Schema getSchema() {
return schema;
}
public String toString() {
StringBuilder sb = new StringBuilder();
sb.append("[").append(srcId.getQueryId()).append("] ");
sb.append(srcId.getId()).append(" => ").append(targetId.getId());
sb.append(" (type=").append(shuffleType);
if (hasShuffleKeys()) {
sb.append(", key=");
sb.append(StringUtils.join(shuffleKeys));
sb.append(", num=").append(numOutputs);
}
sb.append(")");
return sb.toString();
}
}