Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MONDRIAN: Stack-based evaluation context. Previously, each change in the
evaluation context would create a new evaluator. That was expensive. Now the evaluation context maintains a stack of commands that can be executed to restore state to a savepoint. It should allow us to add more state to the evaluator, in particular, building a list of (column, value) pairs, and thereby reducing the cost of making a CellRequest. Some methods of RolapEvaluator are now deprecated. [git-p4: depot-paths = "//open/mondrian/": change = 14242]
- Loading branch information
1 parent
ac2e622
commit 394a83d
Showing
63 changed files
with
1,791 additions
and
813 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,115 @@ | ||
/* | ||
// $Id$ | ||
// 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. | ||
// Copyright (C) 2011-2011 Julian Hyde | ||
// All Rights Reserved. | ||
// You must accept the terms of that agreement to use this software. | ||
*/ | ||
package mondrian.calc.impl; | ||
|
||
import mondrian.calc.Calc; | ||
import mondrian.calc.MemberCalc; | ||
import mondrian.olap.*; | ||
import mondrian.olap.type.ScalarType; | ||
import mondrian.olap.type.Type; | ||
|
||
/** | ||
* Expression which evaluates a few member expressions, | ||
* sets the dimensional context to the result of those expressions, | ||
* then yields the value of the current measure in the current | ||
* dimensional context. | ||
* | ||
* <p>The evaluator's context is preserved. | ||
* | ||
* <p>Note that a MemberValueCalc with 0 member expressions is equivalent to a | ||
* {@link ValueCalc}; see also {@link TupleValueCalc}. | ||
* | ||
* @author jhyde | ||
* @version $Id$ | ||
*/ | ||
public class MemberArrayValueCalc extends GenericCalc { | ||
private final MemberCalc[] memberCalcs; | ||
private final Member[] members; | ||
private final boolean nullCheck; | ||
|
||
/** | ||
* Creates a MemberArrayValueCalc. | ||
* | ||
* <p>Clients outside this package should use the | ||
* {@link MemberValueCalc#create(mondrian.olap.Exp, | ||
* mondrian.calc.MemberCalc[], boolean)} | ||
* factory method. | ||
* | ||
* @param exp Expression | ||
* @param memberCalcs Array of compiled expressions | ||
* @param nullCheck Whether to check for null values due to non-joining | ||
* dimensions in a virtual cube | ||
*/ | ||
MemberArrayValueCalc(Exp exp, MemberCalc[] memberCalcs, boolean nullCheck) { | ||
super(exp); | ||
this.nullCheck = nullCheck; | ||
final Type type = exp.getType(); | ||
assert type instanceof ScalarType : exp; | ||
this.memberCalcs = memberCalcs; | ||
this.members = new Member[memberCalcs.length]; | ||
} | ||
|
||
public Object evaluate(Evaluator evaluator) { | ||
final int savepoint = evaluator.savepoint(); | ||
for (int i = 0; i < memberCalcs.length; i++) { | ||
MemberCalc memberCalc = memberCalcs[i]; | ||
final Member member = memberCalc.evaluateMember(evaluator); | ||
if (member == null | ||
|| member.isNull()) | ||
{ | ||
// This method needs to leave the evaluator in the same state | ||
// it found it. | ||
evaluator.restore(savepoint); | ||
return null; | ||
} | ||
evaluator.setContext(member); | ||
members[i] = member; | ||
} | ||
if (nullCheck | ||
&& evaluator.needToReturnNullForUnrelatedDimension(members)) | ||
{ | ||
evaluator.restore(savepoint); | ||
return null; | ||
} | ||
|
||
final Object result = evaluator.evaluateCurrent(); | ||
evaluator.restore(savepoint); | ||
return result; | ||
} | ||
|
||
public Calc[] getCalcs() { | ||
return memberCalcs; | ||
} | ||
|
||
public boolean dependsOn(Hierarchy hierarchy) { | ||
if (super.dependsOn(hierarchy)) { | ||
return true; | ||
} | ||
for (MemberCalc memberCalc : memberCalcs) { | ||
// If the expression definitely includes the dimension (in this | ||
// case, that means it is a member of that dimension) then we | ||
// do not depend on the dimension. For example, the scalar value of | ||
// [Store].[USA] | ||
// does not depend on [Store]. | ||
// | ||
// If the dimensionality of the expression is unknown, then the | ||
// expression MIGHT include the dimension, so to be safe we have to | ||
// say that it depends on the given dimension. For example, | ||
// Dimensions(3).CurrentMember.Parent | ||
// may depend on [Store]. | ||
if (memberCalc.getType().usesHierarchy(hierarchy, true)) { | ||
return false; | ||
} | ||
} | ||
return true; | ||
} | ||
} | ||
|
||
// End MemberArrayValueCalc.java |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.