001/* 002// This software is subject to the terms of the Eclipse Public License v1.0 003// Agreement, available at the following URL: 004// http://www.eclipse.org/legal/epl-v10.html. 005// You must accept the terms of that agreement to use this software. 006// 007// Copyright (C) 2005-2005 Julian Hyde 008// Copyright (C) 2005-2009 Pentaho 009// All Rights Reserved. 010*/ 011package mondrian.olap; 012 013import mondrian.calc.*; 014import mondrian.calc.impl.BetterExpCompiler; 015 016import java.util.ArrayList; 017import java.util.List; 018 019/** 020 * Holds information necessary to add an expression to the expression result 021 * cache (see {@link Evaluator#getCachedResult(ExpCacheDescriptor)}). 022 * 023 * @author jhyde 024 * @since Aug 16, 2005 025 */ 026public class ExpCacheDescriptor { 027 private final Exp exp; 028 private int[] dependentHierarchyOrdinals; 029 private final Calc calc; 030 031 /** 032 * Creates a descriptor with a given compiled expression. 033 * 034 * @param exp Expression 035 * @param calc Compiled expression 036 * @param evaluator Evaluator 037 */ 038 public ExpCacheDescriptor(Exp exp, Calc calc, Evaluator evaluator) { 039 this.calc = calc; 040 this.exp = exp; 041 computeDepends(calc, evaluator); 042 } 043 044 /** 045 * Creates a descriptor. 046 * 047 * @param exp Expression 048 * @param evaluator Evaluator 049 */ 050 public ExpCacheDescriptor(Exp exp, Evaluator evaluator) { 051 this(exp, new BetterExpCompiler(evaluator, null)); 052 } 053 054 /** 055 * Creates a descriptor. 056 * 057 * @param exp Expression 058 * @param compiler Compiler 059 */ 060 public ExpCacheDescriptor(Exp exp, ExpCompiler compiler) { 061 this.exp = exp; 062 063 // Compile expression. 064 Calc calc = compiler.compile(exp); 065 if (calc == null) { 066 // now allow conversions 067 calc = compiler.compileAs(exp, null, ResultStyle.ANY_ONLY); 068 } 069 this.calc = calc; 070 071 // Compute list of dependent dimensions. 072 computeDepends(calc, compiler.getEvaluator()); 073 } 074 075 private void computeDepends(Calc calc, Evaluator evaluator) { 076 final List<Integer> ordinalList = new ArrayList<Integer>(); 077 final Member[] members = evaluator.getMembers(); 078 for (int i = 0; i < members.length; i++) { 079 Hierarchy hierarchy = members[i].getHierarchy(); 080 if (calc.dependsOn(hierarchy)) { 081 ordinalList.add(i); 082 } 083 } 084 dependentHierarchyOrdinals = new int[ordinalList.size()]; 085 for (int i = 0; i < dependentHierarchyOrdinals.length; i++) { 086 dependentHierarchyOrdinals[i] = ordinalList.get(i); 087 } 088 } 089 090 public Exp getExp() { 091 return exp; 092 } 093 094 public Calc getCalc() { 095 return calc; 096 } 097 098 public Object evaluate(Evaluator evaluator) { 099 return calc.evaluate(evaluator); 100 } 101 102 /** 103 * Returns the ordinals of the hierarchies which this expression is 104 * dependent upon. When the cache descriptor is used to generate a cache 105 * key, the key will consist of a member from each of these hierarchies. 106 */ 107 public int[] getDependentHierarchyOrdinals() { 108 return dependentHierarchyOrdinals; 109 } 110 111} 112 113// End ExpCacheDescriptor.java