/**
   * 将原始数据切割后装入ThreadInfo,并以Key=WaitID,Value= ThreadInfo实体放入到Multimap<String, ThreadInfo>集合中
   * ps:Multimap 类似于Map<key,collection>, key:value-> 1:n
   *
   * @param rawDatas
   * @return
   */
  public Multimap<String, ThreadInfo> getThreadInfo(List<String[]> rawDatas) {
    Multimap<String, ThreadInfo> w_IdMap = HashMultimap.create();
    List<ThreadInfo> threadsList = Lists.newArrayList();
    for (String[] rawData : rawDatas) {
      ThreadInfo threadInfo = new ThreadInfo();
      Pattern t_id = Pattern.compile("tid=(0x[\\d\\w]+)");
      Pattern t_name = Pattern.compile("\"([\\d\\D]*)\"");
      Pattern w_Id = Pattern.compile("\\[(0x[\\d\\w]+)\\]");
      Matcher tIdMatcher = t_id.matcher(rawData[0]);
      Matcher nameMatcher = t_name.matcher(rawData[0]);
      Matcher w_IdMatcher = w_Id.matcher(rawData[0]);
      if (tIdMatcher.find()) {
        threadInfo.setThreadId(tIdMatcher.group(1));
      }

      if (nameMatcher.find()) {
        threadInfo.setThreadName(nameMatcher.group(1));
      }

      if (w_IdMatcher.find()) {
        threadInfo.setWaitThreadId(w_IdMatcher.group(1));
      }
      threadInfo.setThreadCondition(rawData[1]);
      w_IdMap.put(threadInfo.getWaitThreadId(), threadInfo);
    }
    return w_IdMap;
  }
Example #2
0
  public String toGraphviz() {
    StringBuilder builder = new StringBuilder();

    builder.append("digraph QuantileDigest {\n").append("\tgraph [ordering=\"out\"];");

    final List<Node> nodes = new ArrayList<>();
    postOrderTraversal(
        root,
        new Callback() {
          @Override
          public boolean process(Node node) {
            nodes.add(node);
            return true;
          }
        });

    Multimap<Integer, Node> nodesByLevel =
        Multimaps.index(
            nodes,
            new Function<Node, Integer>() {
              @Override
              public Integer apply(Node input) {
                return input.level;
              }
            });

    for (Map.Entry<Integer, Collection<Node>> entry : nodesByLevel.asMap().entrySet()) {
      builder.append("\tsubgraph level_" + entry.getKey() + " {\n").append("\t\trank = same;\n");

      for (Node node : entry.getValue()) {
        builder.append(
            String.format(
                "\t\t%s [label=\"[%s..%s]@%s\\n%s\", shape=rect, style=filled,color=%s];\n",
                idFor(node),
                node.getLowerBound(),
                node.getUpperBound(),
                node.level,
                node.weightedCount,
                node.weightedCount > 0 ? "salmon2" : "white"));
      }

      builder.append("\t}\n");
    }

    for (Node node : nodes) {
      if (node.left != null) {
        builder.append(format("\t%s -> %s;\n", idFor(node), idFor(node.left)));
      }
      if (node.right != null) {
        builder.append(format("\t%s -> %s;\n", idFor(node), idFor(node.right)));
      }
    }

    builder.append("}\n");

    return builder.toString();
  }
 /**
  * expand super types after scanning, for super types that were not scanned. this is helpful in
  * finding the transitive closure without scanning all 3rd party dependencies. it uses {@link
  * ReflectionUtils#getSuperTypes(Class)}.
  *
  * <p>for example, for classes A,B,C where A supertype of B, B supertype of C:
  *
  * <ul>
  *   <li>if scanning C resulted in B (B->C in store), but A was not scanned (although A supertype
  *       of B) - then getSubTypes(A) will not return C
  *   <li>if expanding supertypes, B will be expanded with A (A->B in store) - then getSubTypes(A)
  *       will return C
  * </ul>
  */
 public void expandSuperTypes() {
   if (store.keySet().contains(index(SubTypesScanner.class))) {
     Multimap<String, String> mmap = store.get(index(SubTypesScanner.class));
     Sets.SetView<String> keys = Sets.difference(mmap.keySet(), Sets.newHashSet(mmap.values()));
     Multimap<String, String> expand = HashMultimap.create();
     for (String key : keys) {
       expandSupertypes(expand, key, forName(key));
     }
     mmap.putAll(expand);
   }
 }
 /** merges a Reflections instance metadata into this instance */
 public Reflections merge(final Reflections reflections) {
   if (reflections.store != null) {
     for (String indexName : reflections.store.keySet()) {
       Multimap<String, String> index = reflections.store.get(indexName);
       for (String key : index.keySet()) {
         for (String string : index.get(key)) {
           store.getOrCreate(indexName).put(key, string);
         }
       }
     }
   }
   return this;
 }
 private void expandSupertypes(Multimap<String, String> mmap, String key, Class<?> type) {
   for (Class<?> supertype : ReflectionUtils.getSuperTypes(type)) {
     if (mmap.put(supertype.getName(), key)) {
       if (log != null) log.debug("expanded subtype {} -> {}", supertype.getName(), key);
       expandSupertypes(mmap, supertype.getName(), supertype);
     }
   }
 }
 /**
  * 按照对应关系对 aitID:threadInfo-> 1:n 对N从大到小排序 处理MulitMap中的数据,key:value->1:n 取出<key, n>
  * 对n降序排序后,取得序列后的List<Map.Entry<key, n>>
  *
  * @return
  */
 public List<Map.Entry<String, Integer>> getOrderList(Multimap<String, ThreadInfo> w_IdMap) {
   Set<String> keys = w_IdMap.keySet();
   Map<String, Integer> w_IdMappingThread = Maps.newHashMap();
   for (String key : keys) {
     Collection<ThreadInfo> values = w_IdMap.get(key);
     w_IdMappingThread.put(key, values.size());
   }
   List<Map.Entry<String, Integer>> orderList =
       new ArrayList<Map.Entry<String, Integer>>(w_IdMappingThread.entrySet());
   Collections.sort(
       orderList,
       new Comparator<Map.Entry<String, Integer>>() {
         @Override
         public int compare(Map.Entry<String, Integer> o1, Map.Entry<String, Integer> o2) {
           return o2.getValue().compareTo(o1.getValue());
         }
       });
   return orderList;
 }
 /** 按照要求打印结果 */
 public void printStackInfo(Multimap<String, ThreadInfo> w_IdMap) {
   List<Map.Entry<String, Integer>> orderList = getOrderList(w_IdMap);
   for (Map.Entry<String, Integer> entry : orderList) {
     logger.info(entry.getKey() + "," + entry.getValue()); // 输出wait_id 对应个数
     Collection<ThreadInfo> threads = w_IdMap.get(entry.getKey()); // 输出wait_id对应的ThreadInfo集合
     for (ThreadInfo thread : threads) {
       logger.info("{}", thread);
     }
     logger.info("");
   }
 }