ValueHistogram.java
上传用户:quxuerui
上传日期:2018-01-08
资源大小:41811k
文件大小:5k
源码类别:

网格计算

开发平台:

Java

  1. /**
  2.  * Licensed to the Apache Software Foundation (ASF) under one
  3.  * or more contributor license agreements.  See the NOTICE file
  4.  * distributed with this work for additional information
  5.  * regarding copyright ownership.  The ASF licenses this file
  6.  * to you under the Apache License, Version 2.0 (the
  7.  * "License"); you may not use this file except in compliance
  8.  * with the License.  You may obtain a copy of the License at
  9.  *
  10.  *     http://www.apache.org/licenses/LICENSE-2.0
  11.  *
  12.  * Unless required by applicable law or agreed to in writing, software
  13.  * distributed under the License is distributed on an "AS IS" BASIS,
  14.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  15.  * See the License for the specific language governing permissions and
  16.  * limitations under the License.
  17.  */
  18. package org.apache.hadoop.mapred.lib.aggregate;
  19. import java.util.ArrayList;
  20. import java.util.Iterator;
  21. import java.util.TreeMap;
  22. import java.util.Map.Entry;
  23. import java.util.Arrays;
  24. /**
  25.  * This class implements a value aggregator that computes the 
  26.  * histogram of a sequence of strings.
  27.  * 
  28.  */
  29. public class ValueHistogram implements ValueAggregator {
  30.   TreeMap<Object, Object> items = null;
  31.   public ValueHistogram() {
  32.     items = new TreeMap<Object, Object>();
  33.   }
  34.   /**
  35.    * add the given val to the aggregator.
  36.    * 
  37.    * @param val the value to be added. It is expected to be a string
  38.    * in the form of xxxxtnum, meaning xxxx has num occurrences.
  39.    */
  40.   public void addNextValue(Object val) {
  41.     String valCountStr = val.toString();
  42.     int pos = valCountStr.lastIndexOf("t");
  43.     String valStr = valCountStr;
  44.     String countStr = "1";
  45.     if (pos >= 0) {
  46.       valStr = valCountStr.substring(0, pos);
  47.       countStr = valCountStr.substring(pos + 1);
  48.     }
  49.     
  50.     Long count = (Long) this.items.get(valStr);
  51.     long inc = Long.parseLong(countStr);
  52.     if (count == null) {
  53.       count = inc;
  54.     } else {
  55.       count = count.longValue() + inc;
  56.     }
  57.     items.put(valStr, count);
  58.   }
  59.   /**
  60.    * @return the string representation of this aggregator.
  61.    * It includes the following basic statistics of the histogram:
  62.    *    the number of unique values
  63.    *    the minimum value
  64.    *    the media value
  65.    *    the maximum value
  66.    *    the average value
  67.    *    the standard deviation
  68.    */
  69.   public String getReport() {
  70.     long[] counts = new long[items.size()];
  71.     StringBuffer sb = new StringBuffer();
  72.     Iterator iter = items.values().iterator();
  73.     int i = 0;
  74.     while (iter.hasNext()) {
  75.       Long count = (Long) iter.next();
  76.       counts[i] = count.longValue();
  77.       i += 1;
  78.     }
  79.     Arrays.sort(counts);
  80.     sb.append(counts.length);
  81.     i = 0;
  82.     long acc = 0;
  83.     while (i < counts.length) {
  84.       long nextVal = counts[i];
  85.       int j = i + 1;
  86.       while (j < counts.length && counts[j] == nextVal) {
  87.         j++;
  88.       }
  89.       acc += nextVal * (j - i);
  90.       //sbVal.append("t").append(nextVal).append("t").append(j - i)
  91.       //.append("n");
  92.       i = j;
  93.     }
  94.     double average = 0.0;
  95.     double sd = 0.0;
  96.     if (counts.length > 0) {
  97.       sb.append("t").append(counts[0]);
  98.       sb.append("t").append(counts[counts.length / 2]);
  99.       sb.append("t").append(counts[counts.length - 1]);
  100.       average = acc * 1.0 / counts.length;
  101.       sb.append("t").append(average);
  102.       i = 0;
  103.       while (i < counts.length) {
  104.         double nextDiff = counts[i] - average;
  105.         sd += nextDiff * nextDiff;
  106.         i += 1;
  107.       }
  108.       sd = Math.sqrt(sd / counts.length);
  109.       sb.append("t").append(sd);
  110.     }
  111.     //sb.append("n").append(sbVal.toString());
  112.     return sb.toString();
  113.   }
  114.   /** 
  115.    * 
  116.    * @return a string representation of the list of value/frequence pairs of 
  117.    * the histogram
  118.    */
  119.   public String getReportDetails() {
  120.     StringBuffer sb = new StringBuffer();
  121.     Iterator iter = items.entrySet().iterator();
  122.     while (iter.hasNext()) {
  123.       Entry en = (Entry) iter.next();
  124.       Object val = en.getKey();
  125.       Long count = (Long) en.getValue();
  126.       sb.append("t").append(val.toString()).append("t").append(
  127.                                                                  count.longValue()).append("n");
  128.     }
  129.     return sb.toString();
  130.   }
  131.   /**
  132.    *  @return a list value/frequence pairs.
  133.    *  The return value is expected to be used by the reducer.
  134.    */
  135.   public ArrayList getCombinerOutput() {
  136.     ArrayList<String> retv = new ArrayList<String>();
  137.     Iterator iter = items.entrySet().iterator();
  138.     while (iter.hasNext()) {
  139.       Entry en = (Entry) iter.next();
  140.       Object val = en.getKey();
  141.       Long count = (Long) en.getValue();
  142.       retv.add(val.toString() + "t" + count.longValue());
  143.     }
  144.     return retv;
  145.   }
  146.   /** 
  147.    * 
  148.    * @return a TreeMap representation of the histogram
  149.    */
  150.   public TreeMap getReportItems() {
  151.     return items;
  152.   }
  153.   /** 
  154.    * reset the aggregator
  155.    */
  156.   public void reset() {
  157.     items = new TreeMap<Object, Object>();
  158.   }
  159. }