/* 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 com.alimama.quanjingmonitor.kmeans;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.PriorityQueue;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;
public class KMeansClusterCombiner extends Reducer<Text, Text, Text, Text> {
private final Collection<Cluster> clusters = new ArrayList<Cluster>();
private Map<String, Cluster> clusterMap;
int rep=2;
private void setClusterMap(Collection<Cluster> clusters) {
clusterMap = new HashMap<String, Cluster>();
for (Cluster cluster : clusters) {
clusterMap.put(String.valueOf(cluster.getId()), cluster);
}
clusters.clear();
}
@Override
protected void setup(Context context) throws IOException,
InterruptedException {
super.setup(context);
this.clusters.clear();
Configuration conf = context.getConfiguration();
this.rep=conf.getInt(KMeansDriver.CLUSTER_CONVERGENCE_ABTEST_REP, 2);
try {
String clusterPath = conf.get(KMeansDriver.CLUSTER_PATH_KEY);
if (clusterPath != null && clusterPath.length() > 0) {
KmeansPublic.configureWithClusterInfo(conf, new Path(clusterPath), clusters);
if (clusters.isEmpty()) {
throw new IllegalStateException(
"No clusters found. Check your -c path.");
}
this.setClusterMap(clusters);
}
} catch (Throwable e) {
throw new IllegalStateException(e);
}
}
Comparator<Text> cmp=new Comparator<Text>() {
@Override
public int compare(Text o1, Text o2) {
String[] cols1=o1.toString().split("@abtest@");
String[] cols2=o2.toString().split("@abtest@");
double t1=Double.parseDouble(cols1[0]);
double t2=Double.parseDouble(cols2[0]);
return t1 == t2 ? 0 : t1 > t2 ? 1 : -1;
}
};
@Override
protected void reduce(Text key, Iterable<Text> values, Context context)
throws IOException, InterruptedException {
Cluster clu=clusterMap.get(key.toString());
int limit=1;
if(clu!=null)
{
limit=Math.min(clu.getNumselect()*this.rep*10, 50000);
}
if(limit<1000)
{
limit=1000;
}
PriorityQueue<Text> res= new PriorityQueue<Text>(limit,Collections.reverseOrder(cmp));
for (Text value : values) {
if (res.size() < limit) {
res.add(new Text(value.toString()));
} else if (cmp.compare(res.peek(), new Text(value.toString())) > 0) {
res.add(new Text(value.toString()));
res.poll();
}
}
for(Text s:res)
{
context.write(key, s);
}
}
}