/**
* 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.tez.mapreduce.partition;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.hadoop.classification.InterfaceAudience.Public;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.util.ReflectionUtils;
import org.apache.tez.common.TezRuntimeFrameworkConfigs;
import org.apache.tez.mapreduce.hadoop.MRJobConfig;
import org.apache.tez.runtime.library.api.Partitioner;
import org.apache.tez.runtime.library.common.ConfigUtils;
/**
* Provides an implementation of {@link Partitioner} that is compatible
* with Map Reduce partitioners.
*/
@SuppressWarnings({ "rawtypes", "unchecked" })
@Public
public class MRPartitioner implements org.apache.tez.runtime.library.api.Partitioner {
static final Logger LOG = LoggerFactory.getLogger(MRPartitioner.class);
private final boolean useNewApi;
private final org.apache.hadoop.mapreduce.Partitioner newPartitioner;
private final org.apache.hadoop.mapred.Partitioner oldPartitioner;
public MRPartitioner(Configuration conf) {
this.useNewApi = ConfigUtils.useNewApi(conf);
int partitions = conf.getInt(TezRuntimeFrameworkConfigs.TEZ_RUNTIME_NUM_EXPECTED_PARTITIONS, 1);
if (useNewApi) {
oldPartitioner = null;
if (partitions > 1) {
Class<? extends org.apache.hadoop.mapreduce.Partitioner<?, ?>> clazz =
(Class<? extends org.apache.hadoop.mapreduce.Partitioner<?, ?>>) conf
.getClass(MRJobConfig.PARTITIONER_CLASS_ATTR,
org.apache.hadoop.mapreduce.lib.partition.HashPartitioner.class);
LOG.info("Using newApi, MRpartitionerClass=" + clazz.getName());
newPartitioner = (org.apache.hadoop.mapreduce.Partitioner) ReflectionUtils
.newInstance(clazz, conf);
} else {
newPartitioner = new org.apache.hadoop.mapreduce.Partitioner() {
@Override
public int getPartition(Object key, Object value, int numPartitions) {
return numPartitions - 1;
}
};
}
} else {
newPartitioner = null;
if (partitions > 1) {
Class<? extends org.apache.hadoop.mapred.Partitioner> clazz =
(Class<? extends org.apache.hadoop.mapred.Partitioner>) conf.getClass(
"mapred.partitioner.class", org.apache.hadoop.mapred.lib.HashPartitioner.class);
LOG.info("Using oldApi, MRpartitionerClass=" + clazz.getName());
oldPartitioner = (org.apache.hadoop.mapred.Partitioner) ReflectionUtils.newInstance(
clazz, new JobConf(conf));
} else {
oldPartitioner = new org.apache.hadoop.mapred.Partitioner() {
@Override
public void configure(JobConf job) {
}
@Override
public int getPartition(Object key, Object value, int numPartitions) {
return numPartitions - 1;
}
};
}
}
}
@Override
public int getPartition(Object key, Object value, int numPartitions) {
if (useNewApi) {
return newPartitioner.getPartition(key, value, numPartitions);
} else {
return oldPartitioner.getPartition(key, value, numPartitions);
}
}
}