BottomUpNode extends CpuTreeNode<BottomUpNode> { @Override public void update(@NotNull Range range) { myGlobalTotal = 0; double self = 0; HashMap<CaptureNode, CaptureNode> outerSoFarByParent = new HashMap<>(); for (CaptureNode node : myNodes) { CaptureNode root = findRootNode(node); CaptureNode outerSoFar = outerSoFarByParent.getOrDefault(root, null); if (outerSoFar == null || node.getEnd() > outerSoFar.getEnd()) { if (outerSoFar != null) { myGlobalTotal += getIntersection(range, outerSoFar, ClockType.GLOBAL); } outerSoFarByParent.put(root, node); } self += getIntersection(range, node, ClockType.GLOBAL); for (CaptureNode child : node.getChildren()) { self -= getIntersection(range, child, ClockType.GLOBAL); } } for(CaptureNode outerSoFar : outerSoFarByParent.values()) { myGlobalTotal += getIntersection(range, outerSoFar, ClockType.GLOBAL); } myGlobalChildrenTotal = myGlobalTotal - self; } private  BottomUpNode(String id);  BottomUpNode(@NotNull CaptureNode node); boolean buildChildren(); @Override void update(@NotNull Range range); @NotNull @Override CaptureNodeModel getMethodModel(); @Override CaptureNode.FilterType getFilterType();  }
@Test public void testPartialRangeWithMixedTwoMethods() { CaptureNode root = newNode("main", 0, 100); addChainSubtree(root, newNode("A", 0, 100), newNode("A", 0, 40), newNode("A", 0, 20)); addChainSubtree(root.getChildren().get(0), newNode("B", 45, 100), newNode("A", 50, 70), newNode("B", 55, 65)); addChainSubtree(root.getChildren().get(0).getChildren().get(0), newNode("B", 21, 40), newNode("A", 25, 28)); BottomUpNode node = new BottomUpNode(root); BottomUpNode nodeA = node.getChildren().stream().filter(n -> n.getId().equals("A")).findAny().orElseThrow(AssertionError::new); nodeA.update(new Range(0, 100)); assertEquals(100, nodeA.getGlobalTotal(), EPS); assertEquals(61, nodeA.getGlobalChildrenTotal(), EPS); nodeA.update(new Range(21, 40)); assertEquals(19, nodeA.getGlobalTotal(), EPS); assertEquals(16, nodeA.getGlobalChildrenTotal(), EPS); nodeA.update(new Range(66, 71)); assertEquals(5, nodeA.getGlobalTotal(), EPS); assertEquals(1, nodeA.getGlobalChildrenTotal(), EPS); }