From 683b73ecf812fdd74e56d09b073ea34741262371 Mon Sep 17 00:00:00 2001 From: Stefan Bischof Date: Fri, 21 Nov 2025 19:38:31 +0100 Subject: [PATCH 1/2] refactor evaluate methods to evaluateInternal. enabled profiling Signed-off-by: Stefan Bischof --- .../rolap/common/RolapCatalogParameter.java | 2 +- .../rolap/common/RolapCatalogReader.java | 2 +- .../RolapDependencyTestingEvaluator.java | 6 +- ...r.java => RolapInterceptaleEvaluator.java} | 93 ++++----- .../daanse/rolap/common/RolapResult.java | 8 +- .../daanse/rolap/common/ScenarioImpl.java | 2 +- .../rolap/core/internal/BasicContext.java | 4 +- .../daanse/rolap/element/RolapHierarchy.java | 2 +- .../function/def/intersect/IntersectCalc.java | 2 +- .../def/visualtotals/VisualTotalsCalc.java | 2 +- .../common/agg/DenseSegmentBodyTestBase.java | 192 ------------------ 11 files changed, 53 insertions(+), 262 deletions(-) rename core/src/main/java/org/eclipse/daanse/rolap/common/{RolapProfilingEvaluator.java => RolapInterceptaleEvaluator.java} (56%) delete mode 100644 core/src/test/java/org/eclipse/daanse/rolap/common/agg/DenseSegmentBodyTestBase.java diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogParameter.java b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogParameter.java index f7ccfed..468a4fd 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogParameter.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogParameter.java @@ -157,7 +157,7 @@ public Calc[] getChildCalcs() { } @Override - public Object evaluate(Evaluator evaluator) { + public Object evaluateInternal(Evaluator evaluator) { if (value != null) { return value; } diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogReader.java b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogReader.java index d5864e1..2160aed 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogReader.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapCatalogReader.java @@ -937,7 +937,7 @@ public Calc[] getChildCalcs() { } @Override - public Object evaluate(Evaluator evaluator) { + public Object evaluateInternal(Evaluator evaluator) { if (system) { final String name = SystemPropertyParameter.this.getName(); diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapDependencyTestingEvaluator.java b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapDependencyTestingEvaluator.java index 075eb33..4125889 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapDependencyTestingEvaluator.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapDependencyTestingEvaluator.java @@ -342,7 +342,7 @@ public Calc[] getChildCalcs() { } @Override - public Object evaluate(Evaluator evaluator) { + public Object evaluateInternal(Evaluator evaluator) { RolapDependencyTestingEvaluator dtEval = (RolapDependencyTestingEvaluator) evaluator; return dtEval.evaluate(calc, independentHierarchies, mdxString); @@ -383,7 +383,7 @@ public Calc[] getChildCalcs() { } @Override - public TupleIterable evaluate(Evaluator evaluator) { + public TupleIterable evaluateInternal(Evaluator evaluator) { RolapDependencyTestingEvaluator dtEval = (RolapDependencyTestingEvaluator) evaluator; return (TupleIterable) dtEval.evaluate(calc, independentHierarchies, mdxString); @@ -427,7 +427,7 @@ public Calc[] getChildCalcs() { @Override - public TupleList evaluate(Evaluator evaluator) { + public TupleList evaluateInternal(Evaluator evaluator) { RolapDependencyTestingEvaluator dtEval = (RolapDependencyTestingEvaluator) evaluator; Object o = dtEval.evaluate(calc, independentHierarchies, mdxString); diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapProfilingEvaluator.java b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapInterceptaleEvaluator.java similarity index 56% rename from core/src/main/java/org/eclipse/daanse/rolap/common/RolapProfilingEvaluator.java rename to core/src/main/java/org/eclipse/daanse/rolap/common/RolapInterceptaleEvaluator.java index 76e0028..a061fc2 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapProfilingEvaluator.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapInterceptaleEvaluator.java @@ -28,7 +28,6 @@ import org.eclipse.daanse.olap.api.calc.Calc; import org.eclipse.daanse.olap.api.calc.compiler.ExpressionCompiler; -import org.eclipse.daanse.olap.api.calc.profile.ProfilingCalc; import org.eclipse.daanse.olap.api.element.Member; import org.eclipse.daanse.olap.api.query.component.Expression; import org.eclipse.daanse.olap.calc.base.compiler.DelegatingExpCompiler; @@ -47,10 +46,10 @@ * * Rationale: Children calcs are used in about 50 places, but mostly for * dependency-checking (e.g. - * org.eclipse.daanse.olap.calc.base.AbstractProfilingNestedCalc#anyDepends. A few places uses the - * calcs array but should use more strongly typed members. e.g. - * FilterFunDef.MutableMemberIterCalc should have data members 'MemberListCalc - * listCalc' and 'BooleanCalc conditionCalc'. + * org.eclipse.daanse.olap.calc.base.AbstractProfilingNestedCalc#anyDepends. A + * few places uses the calcs array but should use more strongly typed members. + * e.g. FilterFunDef.MutableMemberIterCalc should have data members + * 'MemberListCalc listCalc' and 'BooleanCalc conditionCalc'. * * * 2. Split Query into parse tree, plan, statement. Fits better into the @@ -63,60 +62,44 @@ * @author jhyde * @since October, 2010 */ -public class RolapProfilingEvaluator extends RolapEvaluator { +public class RolapInterceptaleEvaluator extends RolapEvaluator { - /** - * Creates a profiling evaluator. - * - * @param root Shared context between this evaluator and its children - */ - RolapProfilingEvaluator(RolapEvaluatorRoot root) { - super(root); - } + /** + * Creates a profiling evaluator. + * + * @param root Shared context between this evaluator and its children + */ + RolapInterceptaleEvaluator(RolapEvaluatorRoot root) { + super(root); + } - /** - * Creates a child evaluator. - * - * @param root Root evaluation context - * @param evaluator Parent evaluator - */ - private RolapProfilingEvaluator(RolapEvaluatorRoot root, RolapProfilingEvaluator evaluator, - List> aggregationList) { - super(root, evaluator, aggregationList); - } + /** + * Creates a child evaluator. + * + * @param root Root evaluation context + * @param evaluator Parent evaluator + */ + private RolapInterceptaleEvaluator(RolapEvaluatorRoot root, RolapInterceptaleEvaluator evaluator, + List> aggregationList) { + super(root, evaluator, aggregationList); + } - @Override - protected RolapEvaluator pushClone(List> aggregationList) { - return new RolapProfilingEvaluator(root, this, aggregationList); - } - - /** - * Expression compiler which introduces dependency testing. - * - * - * It also checks that the caller does not modify lists unless it has explicitly - * asked for a mutable list. - */ - public static class ProfilingEvaluatorCompiler extends DelegatingExpCompiler { - public ProfilingEvaluatorCompiler(ExpressionCompiler compiler) { - super(compiler); - } - - @Override - protected ProfilingCalc afterCompile(Expression exp, Calc calc, boolean mutable) { - calc = super.afterCompile(exp, calc, mutable); - if (calc == null) { - return null; - } - - if (calc instanceof ProfilingCalc pc) { - return pc; - } - - throw new RuntimeException("MUST BE PROFILING"); - } - } + @Override + protected RolapEvaluator pushClone(List> aggregationList) { + return new RolapInterceptaleEvaluator(root, this, aggregationList); + } + public static class InterceptableEvaluatorCompiler extends DelegatingExpCompiler { + public InterceptableEvaluatorCompiler(ExpressionCompiler compiler) { + super(compiler); + } + @Override + protected Calc afterCompile(Expression exp, Calc calc, boolean mutable) { + calc = super.afterCompile(exp, calc, mutable); + // Theoretical option to wrap a calc for special reasons, to do extras + return calc; + } + } } diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapResult.java b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapResult.java index 62744de..b39ba5d 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/RolapResult.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/RolapResult.java @@ -172,7 +172,7 @@ public RolapResult( final Execution execution, boolean execute ) { } else { final RolapEvaluatorRoot root = new RolapResultEvaluatorRoot( this ); if ( statement.getProfileHandler() != null ) { - this.evaluator = new RolapProfilingEvaluator( root ); + this.evaluator = new RolapInterceptaleEvaluator( root ); } else { this.evaluator = new RolapEvaluator( root ); } @@ -325,7 +325,7 @@ public RolapResult( final Execution execution, boolean execute ) { setType, new Calc[0]) { @Override - public TupleList evaluate( + public TupleList evaluateInternal( Evaluator evaluator) { ArrayList children = new ArrayList<>(); @@ -416,7 +416,7 @@ public void unparse(Expression[] args, PrintWriter pw) { } else { final RolapEvaluatorRoot root = new RolapResultEvaluatorRoot( this ); if ( statement.getProfileHandler() != null ) { - this.evaluator = new RolapProfilingEvaluator( root ); + this.evaluator = new RolapInterceptaleEvaluator( root ); } else { this.evaluator = new RolapEvaluator( root ); } @@ -505,7 +505,7 @@ public void unparse(Expression[] args, PrintWriter pw) { final Calc calcCached = new AbstractProfilingNestedUnknownCalc( query.getSlicerCalc().getType() ) { @Override - public Object evaluate( Evaluator evaluator ) { + public Object evaluateInternal( Evaluator evaluator ) { try { evaluator.getTiming().markStart( "EvalForSlicer" ); TupleList list = diff --git a/core/src/main/java/org/eclipse/daanse/rolap/common/ScenarioImpl.java b/core/src/main/java/org/eclipse/daanse/rolap/common/ScenarioImpl.java index 64545b4..719436c 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/common/ScenarioImpl.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/common/ScenarioImpl.java @@ -544,7 +544,7 @@ private Scenario getScenario() { } @Override - public Object evaluate(Evaluator evaluator) { + public Object evaluateInternal(Evaluator evaluator) { // Evaluate current member in the given scenario by expanding in // terms of the writeback cells. diff --git a/core/src/main/java/org/eclipse/daanse/rolap/core/internal/BasicContext.java b/core/src/main/java/org/eclipse/daanse/rolap/core/internal/BasicContext.java index 2ce0b2c..32beb09 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/core/internal/BasicContext.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/core/internal/BasicContext.java @@ -61,7 +61,7 @@ import org.eclipse.daanse.rolap.common.RolapDependencyTestingEvaluator; import org.eclipse.daanse.rolap.common.RolapEvaluator; import org.eclipse.daanse.rolap.common.RolapEvaluatorRoot; -import org.eclipse.daanse.rolap.common.RolapProfilingEvaluator; +import org.eclipse.daanse.rolap.common.RolapInterceptaleEvaluator; import org.eclipse.daanse.rolap.common.RolapResult; import org.eclipse.daanse.rolap.common.RolapResultShepherd; import org.eclipse.daanse.rolap.common.agg.AggregationManager; @@ -271,7 +271,7 @@ public List getCustomAggregators() { @Override public ExpressionCompiler createProfilingCompiler(ExpressionCompiler compiler) { - return new RolapProfilingEvaluator.ProfilingEvaluatorCompiler(compiler); + return new RolapInterceptaleEvaluator.InterceptableEvaluatorCompiler(compiler); } /** diff --git a/core/src/main/java/org/eclipse/daanse/rolap/element/RolapHierarchy.java b/core/src/main/java/org/eclipse/daanse/rolap/element/RolapHierarchy.java index e2f6a57..5189af7 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/element/RolapHierarchy.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/element/RolapHierarchy.java @@ -1093,7 +1093,7 @@ public MemberReader createMemberReader(Role role) { setType, new Calc[0]) { @Override - public TupleList evaluate( + public TupleList evaluateInternal( Evaluator evaluator) { return diff --git a/core/src/main/java/org/eclipse/daanse/rolap/function/def/intersect/IntersectCalc.java b/core/src/main/java/org/eclipse/daanse/rolap/function/def/intersect/IntersectCalc.java index 30b58a4..607b777 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/function/def/intersect/IntersectCalc.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/function/def/intersect/IntersectCalc.java @@ -40,7 +40,7 @@ public IntersectCalc(Type type, TupleListCalc listCalc1, TupleListCalc listCalc2 } @Override - public TupleList evaluate(Evaluator evaluator) { + public TupleList evaluateInternal(Evaluator evaluator) { TupleList leftList = getChildCalc(0, TupleListCalc.class).evaluate(evaluator); if (leftList.isEmpty()) { return leftList; diff --git a/core/src/main/java/org/eclipse/daanse/rolap/function/def/visualtotals/VisualTotalsCalc.java b/core/src/main/java/org/eclipse/daanse/rolap/function/def/visualtotals/VisualTotalsCalc.java index 8b8d34f..df0159b 100644 --- a/core/src/main/java/org/eclipse/daanse/rolap/function/def/visualtotals/VisualTotalsCalc.java +++ b/core/src/main/java/org/eclipse/daanse/rolap/function/def/visualtotals/VisualTotalsCalc.java @@ -46,7 +46,7 @@ public VisualTotalsCalc( } @Override - public TupleList evaluate(Evaluator evaluator) { + public TupleList evaluateInternal(Evaluator evaluator) { final List list = tupleListCalc.evaluate(evaluator).slice(0); final List resultList = new ArrayList<>(list); diff --git a/core/src/test/java/org/eclipse/daanse/rolap/common/agg/DenseSegmentBodyTestBase.java b/core/src/test/java/org/eclipse/daanse/rolap/common/agg/DenseSegmentBodyTestBase.java deleted file mode 100644 index 13dd084..0000000 --- a/core/src/test/java/org/eclipse/daanse/rolap/common/agg/DenseSegmentBodyTestBase.java +++ /dev/null @@ -1,192 +0,0 @@ -/* - * This software is subject to the terms of the Eclipse Public License v1.0 - * Agreement, available at the following URL: - * http://www.eclipse.org/legal/epl-v10.html. - * You must accept the terms of that agreement to use this software. - * - * Copyright (c) 2015-2017 Hitachi Vantara.. All rights reserved. - * ---- All changes after Fork in 2023 ------------------------ - * - * Project: Eclipse daanse - * - * Copyright (c) 2023 Contributors to the Eclipse Foundation. - * - * This program and the accompanying materials are made - * available under the terms of the Eclipse Public License 2.0 - * which is available at https://www.eclipse.org/legal/epl-2.0/ - * - * SPDX-License-Identifier: EPL-2.0 - * - * Contributors after Fork in 2023: - * SmartCity Jena - initial - */ - -package org.eclipse.daanse.rolap.common.agg; - -import static java.util.Arrays.asList; -import static org.eclipse.daanse.olap.util.Pair.of; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertFalse; -import static org.junit.jupiter.api.Assertions.assertNotNull; -import static org.junit.jupiter.api.Assertions.assertNull; -import static org.junit.jupiter.api.Assertions.assertTrue; - -import java.util.BitSet; -import java.util.Collections; -import java.util.Iterator; -import java.util.List; -import java.util.Map; -import java.util.SortedSet; -import java.util.TreeSet; - -import org.junit.jupiter.api.Test; -import org.eclipse.daanse.olap.util.Pair; -import org.eclipse.daanse.olap.key.CellKey; -import org.eclipse.daanse.rolap.common.agg.AbstractSegmentBody; - -/** - * This is a base class for two heirs. It provides several template methods - * for testing - * @author Andrey Khayrutdinov - */ -abstract class DenseSegmentBodyTestBase -{ - - final V nonNull = createNonNullValue(); - final V nullValue = createNullValue(); - - @Test - public void testGetObject_NonNull() { - T body = withOutAxes(nonNull); - assertEquals(nonNull, body.getObject(0)); - } - - @Test - public void testGetObject_Null() { - T body = withOutAxes(nullValue); - assertNull(body.getObject(0)); - } - - @Test - public void testGetSize_NoNulls() { - T body = withOutAxes(nonNull, nonNull, nonNull); - assertEquals(body.getSize(), body.getEffectiveSize()); - } - - @Test - public void testGetSize_HasNulls() { - T body = withOutAxes(nonNull, nullValue, nonNull); - assertEquals(3, body.getSize()); - assertEquals(2, body.getEffectiveSize()); - } - - @Test - public void testGetSize_OnlyNulls() { - T body = withOutAxes(nullValue, nullValue, nullValue); - assertEquals(3, body.getSize()); - assertEquals(0, body.getEffectiveSize()); - } - - @Test - public void testGetValueMap_NoNullCells_NoNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, false)); - T body = withAxes(axes, nonNull, nonNull, nonNull); - assertValuesMapIsCorrect(body, 3); - } - - @Test - public void testGetValueMap_NoNullCells_HasNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, true)); - T body = withAxes(axes, nonNull, nonNull, nonNull, nonNull); - assertValuesMapIsCorrect(body, 4); - } - - @Test - public void testGetValueMap_HasNullCells_NoNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, false)); - T body = withAxes(axes, nonNull, nullValue, nonNull, nullValue, nonNull); - assertValuesMapIsCorrect(body, 3); - } - - @Test - public void testGetValueMap_HasNullCells_HasNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, true)); - T body = withAxes( - axes, nonNull, nullValue, nonNull, nullValue, nonNull, nonNull); - assertValuesMapIsCorrect(body, 4); - } - - @Test - public void testGetValueMap_OnlyNullCells_NoNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, false)); - T body = withAxes(axes, nullValue, nullValue); - assertValuesMapIsCorrect(body, 0); - } - - @Test - public void testGetValueMap_OnlyNullCells_HasNullAxes() { - SortedSet axis1 = new TreeSet<>(asList(1, 2)); - SortedSet axis2 = new TreeSet<>(asList(3)); - List, Boolean>> axes = asList( - of(axis1, false), of(axis2, true)); - T body = withAxes(axes, nullValue, nullValue); - assertValuesMapIsCorrect(body, 0); - } - - private void assertValuesMapIsCorrect(T body, int expectedSize) { - Map valueMap = body.getValueMap(); - - assertEquals(expectedSize, valueMap.size()); - assertEquals(expectedSize, valueMap.keySet().size()); - assertEquals(expectedSize, valueMap.values().size()); - assertEquals(expectedSize, valueMap.entrySet().size()); - - int i = 0; - Iterator> it = valueMap.entrySet().iterator(); - while (i < expectedSize) { - assertTrue(it.hasNext(), Integer.toString(i)); - assertNotNull(it.next()); - i++; - } - assertFalse(it.hasNext()); - } - - abstract V createNullValue(); - abstract V createNonNullValue(); - abstract boolean isNull(V value); - - abstract T createSegmentBody( - BitSet nullValues, Object array, - List, Boolean>> axes); - - T withOutAxes(V... values) { - return withAxes( - Collections., Boolean>>emptyList(), - values); - } - - T withAxes(List, Boolean>> axes, V... values) { - BitSet nullValues = new BitSet(); - for (int i = 0; i < values.length; i++) { - if (isNull(values[i])) { - nullValues.set(i); - } - } - return createSegmentBody(nullValues, values, axes); - } -} From ed30109e0948d8f1df6ca74980d2da2319447214 Mon Sep 17 00:00:00 2001 From: dbulahov Date: Mon, 24 Nov 2025 11:56:32 +0300 Subject: [PATCH 2/2] refactor evaluate methods to evaluateInternal. enabled profiling Signed-off-by: dbulahov --- core/test.bndrun | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/test.bndrun b/core/test.bndrun index 60a24bb..6441ca3 100644 --- a/core/test.bndrun +++ b/core/test.bndrun @@ -79,11 +79,13 @@ org.eclipse.emf.common;version='[2.30.0,2.30.1)',\ org.eclipse.emf.ecore;version='[2.36.0,2.36.1)',\ org.eclipse.emf.ecore.xmi;version='[2.37.0,2.37.1)',\ + org.gecko.emf.osgi.api;version='[6.2.0,6.2.1)',\ org.gecko.emf.osgi.component;version='[6.2.0,6.2.1)',\ org.mockito.junit-jupiter;version='[5.12.0,5.12.1)',\ org.mockito.mockito-core;version='[5.12.0,5.12.1)',\ org.objenesis;version='[3.3.0,3.3.1)',\ org.opentest4j;version='[1.3.0,1.3.1)',\ + org.osgi.service.cm;version='[1.6.1,1.6.2)',\ org.osgi.service.component;version='[1.5.1,1.5.2)',\ org.osgi.test.assertj.framework;version='[1.3.0,1.3.1)',\ org.osgi.test.common;version='[1.3.0,1.3.1)',\