Skip to content

Commit

Permalink
SubAggregation now done properly
Browse files Browse the repository at this point in the history
- Descendant/Ancestor Tree aggregation (for calling and caller methods
in a Flat View) has been fixed, and aggregates the ancestor/descendant
tree of the aggregated LeanNodes
- Information duplication in aggregator interfaces has been removed
- Grouping now stored in aggregation to allow subaggregation and to
avoid disconnect with front-end
- Removed fqmnlink pre-aggregation since it was a tad misguided and is
no longer necessary anyway
- Moved extractor classes into separate subpackage of util
  • Loading branch information
PhRX committed Feb 6, 2017
1 parent e395024 commit db997a0
Show file tree
Hide file tree
Showing 16 changed files with 209 additions and 348 deletions.
Expand Up @@ -8,7 +8,6 @@
import com.insightfullogic.honest_profiler.core.aggregation.grouping.CombinedGrouping;
import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Flat;
import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Tree;
import com.insightfullogic.honest_profiler.core.profiles.lean.LeanNode;
import com.insightfullogic.honest_profiler.core.profiles.lean.LeanProfile;
import com.insightfullogic.honest_profiler.core.profiles.lean.NumericInfo;

Expand All @@ -21,7 +20,6 @@ public class AggregationProfile
private static final TreeProfileAggregator treeAggregator = new TreeProfileAggregator();

private final LeanProfile source;
private final Map<String, FqmnLink> fqmnLinks;

private final NumericInfo global;

Expand All @@ -31,7 +29,6 @@ public class AggregationProfile
public AggregationProfile(LeanProfile source)
{
this.source = source;
fqmnLinks = new HashMap<>();
global = new NumericInfo();
cachedFlats = new HashMap<>();
cachedTrees = new HashMap<>();
Expand All @@ -42,7 +39,6 @@ public AggregationProfile(LeanProfile source)
source.getThreads().forEach((id, node) -> node.setThreadInfo(source.getThreadInfo(id)));

aggregateGlobal();
calculateLinks();
}

public LeanProfile getSource()
Expand All @@ -55,17 +51,6 @@ public NumericInfo getGlobalData()
return global;
}

public FqmnLink getFqmnLink(LeanNode node)
{
return fqmnLinks
.get(source.getMethodInfoMap().get(node.getFrame().getMethodId()).getFqmn());
}

public Map<String, FqmnLink> getFqmnLinks()
{
return fqmnLinks;
}

public Flat getFlat(CombinedGrouping grouping)
{
return cachedFlats.computeIfAbsent(grouping, g -> flatAggregator.aggregate(this, g));
Expand All @@ -84,31 +69,4 @@ private void aggregateGlobal()
(data1, data2) -> data1.add(data2));
global.add(aggregated);
}

private void calculateLinks()
{
source.getThreads()
.forEach((id, data) -> data.getChildren().forEach(node -> link(id, node)));
}

private void link(Long threadId, LeanNode node)
{
String fqmn = source.getMethodInfoMap().get(node.getFrame().getMethodId()).getFqmn();
FqmnLink link = fqmnLinks.computeIfAbsent(fqmn, FqmnLink::new);

link.addSibling(threadId, node);

LeanNode parent = node.getParent();
if (parent != null && !parent.isThreadNode())
{
// Add FQMN Link Parent-Child relations
link.addParent(threadId, parent);
if (parent.getFrame() != null)
{
getFqmnLink(parent).addChild(threadId, node);
}
}

node.getChildren().forEach(child -> link(threadId, child));
}
}

This file was deleted.

Expand Up @@ -3,88 +3,87 @@
import static java.util.stream.Collector.of;
import static java.util.stream.Collectors.groupingBy;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collector;

import com.insightfullogic.honest_profiler.core.aggregation.AggregationProfile;
import com.insightfullogic.honest_profiler.core.aggregation.FqmnLink;
import com.insightfullogic.honest_profiler.core.aggregation.grouping.CombinedGrouping;
import com.insightfullogic.honest_profiler.core.aggregation.result.Aggregation;
import com.insightfullogic.honest_profiler.core.aggregation.result.Keyed;
import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Entry;
import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Node;
import com.insightfullogic.honest_profiler.core.aggregation.result.straight.Tree;
import com.insightfullogic.honest_profiler.core.profiles.lean.LeanNode;

/**
* Aggregator which takes an {@link Entry} and aggregates the ancestors into a {@link Tree}.
* Aggregator which takes an {@link Entry} and aggregates the ancestors of all the {@link LeanNode}s aggregated by that
* {@link Entry} into a {@link Tree}.
*/
public class AncestorTreeAggregator implements SubAggregator<Entry, Node>
{
// Aggregator Implementation

/**
* @see SubAggregator#aggregate(Object, LeanNode)
* @see SubAggregator#aggregate(Object)
*/
@Override
public Tree aggregate(AggregationProfile source, Entry input)
public Tree aggregate(Entry input)
{
Node root = new Node(input);
List<Node> list = new ArrayList<>();
list.add(root);
Aggregation<Keyed<String>> aggregation = input.getAggregation();
AggregationProfile source = aggregation.getSource();
CombinedGrouping grouping = aggregation.getGrouping();

Tree result = new Tree(source, input.getAggregation().getGrouping());

Tree result = new Tree(source, list);
Set<String> processed = new HashSet<>();
Node root = new Node(input);
result.getData().add(root);

addAncestors(source, root, result, processed);
addAncestors(source, root, result, grouping);
return result;
}

// private void addAncestors(AggregationProfile source, Node child, Tree tree)
// {
// child.getAggregatedNodes().stream().map(node -> node.getParent()).collect(collector);
// }

private void addAncestors(AggregationProfile source, Node parent, Tree tree,
Set<String> processed)
/**
* Recursive method for aggregating the parents (and ancestors) of the {@link LeanNode}s which are aggregated by the
* provided {@link Node} and adding them as children.
*
* @param source the original {@link AggregationProfile}
* @param child the input {@link Node}
* @param tree the resulting {@link Tree}
* @param grouping the key calculation grouping
*/
private void addAncestors(AggregationProfile source, Node child, Tree tree,
CombinedGrouping grouping)
{
FqmnLink fqmnLink = source.getFqmnLinks().get(parent.getKey());
Map<String, Node> callers = fqmnLink.getParents().values().stream()
.flatMap(set -> set.stream()).filter(
node -> node != null
&& !node.isThreadNode()
&& !processed.contains(source.getSource().getFqmn(node)))
.collect(
groupingBy(
node -> source.getSource().getFqmn(node),
getCollector(source, tree, processed)));
parent.addAll(callers);
}
Map<String, Node> result = child.getAggregatedNodes().stream().map(node -> node.getParent())
// Parent of a root LeanNode is null
.filter(node -> node != null)
.collect(groupingBy(
// Group LeanNodes by calculated key
node -> grouping.apply(source, node),
// Downstream collector, collects LeanNodes in a single group
of(
// Supplier, creates an empty Node
() ->
{
Node node = new Node(tree);
node.setReference(source.getGlobalData());
return node;
},
// Accumulator, aggregates a LeanNode into the Entry accumulator
(node, leanNode) ->
{
node.add(leanNode);
node.setKey(grouping.apply(source, leanNode));
},
// Combiner, combines two Nodes with the same key
(node1, node2) -> node1.combine(node2)
)
));

private Collector<LeanNode, Node, Node> getCollector(AggregationProfile source, Tree tree,
Set<String> processed)
{
return of(
// Supplier
() ->
{
Node node = new Node(tree);
node.setReference(source.getGlobalData());
return node;
},
// Accumulator
(accumulator, node) ->
{
String fqmn = source.getSource().getFqmn(node);
processed.add(fqmn);
accumulator.add(fqmn, node);
if (accumulator.getChildren().isEmpty())
{
addAncestors(source, accumulator, tree, processed); // Recursion here !
}
},
// Combiner
(e1, e2) -> e1.combine(e2));
result.entrySet().forEach(mapEntry ->
{
child.addChild(mapEntry.getValue());
// Recursively add ancestors
addAncestors(source, mapEntry.getValue(), tree, grouping);
});
}
}

0 comments on commit db997a0

Please sign in to comment.