From 4df04a254397836b1bfe384ac9e6413e1ff9b242 Mon Sep 17 00:00:00 2001 From: Erik Gahlin Date: Tue, 23 Sep 2025 14:53:04 +0000 Subject: [PATCH] 8366809: JFR: Use factory for aggregator functions Reviewed-by: mgronlun --- .../classes/jdk/jfr/internal/query/Field.java | 3 + .../jdk/jfr/internal/query/Function.java | 60 ++++++++++--------- .../jdk/jfr/internal/query/Histogram.java | 5 +- 3 files changed, 38 insertions(+), 30 deletions(-) diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Field.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Field.java index 90cd1c40a76..b7fc4381670 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Field.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Field.java @@ -33,6 +33,7 @@ import jdk.jfr.consumer.RecordedEvent; import jdk.jfr.internal.query.Configuration.Truncate; import jdk.jfr.internal.query.Query.Grouper; import jdk.jfr.internal.query.Query.OrderElement; +import jdk.jfr.internal.query.Function.FunctionFactory; /** * Field is the core class of the package. @@ -137,6 +138,8 @@ final class Field { public int precision = -1; + public FunctionFactory functionFactory; + public Field(FilteredType type, String name) { this.type = type; this.name = name; diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java index 0c9ca96ee20..f01105c698c 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Function.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2023, 2024, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2023, 2025, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -35,45 +35,49 @@ import java.util.Set; abstract class Function { + interface FunctionFactory { + Function newFunction(); + } + public abstract void add(Object value); public abstract Object result(); - public static Function create(Field field) { + public static FunctionFactory createFactory(Field field) { Aggregator aggregator = field.aggregator; if (field.grouper != null || aggregator == Aggregator.MISSING) { - return new FirstNonNull(); + return () -> new FirstNonNull(); } if (aggregator == Aggregator.LIST) { - return new Container(new ArrayList<>()); + return () -> new Container(new ArrayList<>()); } if (aggregator == Aggregator.SET) { - return new Container(new LinkedHashSet<>()); + return () -> new Container(new LinkedHashSet<>()); } if (aggregator == Aggregator.DIFFERENCE) { if (field.timestamp) { - return new TimeDifference(); + return () -> new TimeDifference(); } else { - return new Difference(); + return () -> new Difference(); } } if (aggregator == Aggregator.STANDARD_DEVIATION) { if (field.timespan) { - return new TimespanFunction(new StandardDeviation()); + return () -> new TimespanFunction(new StandardDeviation()); } else { - return new StandardDeviation(); + return () -> new StandardDeviation(); } } if (aggregator == Aggregator.MEDIAN) { if (field.timespan) { - return new TimespanFunction(new Median()); + return () -> new TimespanFunction(new Median()); } else { - return new Median(); + return () -> new Median(); } } @@ -83,7 +87,6 @@ abstract class Function { if (aggregator == Aggregator.P95) { return createPercentile(field, 0.95); - } if (aggregator == Aggregator.P99) { return createPercentile(field, 0.99); @@ -92,46 +95,46 @@ abstract class Function { return createPercentile(field, 0.999); } if (aggregator == Aggregator.MAXIMUM) { - return new Maximum(); + return () -> new Maximum(); } if (aggregator == Aggregator.MINIMUM) { - return new Minimum(); + return () -> new Minimum(); } if (aggregator == Aggregator.SUM) { if (field.timespan) { - return new SumDuration(); + return () -> new SumDuration(); } if (field.fractionalType) { - return new SumDouble(); + return () -> new SumDouble(); } if (field.integralType) { - return new SumLong(); + return () -> new SumLong(); } } if (aggregator == Aggregator.FIRST) { - return new First(); + return () -> new First(); } if (aggregator == Aggregator.LAST_BATCH) { - return new LastBatch(field); + return () -> new LastBatch(field); } if (aggregator == Aggregator.LAST) { - return new Last(); + return () -> new Last(); } if (aggregator == Aggregator.AVERAGE) { if (field.timespan) { - return new AverageDuration(); + return () -> new AverageDuration(); } else { - return new Average(); + return () -> new Average(); } } if (aggregator == Aggregator.COUNT) { - return new Count(); + return () -> new Count(); } if (aggregator == Aggregator.UNIQUE) { - return new Unique(); + return () -> new Unique(); } - return new Null(); + return () -> new Null(); } // **** AVERAGE **** @@ -507,12 +510,11 @@ abstract class Function { } // **** PERCENTILE **** - private static Function createPercentile(Field field, double percentile) { - Percentile p = new Percentile(percentile); + private static FunctionFactory createPercentile(Field field, double percentile) { if (field.timespan) { - return new TimespanFunction(p); + return () -> new TimespanFunction(new Percentile(percentile)); } else { - return p; + return () -> new Percentile(percentile); } } diff --git a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Histogram.java b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Histogram.java index d3d596dc4b9..8b68c492c6e 100644 --- a/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Histogram.java +++ b/src/jdk.jfr/share/classes/jdk/jfr/internal/query/Histogram.java @@ -122,6 +122,9 @@ final class Histogram { public void addFields(List fields) { this.fields.addAll(fields); + for (Field field : fields) { + field.functionFactory = Function.createFactory(field); + } } public void add(RecordedEvent e, FilteredType type, List sourceFields) { @@ -168,7 +171,7 @@ final class Histogram { private Function[] createFunctions() { Function[] functions = new Function[fields.size()]; for (int i = 0; i < functions.length; i++) { - functions[i] = Function.create(fields.get(i)); + functions[i] = fields.get(i).functionFactory.newFunction(); } return functions; }