Skip to content

Commit

Permalink
[Profiling] Limit TopN functions to available data
Browse files Browse the repository at this point in the history
With this commit we consider a case in the TopN functions API where the
specified limit is larger than the available number of TopN functions.
Currently this throws an error (`IndexOutOfBoundException`). With this
check in place we just return the list as is.
  • Loading branch information
danielmitterdorfer committed Apr 10, 2024
1 parent 13f95fd commit cdd45b3
Show file tree
Hide file tree
Showing 2 changed files with 89 additions and 2 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ static GetTopNFunctionsResponse buildTopNFunctions(GetStackTracesResponse respon
return builder.build();
}

private static class TopNFunctionsBuilder {
static class TopNFunctionsBuilder {
private final Integer limit;
private final HashMap<String, TopNFunction> topNFunctions;

Expand All @@ -141,7 +141,7 @@ public GetTopNFunctionsResponse build() {
sumTotalCount += topNFunction.getTotalCount();
}
// limit at the end so global stats are independent of the limit
if (limit != null && limit > 0) {
if (limit != null && limit > 0 && limit < functions.size()) {
functions = functions.subList(0, limit);
}
return new GetTopNFunctionsResponse(sumSelfCount, sumTotalCount, functions);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License
* 2.0; you may not use this file except in compliance with the Elastic License
* 2.0.
*/

package org.elasticsearch.xpack.profiling.action;

import org.elasticsearch.test.ESTestCase;

public class TopNFunctionsBuilderTests extends ESTestCase {
public void testBuildFunctions() {
TransportGetTopNFunctionsAction.TopNFunctionsBuilder builder = new TransportGetTopNFunctionsAction.TopNFunctionsBuilder(null);
TopNFunction foo = foo();
TopNFunction bar = bar();
builder.addTopNFunction(foo);
builder.addTopNFunction(bar);

GetTopNFunctionsResponse response = builder.build();

assertEquals(7L, response.getSelfCount());
assertEquals(14L, response.getTotalCount());
assertEquals(2, response.getTopN().size());
assertEquals(foo, response.getTopN().get(0));
assertEquals(bar, response.getTopN().get(1));
}

public void testBuildFunctionsWithLimitSmallerThanAvailableFunctionCount() {
TransportGetTopNFunctionsAction.TopNFunctionsBuilder builder = new TransportGetTopNFunctionsAction.TopNFunctionsBuilder(1);
TopNFunction foo = foo();
TopNFunction bar = bar();
builder.addTopNFunction(foo);
builder.addTopNFunction(bar);

GetTopNFunctionsResponse response = builder.build();

// total counts are independent of the limit
assertEquals(7L, response.getSelfCount());
assertEquals(14L, response.getTotalCount());
assertEquals(1, response.getTopN().size());
assertEquals(foo, response.getTopN().get(0));
}

public void testBuildFunctionsWithLimitHigherThanAvailableFunctionCount() {
TransportGetTopNFunctionsAction.TopNFunctionsBuilder builder = new TransportGetTopNFunctionsAction.TopNFunctionsBuilder(5);
TopNFunction foo = foo();
TopNFunction bar = bar();
builder.addTopNFunction(foo);
builder.addTopNFunction(bar);

GetTopNFunctionsResponse response = builder.build();

assertEquals(7L, response.getSelfCount());
assertEquals(14L, response.getTotalCount());
// still limited to the available two functions
assertEquals(2, response.getTopN().size());
assertEquals(foo, response.getTopN().get(0));
assertEquals(bar, response.getTopN().get(1));
}

private TopNFunction foo() {
TopNFunction foo = function("foo");
foo.addSelfCount(5L);
foo.addTotalCount(10L);
foo.addSelfAnnualCO2Tons(1.0d);
foo.addTotalAnnualCO2Tons(2.0d);
foo.addSelfAnnualCostsUSD(32.2d);
foo.addTotalAnnualCostsUSD(64.4d);
return foo;
}

private TopNFunction bar() {
TopNFunction bar = function("bar");
bar.addSelfCount(2L);
bar.addTotalCount(4L);
bar.addSelfAnnualCO2Tons(0.5d);
bar.addTotalAnnualCO2Tons(1.0d);
bar.addSelfAnnualCostsUSD(16.0d);
bar.addTotalAnnualCostsUSD(32.0d);
return bar;
}

private TopNFunction function(String name) {
return new TopNFunction(name, 3, false, 0, name, "main.c", 1, "demo");
}
}

0 comments on commit cdd45b3

Please sign in to comment.