rolapresult.java
来自「数据仓库展示程序」· Java 代码 · 共 717 行 · 第 1/2 页
JAVA
717 行
public Object get(Evaluator evaluator) {
final RolapEvaluator rolapEvaluator = (RolapEvaluator) evaluator;
return aggMan.getCellFromCache(rolapEvaluator.getCurrentMembers());
}
}
private void executeStripe(int axisOrdinal, RolapEvaluator evaluator) {
if (axisOrdinal < 0) {
RolapAxis axis = (RolapAxis) slicerAxis;
int count = axis.positions.length;
for (int i = 0; i < count; i++) {
RolapPosition position = (RolapPosition) axis.positions[i];
for (int j = 0; j < position.members.length; j++) {
evaluator.setContext(position.members[j]);
}
Object o;
try {
o = evaluator.evaluateCurrent();
} catch (MondrianEvaluationException e) {
o = e;
}
if (o != null && o != RolapUtil.valueNotReadyException) {
CellKey key = point.copy();
cellValues.put(key, o);
// Compute the formatted value, to ensure that any needed
// values are in the cache.
try {
Cell cell = getCell(point.ordinals);
Util.discard(cell.getFormattedValue());
} catch (MondrianEvaluationException e) {
// ignore
} catch (Throwable e) {
Util.discard(e);
}
}
}
} else {
RolapAxis axis = (RolapAxis) axes[axisOrdinal];
int count = axis.positions.length;
for (int i = 0; i < count; i++) {
point.ordinals[axisOrdinal] = i;
RolapPosition position = (RolapPosition) axis.positions[i];
for (int j = 0; j < position.members.length; j++) {
evaluator.setContext(position.members[j]);
}
executeStripe(axisOrdinal - 1, evaluator);
}
}
}
/**
* Converts a cell ordinal to a set of cell coordinates. Converse of
* {@link #getCellOrdinal}. For example, if this result is 10 x 10 x 10,
* then cell ordinal 537 has coordinates (5, 3, 7).
*/
public int[] getCellPos(int cellOrdinal) {
int[] pos = new int[axes.length];
for (int j = 0; j < axes.length; j++) {
pos[j] = (cellOrdinal % modulos[j + 1]) / modulos[j];
}
return pos;
}
/**
* Converts a set of cell coordinates to a cell ordinal. Converse of
* {@link #getCellPos}.
*/
int getCellOrdinal(int[] pos) {
int ordinal = 0;
for (int j = 0; j < axes.length; j++) {
ordinal += pos[j] * modulos[j];
}
return ordinal;
}
RolapEvaluator getCellEvaluator(int[] pos) {
final RolapEvaluator cellEvaluator = (RolapEvaluator) evaluator.push();
for (int i = 0; i < pos.length; i++) {
Position position = axes[i].positions[pos[i]];
for (int j = 0; j < position.members.length; j++) {
cellEvaluator.setContext(position.members[j]);
}
}
return cellEvaluator;
}
Evaluator getEvaluator(int[] pos) {
// Set up evaluator's context, so that context-dependent format
// strings work properly.
Evaluator cellEvaluator = evaluator.push();
for (int i = -1; i < axes.length; i++) {
Axis axis;
int index;
if (i < 0) {
axis = slicerAxis;
index = 0;
} else {
axis = axes[i];
index = pos[i];
}
Position position = axis.positions[index];
for (int j = 0; j < position.members.length; j++) {
Member member = position.members[j];
cellEvaluator.setContext(member);
}
}
return cellEvaluator;
}
/**
* Evaluator which checks dependencies of expressions.
*
* <p>For each expression evaluation, this valuator evaluates each
* expression more times, and makes sure that the results of the expression
* are independent of dimensions which the expression claims to be
* independent of.
*
* <p>Since it evaluates each expression twice, it also exposes function
* implementations which change the context of the evaluator.
*/
private class DependencyTestingEvaluator extends RolapEvaluator {
/**
* Creates an evaluator.
*/
DependencyTestingEvaluator(RolapResult result, int expDeps) {
super(new DependencyTestingEvalutorRoot(result, expDeps));
}
/**
* Creates a child evaluator.
*/
private DependencyTestingEvaluator(
RolapEvaluatorRoot root,
DependencyTestingEvaluator evaluator,
CellReader cellReader,
Member[] cloneCurrentMembers) {
super(root, evaluator, cellReader, cloneCurrentMembers);
}
/**
* Returns the dimensions an expression depends on, caching the result.
*/
private Dimension[] getIndependentDimensions(Exp exp) {
Dimension[] indDims = (Dimension[]) expIndDims.get(exp);
if (indDims == null) {
List indDimList = new ArrayList();
final Dimension[] dims = root.cube.getDimensions();
for (int i = 0; i < dims.length; i++) {
Dimension dim = dims[i];
if (!exp.dependsOn(dim)) {
indDimList.add(dim);
}
}
indDims = (Dimension[])
indDimList.toArray(new Dimension[indDimList.size()]);
expIndDims.put(exp, indDims);
}
return indDims;
}
public RolapEvaluator _push() {
Member[] cloneCurrentMembers =
(Member[]) this.getCurrentMembers().clone();
return new DependencyTestingEvaluator(
root,
this,
cellReader,
cloneCurrentMembers);
}
public Object visit(FunCall funCall) {
final DependencyTestingEvalutorRoot dteRoot =
(DependencyTestingEvalutorRoot) root;
if (dteRoot.faking) {
++dteRoot.fakeCallCount;
} else {
++dteRoot.callCount;
}
// Evaluate the call for real.
final Object result = super.visit(funCall);
if (batchingReader.isDirty()) {
return result;
}
// Change one of the allegedly independent dimensions and evaluate
// again.
//
// Don't do it if the faking is disabled,
// or if we're already faking another dimension,
// or if we're filtering out nonempty cells (which makes us
// dependent on everything),
// or if the ratio of fake evals to real evals is too high (which
// would make us too slow).
if (dteRoot.disabled ||
dteRoot.faking ||
isNonEmpty() ||
(double) dteRoot.fakeCallCount >
(double) dteRoot.callCount * random.nextDouble() * 2 *
dteRoot.expDeps) {
return result;
}
Dimension[] independentDimensions =
getIndependentDimensions(funCall);
if (independentDimensions.length == 0) {
return result;
}
dteRoot.faking = true;
++dteRoot.fakeCount;
++dteRoot.fakeCallCount;
final int i = random.nextInt(independentDimensions.length);
final Member saveMember = getContext(independentDimensions[i]);
final Member otherMember =
chooseOtherMember(saveMember, query.getSchemaReader(false));
setContext(otherMember);
final Object otherResult = super.visit(funCall);
if (!equals(otherResult, result)) {
final Member[] members = getCurrentMembers();
final StringBuffer buf = new StringBuffer();
for (int j = 0; j < members.length; j++) {
if (j > 0) {
buf.append(", ");
}
buf.append(members[j].getUniqueName());
}
throw Util.newInternal(
"Expression '" + funCall.toMdx() +
"' claims to be independent of dimension " +
saveMember.getDimension() + " but is not; context is {" +
buf.toString() + "}; First result: " +
toString(result) + ", Second result: " +
toString(otherResult));
}
// Restore context.
setContext(saveMember);
dteRoot.faking = false;
return result;
}
/**
* Chooses another member of the same hierarchy.
* The member will come from all levels with the same probability.
* For example, given [Gender].[M], the result has a
* @param save
* @param schemaReader
* @return
*/
private Member chooseOtherMember(
final Member save, SchemaReader schemaReader) {
final Hierarchy hierarchy = save.getHierarchy();
while (true) {
// Choose a random level.
final Level[] levels = hierarchy.getLevels();
final int levelDepth = random.nextInt(levels.length) + 1;
Member member = null;
for (int i = 0; i < levelDepth; i++) {
Member[] members;
if (i == 0) {
members = schemaReader.getLevelMembers(levels[i]);
} else {
members = schemaReader.getMemberChildren(member);
}
if (members.length == 0) {
break;
}
member = members[random.nextInt(members.length)];
}
// If the member chosen happens to be the same as the original
// member, try again.
if (member != save) {
return member;
}
}
}
private boolean equals(Object o1, Object o2) {
if (o1 == null) {
return o2 == null;
}
if (o2 == null) {
return false;
}
if (o1 instanceof Object[]) {
if (o2 instanceof Object[]) {
Object[] a1 = (Object[]) o1;
Object[] a2 = (Object[]) o2;
if (a1.length == a2.length) {
for (int i = 0; i < a1.length; i++) {
if (!equals(a1[i], a2[i])) {
return false;
}
}
return true;
}
}
return false;
}
if (o1 instanceof List) {
if (o2 instanceof List) {
return equals(
((List) o1).toArray(),
((List) o2).toArray());
}
return false;
}
return o1.equals(o2);
}
private String toString(Object o) {
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
toString(o, pw);
return sw.toString();
}
private void toString(Object o, PrintWriter pw) {
if (o instanceof Object[]) {
Object[] a = (Object[]) o;
pw.print("{");
for (int i = 0; i < a.length; i++) {
Object o1 = a[i];
if (i > 0) {
pw.print(", ");
}
toString(o1, pw);
}
pw.print("}");
} else if (o instanceof List) {
List list = (List) o;
toString(list.toArray(), pw);
} else if (o instanceof Member) {
Member member = (Member) o;
pw.print(member.getUniqueName());
} else {
pw.print(o);
}
}
}
private static class DependencyTestingEvalutorRoot
extends RolapEvaluator.RolapEvaluatorRoot {
final int expDeps;
int callCount;
int fakeCallCount;
int fakeCount;
boolean faking;
boolean disabled;
DependencyTestingEvalutorRoot(RolapResult result, int expDeps) {
super(result);
this.expDeps = expDeps;
}
}
}
// End RolapResult.java
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?