/** * 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.logical; import java.util.Arrays; import com.google.common.base.Preconditions; import com.google.gson.annotations.Expose; import org.apache.tajo.catalog.Column; import org.apache.tajo.util.StringUtils; import org.apache.tajo.util.TUtil; import static org.apache.tajo.plan.serder.PlanProto.ShuffleType; /** * ShuffeFileWriteNode is an expression for an intermediate data materialization step. */ public class ShuffleFileWriteNode extends PersistentStoreNode implements Cloneable { @Expose private ShuffleType shuffleType = ShuffleType.NONE_SHUFFLE; @Expose private int numOutputs; @Expose private Column [] shuffleKeys; public ShuffleFileWriteNode(int pid) { super(pid, NodeType.STORE); } public final int getNumOutputs() { return this.numOutputs; } public final boolean hasShuffleKeys() { return this.shuffleKeys != null; } public final Column [] getShuffleKeys() { return shuffleKeys; } public final void setShuffle(ShuffleType type, Column[] keys, int numPartitions) { Preconditions.checkArgument(keys.length >= 0, "At least one partition key must be specified."); // In outer join, zero can be passed into this value because of empty tables. // So, we should allow zero. Preconditions.checkArgument(numPartitions >= 0, "The number of partitions must be positive: %s", numPartitions); this.shuffleType = type; this.shuffleKeys = keys; this.numOutputs = numPartitions; } public ShuffleType getShuffleType() { return this.shuffleType; } @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + numOutputs; result = prime * result + Arrays.hashCode(shuffleKeys); result = prime * result + ((shuffleType == null) ? 0 : shuffleType.hashCode()); return result; } @Override public boolean equals(Object obj) { if (obj instanceof ShuffleFileWriteNode) { ShuffleFileWriteNode other = (ShuffleFileWriteNode) obj; boolean eq = super.equals(other); eq = eq && this.numOutputs == other.numOutputs; eq = eq && TUtil.checkEquals(shuffleKeys, other.shuffleKeys); return eq; } else { return false; } } @Override public Object clone() throws CloneNotSupportedException { ShuffleFileWriteNode store = (ShuffleFileWriteNode) super.clone(); store.numOutputs = numOutputs; store.shuffleKeys = shuffleKeys != null ? shuffleKeys.clone() : null; return store; } public String toString() { StringBuilder sb = new StringBuilder("Shuffle Write (type=" + shuffleType.name().toLowerCase()); if (storageType != null) { sb.append(", storage="+ storageType); } sb.append(", part number=").append(numOutputs); if (shuffleKeys != null) { sb.append(", keys: ").append(StringUtils.join(shuffleKeys)); } sb.append(")"); return sb.toString(); } }