Package com.taobao.top.analysis.util

Source Code of com.taobao.top.analysis.util.MemberWeight

package com.taobao.top.analysis.util;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.net.InetAddress;
import java.net.URL;
import java.net.UnknownHostException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.PriorityQueue;
import java.util.concurrent.ConcurrentHashMap;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import com.taobao.top.analysis.exception.AnalysisException;
import com.taobao.top.analysis.statistics.data.Alias;
import com.taobao.top.analysis.statistics.data.ObjectColumn;
import com.taobao.top.analysis.statistics.data.Report;
import com.taobao.top.analysis.statistics.data.ReportEntry;
import com.taobao.top.analysis.statistics.data.ReportOrderComparator;
import com.taobao.top.analysis.statistics.data.impl.SimpleCalculator;
import com.taobao.top.analysis.statistics.reduce.IReducer.ReduceType;
import com.taobao.top.analysis.statistics.reduce.group.AvgFunction;

/**
* 报表工具类
*
* @author fangweng
*
*/
public class ReportUtil {
  private static final Log logger = LogFactory.getLog(ReportUtil.class);
  private static final Log clusterLogger = LogFactory.getLog("cluster");
  private static Map<Object, Object> localCache = new ConcurrentHashMap<Object, Object>();
  public final static String RETURN = "\r\n";
  public final static String MASTER_LOG = "master";
  public final static String SLAVE_LOG = "slave";
  public final static Threshold threshold = new Threshold(5000);

  private static String ip;

  private static String separator;

  static {
    try {
      ip = InetAddress.getLocalHost().getHostAddress();
      separator = System.getProperty("line.separator");
    } catch (UnknownHostException e) {
    }
  }

  public static String getIp() {
    return ip;
  }

  public static String getSeparator() {
    return separator;
  }
 
  public static void clusterLog(String log)
  {
    clusterLogger.info(log + RETURN);
  }

  public static InputStream getInputStreamFromFile(String file)
      throws IOException {
    InputStream in = null;

    String localdir = new StringBuilder()
        .append(System.getProperty("user.dir"))
        .append(File.separatorChar).toString();
    ClassLoader loader = Thread.currentThread().getContextClassLoader();

    if (file.startsWith("file:")) {
      try {
        in = new java.io.FileInputStream(new File(file.substring(file
            .indexOf("file:") + "file:".length())));
      } catch (Exception e) {
        logger.error(e, e);
      }

      if (in == null)
        in = new java.io.FileInputStream(new File(localdir
            + file.substring(file.indexOf("file:")
                + "file:".length())));
    } else {
      URL url = loader.getResource(file);

      if (url == null) {
        String error = "configFile: " + file + " not exist !";
        logger.error(error);
        throw new java.lang.RuntimeException(error);
      }

      in = url.openStream();
    }

    return in;
  }

  public static byte generateOperationFlag(String operation)
      throws AnalysisException {

    if (operation
        .startsWith(AnalysisConstants.CONDITION_EQUALORGREATER_STR)) {
      return AnalysisConstants.CONDITION_EQUALORGREATER;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_EQUALORLESSER_STR)) {
      return AnalysisConstants.CONDITION_EQUALORLESSER;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_NOT_EQUAL_STR)) {
      return AnalysisConstants.CONDITION_NOT_EQUAL;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_EQUAL_STR)) {
      return AnalysisConstants.CONDITION_EQUAL;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_GREATER_STR)) {
      return AnalysisConstants.CONDITION_GREATER;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_LESSER_STR)) {
      return AnalysisConstants.CONDITION_LESSER;
    }

    if (operation.startsWith(AnalysisConstants.CONDITION_ISNUMBER_STR)) {
      return AnalysisConstants.CONDITION_ISNUMBER;
    }
   
    if (operation.startsWith(AnalysisConstants.CONDITION_IN_STR)) {
      return AnalysisConstants.CONDITION_IN;
    }
   
    if(operation.startsWith(AnalysisConstants.CONDITION_LIKE_STR)) {
        return AnalysisConstants.CONDITION_LIKE;
    }

    throw new AnalysisException("Entry Operation not support!");

  }

  public static byte generateOperationFlag(char operation)
      throws AnalysisException {

    if (operation == AnalysisConstants.OPERATE_DIVIDE_CHAR) {
      return AnalysisConstants.OPERATE_DIVIDE;
    }
    if (operation == AnalysisConstants.OPERATE_MINUS_CHAR) {
      return AnalysisConstants.OPERATE_MINUS;
    }
    if (operation == AnalysisConstants.OPERATE_PLUS_CHAR) {
      return AnalysisConstants.OPERATE_PLUS;
    }
    if (operation == AnalysisConstants.OPERATE_RIDE_CHAR) {
      return AnalysisConstants.OPERATE_RIDE;
    }

    throw new AnalysisException("Entry Operation not support!");

  }

  // /**
  // * 根据定义获取对应日志行产生的key
  // *
  // * @param entry
  // * @param contents
  // * @return
  // */
  // public static String generateKey(ReportEntry entry, String[]
  // contents,List<InnerKey> innerKeyPool) {
  // StringBuilder key = new StringBuilder();
  //
  // try {
  // boolean checkResult = false;
  //
  // if (entry.getConditionKStack() != null
  // && entry.getConditionKStack().size() > 0) {
  // for (int i = 0; i < entry.getConditionKStack().size(); i++) {
  //
  // Object conditionKey = entry.getConditionKStack().get(i);
  // byte operator = entry.getConditionOpStack().get(i);
  // Object conditionValue = entry.getConditionVStack().get(i);
  // int k = -1;
  //
  // // 长度condition特殊处理,没有指定的key列
  // if (!conditionKey.equals(AnalysisConstants.RECORD_LENGTH)) {
  // k = (Integer) conditionKey;
  // }
  //
  // checkResult = checkKeyCondition(operator, k,
  // conditionValue, contents);
  //
  // if (entry.isAndCondition() && !checkResult)
  // return AnalysisConstants.IGNORE_PROCESS;
  //
  // if (!entry.isAndCondition() && checkResult)
  // break;
  // }
  // }
  //
  // if (!entry.isAndCondition() && !checkResult)
  // return AnalysisConstants.IGNORE_PROCESS;
  //
  // for (int c : entry.getKeys()) {
  // // 全局统计,没有key
  // if (c == AnalysisConstants.GLOBAL_KEY)
  // return AnalysisConstants.GLOBAL_KEY_STR;
  //
  // key.append(innerKeyReplace(c,contents[c -
  // 1],innerKeyPool)).append(AnalysisConstants.SPLIT_KEY);
  // }
  //
  // } catch (Exception ex) {
  // logger.error("generateKey error",ex);
  // return AnalysisConstants.IGNORE_PROCESS;
  // }
  //
  // return key.toString();
  // }

  // private static String innerKeyReplace(int key,String value,List<InnerKey>
  // innerKeyPool)
  // {
  // String result = value;
  //
  // if (innerKeyPool == null || (innerKeyPool != null && innerKeyPool.size()
  // == 0))
  // return result;
  //
  // for(InnerKey ik : innerKeyPool)
  // {
  // if (ik.getKey() == key)
  // {
  // if (ik.getInnerKeys().get(value) != null)
  // result = ik.getInnerKeys().get(value);
  //
  // break;
  // }
  // }
  //
  // return result;
  // }

  // /**
  // * 返回是否符合条件
  // *
  // * @param operator
  // * @param conditionKey
  // * @param conditionValue
  // * @param contents
  // * @return
  // */
  // private static boolean checkKeyCondition(byte operator, int conditionKey,
  // Object conditionValue, String[] contents) {
  // boolean result = false;
  //
  // if (operator == AnalysisConstants.CONDITION_EQUAL) {
  // if (conditionKey > 0)
  // result = contents[conditionKey - 1].equals(conditionValue);
  // else
  // result = contents.length == (Integer)conditionValue;
  // } else if (operator == AnalysisConstants.CONDITION_NOT_EQUAL) {
  // if (conditionKey > 0)
  // result = !contents[conditionKey - 1].equals(conditionValue);
  // else
  // result = contents.length != (Integer)conditionValue;
  // } else {
  // double cmpValue = 0;
  //
  // if (conditionKey > 0)
  // cmpValue = Double.valueOf(contents[conditionKey - 1])
  // - (Double)conditionValue;
  // else
  // cmpValue = contents.length - (Integer)conditionValue;
  //
  // if (operator == AnalysisConstants.CONDITION_EQUALORGREATER)
  // return cmpValue >= 0;
  //
  // if (operator == AnalysisConstants.CONDITION_EQUALORLESSER)
  // return cmpValue <= 0;
  //
  // if (operator == AnalysisConstants.CONDITION_GREATER)
  // return cmpValue > 0;
  //
  // if (operator == AnalysisConstants.CONDITION_LESSER)
  // return cmpValue < 0;
  //
  // }
  //
  // return result;
  // }

  private static java.text.DateFormat df = new SimpleDateFormat(
      "yyyy-MM-dd HH:mm:ss");

  public static String formateDateTime(long time) {
    java.util.Calendar cal = java.util.Calendar.getInstance();
    cal.setTimeInMillis(time);
    return df.format(cal.getTime());
  }
 
  /**
   * 简单的从column 的json对象中获得对应属性的结果
   * @param column
   * @param subKeyName
   */
  public static String getValueFromJosnObj(String column, String subKeyName)
  {
    String k = new StringBuilder("\"").append(subKeyName).append("\":").toString();
   
    if (column.indexOf(k) <= 0)
      return null;
   
    String v = column.substring(column.indexOf(k) + k.length());
   
    if (v.indexOf(",") > 0)
    {
      v = v.substring(0,v.indexOf(","));
    }
   
    if (v.indexOf("[") >= 0)
      v = v.substring(v.indexOf("[")+1);
   
    if (v.indexOf("]") > 0)
      v = v.substring(0,v.indexOf("]"));
   
    if (v.indexOf("\"") >= 0)
      v = v.substring(v.indexOf("\"")+1);
   
    if (v.endsWith("\""))
      v = v.substring(0,v.length()-1);
   
    return v;
   
  }

  /**
   * 根据别名定义来转换报表模型中定义的key,直接转换为实际的列号
   *
   * @param keys
   * @param aliasPool
   */
  public static int[] transformVars(String[] keys,
      Map<String, Alias> aliasPool,List<ObjectColumn> subKeys) {
    if (keys != null && keys.length > 0) {

      int[] tKeys = new int[keys.length];

      for (int i = 0; i < keys.length; i++) {
        if (aliasPool != null && aliasPool.size() > 0
            && aliasPool.get(keys[i]) != null)
          tKeys[i] = aliasPool.get(keys[i]).getKey();
        else if (keys[i].equals(AnalysisConstants.GLOBAL_KEY_STR))
          tKeys[i] = AnalysisConstants.GLOBAL_KEY;
        else
          if(aliasPool != null && aliasPool.size() > 0 &&
              keys[i].indexOf(".") > 0 && aliasPool.get(keys[i].substring(0, keys[i].indexOf("."))) != null)//列是复杂对象
         
            tKeys[i] = AnalysisConstants.Object_KEY;
            subKeys.add(new ObjectColumn(aliasPool.get(keys[i].substring(0, keys[i].indexOf("."))).getKey(),
                keys[i].substring(keys[i].indexOf(".") + 1)));
          }
          else
            tKeys[i] = Integer.parseInt(keys[i]);
      }

      return tKeys;
    } else
      return new int[0];
  }

  /**
   * 根据别名定义来转换报表模型中定义的key,直接转换为实际的列号
   *
   * @param key
   * @param aliasPool
   * @return
   */
  public static Object transformVar(String key, Map<String, Alias> aliasPool) {
    Object result = key;

    if (aliasPool != null && aliasPool.size() > 0
        && aliasPool.get(key) != null) {
      result = aliasPool.get(key).getKey();
    }

    return result;
  }

  /**
   * 根据接口定义获取实际的接口实现实例
   *
   * @param <I>
   * @param interfaceDefinition
   * @param classLoader
   * @param className
   * @param needCache
   * @return
   */
  @SuppressWarnings("unchecked")
  public static <I> I getInstance(Class<I> interfaceDefinition,
      ClassLoader classLoader, String className, boolean needCache) {

    // 获取缓存的情况,或者移除缓存
    if (needCache) {
      Object instance = localCache.get(className);

      if (instance == null) {
        instance = newInstance(interfaceDefinition, className,
            classLoader);
        localCache.put(className, instance);
      }

      return (I) instance;
    } else {
      return newInstance(interfaceDefinition, className, classLoader);
    }

  }

  /**
   * 创建实例
   *
   * @param <I>
   * @param interfaceDefinition
   * @param className
   * @param classLoader
   * @return
   */
  @SuppressWarnings("unchecked")
  private static <I> I newInstance(Class<I> interfaceDefinition,
      String className, ClassLoader classLoader) {
    try {
      Class<I> spiClass;

      if (classLoader == null) {
        spiClass = (Class<I>) Class.forName(className);
      } else {
        spiClass = (Class<I>) classLoader.loadClass(className);
      }

      return spiClass.newInstance();
    } catch (ClassNotFoundException x) {
      throw new java.lang.RuntimeException("Provider " + className
          + " not found", x);
    } catch (Exception ex) {
      throw new java.lang.RuntimeException("Provider " + className
          + " could not be instantiated: " + ex, ex);
    }
  }

  /**
   * 排序
   *
   * @param list
   * @param orders
   */
  public static void doOrder(ArrayList<Object[]> list, String[] orders,
      Report report) {
    if (orders == null || (orders != null && (orders.length == 0)))
      return;

    int[] columns = new int[orders.length];
    boolean[] isDesc = new boolean[orders.length];

    for (int i = 0; i < isDesc.length; i++) {
      isDesc[i] = true;
    }

    int index = 0;

    for (String order : orders) {
      if (order.startsWith("+") || order.startsWith("-")) {
        if (order.startsWith("+"))
          isDesc[index] = false;

        order = order.substring(1);
      }

      for (ReportEntry entry : report.getReportEntrys()) {
        if (order.equals(entry.getName())) {
          break;
        }
        columns[index] += 1;
      }

      if (columns[index] >= report.getReportEntrys().size())
        columns[index] = 0;

      index += 1;
    }

    Collections.sort(list, new ReportOrderComparator<Object[]>(columns,
        isDesc));

  }

  /**
   * 格式化结果,很消耗...
   *
   * @param formatStack
   * @param value
   * @return
   */
  public static Object formatValue(List<String> formatStack, Object value) {
    Object result = value;

    try {
      for (String filter : formatStack) {
        if (filter.startsWith(AnalysisConstants.CONDITION_ROUND_STR)) {

          int round = Integer.valueOf(filter
              .substring(AnalysisConstants.CONDITION_ROUND_STR
                  .length()));
          double r = Math.pow(10, round);

          if (value instanceof Double) {
            result = (Double) (Math.round((Double) value * r) / r);
          } else
            result = (Double) (Math.round((Double.valueOf(value
                .toString()) * r)) / r);

          continue;
        }
      }
    } catch (Exception ex) {
      logger.error(ex, ex);
    }

    return result;
  }

  // /**
  // * 检查参数是否符合过滤器定义
  // *
  // * @param valuefilterOpStack
  // * @param valuefilterStack
  // * @param value
  // * @return
  // */
  // public static boolean checkValue(List<Byte> valuefilterOpStack,
  // List<Object> valuefilterStack, Object value) {
  // boolean result = true;
  //
  // if (valuefilterStack == null
  // || (valuefilterStack != null && valuefilterStack.size() == 0))
  // return result;
  //
  // try {
  // for (int i = 0; i < valuefilterStack.size(); i++) {
  // Object filterValue = valuefilterStack.get(i);
  // Byte filterOpt = valuefilterOpStack.get(i);
  //
  // if (filterOpt == AnalysisConstants.CONDITION_ISNUMBER) {
  // Double.parseDouble(value.toString());
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_EQUAL) {
  // if (value.equals(filterValue)) {
  // continue;
  // } else
  // return false;
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_EQUALORGREATER) {
  // Double v = Double.valueOf(value.toString());
  // Double compareValue = (Double)filterValue;
  //
  // if (v >= compareValue) {
  // continue;
  // } else
  // return false;
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_EQUALORLESSER) {
  // Double v = Double.valueOf(value.toString());
  // Double compareValue = (Double)filterValue;
  //
  // if (v <= compareValue) {
  // continue;
  // } else
  // return false;
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_GREATER) {
  // Double v = Double.valueOf(value.toString());
  // Double compareValue = (Double)filterValue;
  //
  // if (v > compareValue) {
  // continue;
  // } else
  // return false;
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_LESSER) {
  // Double v = Double.valueOf(value.toString());
  // Double compareValue = (Double)filterValue;
  //
  // if (v < compareValue) {
  // continue;
  // } else
  // return false;
  // }
  //
  // if (filterOpt == AnalysisConstants.CONDITION_NOT_EQUAL) {
  // if (!value.equals(filterValue)) {
  // continue;
  // } else
  // return false;
  // }
  //
  // }
  // } catch (Exception ex) {
  // result = false;
  // }
  //
  // return result;
  // }

  /**
   * 合并结果集
   *
   * @param resultPools
   * @param entryPool
   * @return
   */
  public static Map<String, Map<String, Object>> mergeEntryResult(
      Map<String, Map<String, Object>>[] resultPools,
      Map<String, ReportEntry> entryPool, boolean needMergeLazy,ReduceType reduceType) {
    if (resultPools == null
        || (resultPools != null && resultPools.length == 0))
      return null;

    Map<String, Map<String, Object>> result = null;

    result = merge(resultPools, entryPool,reduceType);

    if (result == null || (result != null && result.size() <= 0))
      return result;

    if (needMergeLazy) {
      lazyMerge(result, entryPool);
    }

    return result;
  }

  public static void cleanLazyData(Map<String, Map<String, Object>> result,
      Map<String, ReportEntry> entryPool) {
    if (entryPool != null) {
      Iterator<String> entryKeys = entryPool.keySet().iterator();

      while (entryKeys.hasNext()) {
        String entryId = entryKeys.next();

        ReportEntry entry = entryPool.get(entryId);
        if (entry.isLazy()) {
          Map<String, Object> t = result.remove(entryId);

          if (t != null)
            t.clear();
        }

      }
    }

  }
 
  public static void cleanPeriodData(Map<String, Map<String, Object>> result,
            Map<String, ReportEntry> entryPool) {
      if (entryPool != null) {
            Iterator<String> entryKeys = entryPool.keySet().iterator();

            while (entryKeys.hasNext()) {
                String entryId = entryKeys.next();

                ReportEntry entry = entryPool.get(entryId);

                if (entry.isPeriod()) {
                    Map<String, Object> t = result.remove(entryId);

                    if (t != null)
                        t.clear();
                }
                //遍历删除平均值计算
                if(entry.getGroupFunction() != null && entry.getGroupFunction() instanceof AvgFunction) {
                    if(result.get(entryId) == null)
                        continue;
                    Iterator<Map.Entry<String, Object>> entries = result.get(entryId).entrySet().iterator();
                    while(entries.hasNext()) {
                        Entry<String, Object> en = entries.next();
                        String key = en.getKey();
                        if(!key.startsWith(AnalysisConstants.PREF_SUM) && !key.startsWith(AnalysisConstants.PREF_COUNT)) {
                            entries.remove();
                        }
                    }
                }

            }
        }
  }
 

  public static void lazyMerge(Map<String, Map<String, Object>> result,
      Map<String, ReportEntry> entryPool) {
    // 增加对于lazy entry的处理
    ArrayList<String> entryKeys = new ArrayList<String>();
    entryKeys.addAll(entryPool.keySet());
    // 二级lazy的优先顺序保证
    Collections.sort(entryKeys);

    for (String entryId : entryKeys) {

      ReportEntry entry = entryPool
          .get(entryId);
      if (entry.isLazy())
      {
        if (result.get(entryId) == null)
          result.put(entryId, new HashMap<String, Object>());
        SimpleCalculator c = (SimpleCalculator)entry.getCalculator();
        if (c.getBindingStack() != null
            && c.getBindingStack().size() > 0) {
          List<Object> _bindingStack = c.getBindingStack();
          int size = _bindingStack.size();

          String leftEntryId = (String) _bindingStack.get(0);

          Map<String, Object> leftMap = result.get(leftEntryId);

          if (leftMap == null
              || (leftMap != null && leftMap.size() <= 0)) {
            continue;
          }
          Iterator<String> iter = leftMap.keySet().iterator();
          java.util.Map<String, Double> cacheMap = new java.util.HashMap<String, Double>();
          while (iter.hasNext()) {
            try {
              String nodekey = iter.next();
              Object nodevalue = result.get(leftEntryId).get(
                  nodekey);
              Object rightvalue = null;

              for (int i = 0; i < size - 1; i++) {
                String rightkey = (String) _bindingStack
                    .get(i + 1);

                if (rightkey.startsWith("sum:")) {
                  rightkey = rightkey.substring(rightkey
                      .indexOf("sum:") + "sum:".length());
                  double sumValue = 0;
                  if (cacheMap.get(rightkey) != null) {
                    sumValue = cacheMap.get(rightkey);

                  } else {
                    Iterator<Object> rValues = result
                        .get(rightkey).values()
                        .iterator();

                    while (rValues.hasNext()) {
                      Object rv = rValues.next();

                      if (rv != null) {
                        if (rv instanceof String)
                          sumValue += Double
                              .valueOf((String) rv);
                        else {
                          sumValue += (Double) rv;
                        }
                      }

                    }
                    cacheMap.put(rightkey, sumValue);
                  }

                  rightvalue = sumValue;

                } else {
                  // 简单实现只支持两位计算,同时是+或者-
                  if (rightkey
                      .indexOf(AnalysisConstants.OPERATE_PLUS_CHAR) > 0
                      || rightkey
                          .indexOf(AnalysisConstants.OPERATE_MINUS_CHAR) > 0) {

                    String l;
                    String r;

                    if (rightkey
                        .indexOf(AnalysisConstants.OPERATE_PLUS_CHAR) > 0) {
                      l = rightkey
                          .substring(
                              0,
                              rightkey.indexOf(AnalysisConstants.OPERATE_PLUS_CHAR))
                          .trim();

                      r = rightkey
                          .substring(
                              rightkey.indexOf(AnalysisConstants.OPERATE_PLUS_CHAR) + 1)
                          .trim();

                      if (result.get(l) == null
                          || result.get(r) == null
                          || (result.get(l) != null && result
                              .get(l)
                              .get(nodekey) == null)
                          || (result.get(r) != null && result
                              .get(r)
                              .get(nodekey) == null))
                        continue;

                      rightvalue = Double.valueOf(result
                          .get(l).get(nodekey)
                          .toString())
                          + Double.valueOf(result
                              .get(r)
                              .get(nodekey)
                              .toString());
                    } else {
                      l = rightkey
                          .substring(
                              0,
                              rightkey.indexOf(AnalysisConstants.OPERATE_MINUS_CHAR))
                          .trim();

                      r = rightkey
                          .substring(
                              rightkey.indexOf(AnalysisConstants.OPERATE_MINUS_CHAR) + 1)
                          .trim();

                      if (result.get(l) == null
                          || result.get(r) == null
                          || (result.get(l) != null && result
                              .get(l)
                              .get(nodekey) == null)
                          || (result.get(r) != null && result
                              .get(r)
                              .get(nodekey) == null))
                        continue;

                      rightvalue = Double.valueOf(result
                          .get(l).get(nodekey)
                          .toString())
                          - Double.valueOf(result
                              .get(r)
                              .get(nodekey)
                              .toString());
                    }

                                    }
                                    else {
                                        try {
                                            rightvalue = result.get(rightkey).get(nodekey);
                                        }
                                        catch (Throwable e) {
                                            if(!threshold.sholdBlock())
                                                logger.error("resultkey is null" + rightkey, e);
                                        }
                                    }
                }

                if (rightvalue != null) {
                  if (nodevalue != null) {
                    if (c.getOperatorStack().get(i) == AnalysisConstants.OPERATE_PLUS) {
                      if (nodevalue instanceof Double
                          || rightvalue instanceof Double)
                        nodevalue = Double
                            .valueOf(nodevalue
                                .toString())
                            + Double.valueOf(rightvalue
                                .toString());
                      else
                        nodevalue = (Long) nodevalue
                            + (Long) rightvalue;

                      continue;
                    }

                    if (c.getOperatorStack().get(i) == AnalysisConstants.OPERATE_MINUS) {
                      if (nodevalue instanceof Double
                          || rightvalue instanceof Double)
                        nodevalue = Double
                            .valueOf(nodevalue
                                .toString())
                            - Double.valueOf(rightvalue
                                .toString());
                      else
                        nodevalue = (Long) nodevalue
                            - (Long) rightvalue;

                      continue;
                    }

                    if (c.getOperatorStack().get(i) == AnalysisConstants.OPERATE_RIDE) {
                      if (nodevalue instanceof Double
                          || rightvalue instanceof Double)
                        nodevalue = Double
                            .valueOf(nodevalue
                                .toString())
                            * Double.valueOf(rightvalue
                                .toString());
                      else
                        nodevalue = (Long) nodevalue
                            * (Long) rightvalue;

                      continue;
                    }

                    if (c.getOperatorStack().get(i) == AnalysisConstants.OPERATE_DIVIDE) {
                      nodevalue = Double
                          .valueOf(nodevalue
                              .toString())
                          / Double.valueOf(rightvalue
                              .toString());

                      continue;
                    }
                  } else {
                    // nodevalue=rightvalue;
                  }

                }

              }

              result.get(entryId).put(nodekey, nodevalue);
            } catch (Exception ex) {

              logger.error(
                  new StringBuilder("entry : ").append(
                      entry.getName()).append(
                      " lazy process error!"), ex);
              continue;
            }

          }
          cacheMap.clear();
        }

      }
      else
        //处理average的情况
        if (entry.getGroupFunction() instanceof AvgFunction)
        {
          Map<String,Object> av = result.get(entryId);
          Map<String,Object> tv = new HashMap<String,Object>();
         
          if (av != null)
          {
            Iterator<String> avKeys = av.keySet().iterator();
           
            while(avKeys.hasNext())
            {
              String ak = avKeys.next();
             
              if (ak.startsWith(AnalysisConstants.PREF_SUM))
              {
                String key = ak.substring(AnalysisConstants.PREF_SUM.length());
               
                tv.put(key, (Double)av.get(ak)/
                    (Double)av.get(new StringBuilder().append(AnalysisConstants.PREF_COUNT).append(key)
                          .toString()));
               
              }
            }
           
            if (tv.size() > 0)
              av.putAll(tv);
           
            tv.clear();
          }
        }

    }
  }

  protected static Map<String, Map<String, Object>> merge(
      Map<String, Map<String, Object>>[] entryPools,
      Map<String, ReportEntry> entryConfig,ReduceType reduceType) {
    Map<String, Map<String, Object>> result = null;

    int _index = 0;

    // 过滤一下最前面的空的结果
    for (int i = 0; i < entryPools.length; i++) {
      _index = i;

      if (entryPools[i] != null) {
        result = entryPools[i];
        break;
      }
    }
   
    //对深度merge时,只有单个结果集合的时候也做一次深层扫描
    if (reduceType == ReduceType.DEEP_MERGE && (_index == entryPools.length - 1))
    {
      result = new HashMap<String,Map<String,Object>>();
      _index = entryPools.length - 2;
    }

    // 直接用resultPools的第一个作为基础数组,从第二个数组开始
    for (int i = _index+1; i < entryPools.length; i++) {
      Map<String, Map<String, Object>> node = entryPools[i];
      if (node == null || (node != null && node.size() == 0))
        continue;
      Iterator<String> iter = node.keySet().iterator();
      while (iter.hasNext()) {
        String entryId = iter.next();
        ReportEntry entry = entryConfig.get(entryId);
        if (entry == null || (entry != null && entry.isLazy()))
          continue;
        if (result.get(entryId) == null)
          result.put(entryId, new HashMap<String, Object>());
        Map<String, Object> content = node.get(entryId);
        Iterator<String> keyIter = content.keySet().iterator();
        while (keyIter.hasNext()) {
          String key = keyIter.next();
          Object value = content.get(key);
          if (key == null || value == null)
            continue;
                    try {
                        entry.getReduceClass().reducer(entry, key, value, result.get(entryId), reduceType);
                    } catch (Throwable e) {
              logger.error("reduce error entryName:" + entry.getName() + ", key:" + key + ",value:" + value + "," + entry.getReports().toString(), e);
          }
        }

      }

    }

    return result;
  }
 

  /**
   * 获得报表文件存储路径
   *
   * @param 报表名称
   * @param 输出目录
   * @param 报表日期
   * @param 是否需要有后缀
   * @return
   */
  public static String getReportFileLocation(String reportname,
      String targetDir, long date, boolean needsuffix) {
    Calendar calendar = Calendar.getInstance();
    calendar.setTimeInMillis(date);
    String currentTime = new StringBuilder()
        .append(calendar.get(Calendar.YEAR)).append("-")
        .append(calendar.get(Calendar.MONTH) + 1).append("-")
        .append(calendar.get(Calendar.DAY_OF_MONTH)).toString();

    StringBuilder result = new StringBuilder();

    if (!targetDir.endsWith(File.separator))
      result.append(targetDir).append(File.separator).append(currentTime)
          .append(File.separator).toString();
    else
      result.append(targetDir).append(currentTime).append(File.separator)
          .toString();

    if (needsuffix) {
      calendar.add(Calendar.DAY_OF_MONTH, -1);
      String stattime = new StringBuilder()
          .append(calendar.get(Calendar.YEAR)).append("-")
          .append(calendar.get(Calendar.MONTH) + 1).append("-")
          .append(calendar.get(Calendar.DAY_OF_MONTH)).toString();

      result.append(reportname).append("_").append(stattime)
          .append(".csv").toString();
    } else {
      result.append(reportname).append(".csv").toString();
    }

    return result.toString();
  }

  /**
   * @param inputFile
   * @return
   */
  public static String createReportHtml(String inputFile, String title,
      int countNum) {
    StringBuilder result = new StringBuilder();
    java.io.BufferedReader br = null;

    try {
      File file = new File(inputFile);

      if (!file.exists())
        throw new java.lang.RuntimeException("chart file not exist : "
            + inputFile);

      br = new BufferedReader(new InputStreamReader(new FileInputStream(
          file), "gb2312"));

      String line = null;
      int index = 0;

      result.append("<br/>").append(title).append("<br/>");

      while ((line = br.readLine()) != null) {
        String[] contents = line.split(",");
        if (index == 0) {
          result.append("<table border=\"1\">");
        }
        result.append("<tr>");

        for (String c : contents) {
          if (index == 0)
            result.append("<th>").append(c).append("</th>");
          else
            result.append("<td>").append(c).append("</td>");
        }

        result.append("</tr>");
        index += 1;

        if (countNum > 0 && index > countNum)
          break;
      }

      result.append("</table>");
    } catch (Exception ex) {

      logger.error(ex, ex);
    } finally {
      if (br != null) {
        try {
          br.close();
        } catch (IOException e) {

          logger.error(e, e);
        }
      }
    }

    return result.toString();
  }

  /**
   * 将对象写入文件
   *
   * @param o
   * @param file
   */
  public static void writeObjectToFile(Object o, String file) {
    java.io.ObjectOutputStream out = null;

    try {
      new File(file).createNewFile();
      File f = new File(file);
      out = new ObjectOutputStream(new FileOutputStream(f));
      out.writeObject(o);
    } catch (Exception ex) {

      logger.error(ex, ex);
    } finally {
      if (out != null)
        try {
          out.close();
        } catch (IOException e) {

          logger.error(e, e);
        }
    }

  }
 
 
  /**
   * 简单的支持双向权重的分配算法
   * @param 资源要分配的对象,支持member split weight的表示方法
   * @param 对象要获得的资源,支持resource split weight的表示方法
   * @return resource:member
   */
  public static Map<String,String> SimpleAllocationAlgorithm(List<String> member,List<String> resource,String split)
  {
    Map<String,String> result = new HashMap<String,String>();
   
    if (member == null || resource == null
        || (member != null && member.size() == 0)
        || (resource != null && resource.size() == 0))
      return result;
   
    if (member.size() == 1)
    {
      String m = StringUtils.splitByWholeSeparator(member.get(0),split)[0];
     
      for(String r : resource)
      {
        result.put(r, m);
      }
      return result;
    }
   
    PriorityQueue<MemberWeight> memberWeights = new PriorityQueue<MemberWeight>();
    PriorityQueue<ResourceWeight> resourceWeights = new PriorityQueue<ResourceWeight>();
   
    //先将member中带有权重的情况打散
    for(int i = 0 ; i < member.size(); i++)
    {
      String m = member.get(i);
     
      memberWeights.add(new MemberWeight(m,split));
    }
   
    for(int i = 0 ; i < resource.size(); i++)
    {
      String res = resource.get(i);
     
      resourceWeights.add(new ResourceWeight(res,split));
    }
   
    ResourceWeight _res = null;
   
    while((_res = resourceWeights.poll()) != null)
    {
     
      MemberWeight _member = memberWeights.poll();
      _member.setTaskWeight(_member.getTaskWeight() + _res.getWeight());
      memberWeights.add(_member);
     
      result.put(_res.getKey(), _member.getKey());
    }
   
    return result;
  }
 
  public static void main(String[] args)
  {
    List<String> member = new ArrayList<String>();
    List<String> resource = new ArrayList<String>();
   
    member.add("analysis1");
    member.add("analysis2");
    member.add("analysis3");
   
    resource.add("job1");
    resource.add("job2");
    resource.add("job3");
    resource.add("job4");
    resource.add("job5");
   
    Map<String,String> r2m = SimpleAllocationAlgorithm(member,resource,":");
   
    for(Entry<String,String> t : r2m.entrySet())
    {
      System.out.println(t.getKey() + ":" + t.getValue());
    }
   
    System.out.println("-----------------");
    member.clear();
    resource.clear();
    r2m.clear();
   
    member.add("analysis1");
    member.add("analysis2");
    member.add("analysis3");
   
    resource.add("job1");
    resource.add("job2");
    resource.add("job3:4");
    resource.add("job4");
    resource.add("job5:2");
    resource.add("job6");
    resource.add("job7");
    resource.add("job8");
   
    r2m = SimpleAllocationAlgorithm(member,resource,":");
   
    for(Entry<String,String> t : r2m.entrySet())
    {
      System.out.println(t.getKey() + ":" + t.getValue());
    }
   
    System.out.println("-----------------");
    member.clear();
    resource.clear();
    r2m.clear();
   
    member.add("analysis1:4");
    member.add("analysis2");
    member.add("analysis3");
   
    resource.add("job1");
    resource.add("job2");
    resource.add("job3:4");
    resource.add("job4");
    resource.add("job5:2");
    resource.add("job6");
    resource.add("job7");
    resource.add("job8");
    resource.add("job9:20");
   
    r2m = SimpleAllocationAlgorithm(member,resource,":");
   
    for(Entry<String,String> t : r2m.entrySet())
    {
      System.out.println(t.getKey() + ":" + t.getValue());
    }
   
   
  }
 

  /**
   * 读取对象从文件
   *
   * @param file
   * @return
   */
  public static Object readObjectFromFile(String file) {
    Object result = null;

    ObjectInputStream bin = null;

    try {
      File f = new File(file);
      bin = new ObjectInputStream(new FileInputStream(f));
      result = bin.readObject();
    } catch (Exception ex) {

      logger.error(ex, ex);
    } finally {
      if (bin != null)
        try {
          bin.close();
        } catch (IOException e) {

          logger.error(e, e);
        }
    }

    return result;
  }

  // 用于不可逆压缩字符串的字典
  static String[] dict = new String[] { "a", "b", "c", "d", "e", "f", "g",
      "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t",
      "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6",
      "7", "8", "9", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
      "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W",
      "X", "Y", "Z", "<", ">" };

  /**
   * 不可逆方式压缩字符串,存在一定重复的可能性,指定的compressedLength越小,越容易重复,compress当前最大长度限制为10
   * md5后的16byte做压缩,得到指定的压缩长度 然后再将中间字母和长度拼接在压缩字符串上
   *
   * @param origin
   * @param compressedLength
   *            ,需要压缩到多少位,小于等于20,当等于0的时候,判断原始字符串是否大于32,如果是,则直接用md5转换为Hex串
   * @return
   */
  public static String compressString(String origin, int compressedLength) {
    // 特殊处理0
    if (compressedLength == 0 && (origin != null && origin.length() > 32)) {
      return DigestUtils.md5Hex(origin);
    }

    if (origin == null
        || (origin != null && (origin.length() < compressedLength + 1
            + String.valueOf(origin.length()).length())))
      return origin;

    if (compressedLength > 20) {
      compressedLength = 20;
      logger.warn("compressString function compressedLength must less 20");
    }

    StringBuilder result = new StringBuilder();

    result.append(origin.length()).append(
        origin.charAt(origin.length() / 2));

    try {
      byte[] dest = DigestUtils.md5(origin);
      long destLong1 = 0;
      long destLong2 = 0;

      for (int i = 0; i < 8; i++) {
        destLong1 |= dest[i] & 0xff;
        destLong1 <<= 8;
      }

      for (int i = 8; i < 15; i++) {
        destLong2 |= dest[i] & 0xff;
        destLong2 <<= 8;
      }

      if (compressedLength <= 10) {
        for (int j = 0; j < compressedLength; j++) {
          long index = destLong1 & 0x0000003F;
          result.append(dict[(int) index]);
          destLong1 >>= 6;
        }
      } else {
        for (int j = 0; j < 10; j++) {
          long index = destLong1 & 0x0000003F;
          result.append(dict[(int) index]);
          destLong1 >>= 6;
        }

        for (int j = 0; j < compressedLength - 10; j++) {
          long index = destLong2 & 0x0000003F;
          result.append(dict[(int) index]);
          destLong2 >>= 6;
        }
      }

    } catch (Exception ex) {
      logger.error("comporessString error !", ex);
    }

    return result.toString();
  }

//  public static void main(String[] args) {
//    String test = "1234567890abcdefg";
//    System.out.println(compressString(test, 8));
//    System.out.println(compressString(test, 10));
//    System.out.println(compressString(test, 14));
//  }

}

class MemberWeight implements java.lang.Comparable<MemberWeight>
{
  private static final Log logger = LogFactory.getLog(MemberWeight.class);
     
  String key;
  int weight;
  int taskWeight;
 
  public MemberWeight(String memWeight,String split)
  {
    if (memWeight.indexOf(split) <= 0)
      init(memWeight,1);
    else
    {
      String[] marr = StringUtils.splitByWholeSeparator(memWeight,split);
     
      try
      {
        init(marr[0], Integer.valueOf(marr[1]));
      }
      catch(Exception ex)
      {
        logger.error("SimpleAllocationAlgorithm error",ex);
      }
    }
  }
 
  public MemberWeight(String key,int weight)
  {
    init(key,weight);
  }
 
  void init(String key,int weight)
  {
    this.key = key;
   
    if(weight <= 0)
      this.weight = 1;
    else
      this.weight = weight;
   
    this.taskWeight = 0;
  }

  public String getKey() {
    return key;
  }

  public void setKey(String key) {
    this.key = key;
  }

  public int getWeight() {
    return weight;
  }
  public void setWeight(int weight) {
    this.weight = weight;
  }

  public int getTaskWeight() {
    return taskWeight;
  }

  public void setTaskWeight(int taskWeight) {
    this.taskWeight = taskWeight;
  }

  @Override
  public int compareTo(MemberWeight o) {
    if (taskWeight == 0)
      return 1/weight - 1/o.weight;
    else
      return taskWeight/weight - o.taskWeight/o.weight;
  }
}

class ResourceWeight extends MemberWeight
{
  @Override
  public int compareTo(MemberWeight o) {
   
    return o.weight - this.weight;
  }

  public ResourceWeight(String memWeight,String split)
  {
    super(memWeight, split);
  }
 
 
}
TOP

Related Classes of com.taobao.top.analysis.util.MemberWeight

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.
div>