1 10 package mondrian.rolap.agg; 11 12 import mondrian.olap.Util; 13 import mondrian.rolap.StarPredicate; 14 import mondrian.rolap.RolapStar; 15 import mondrian.rolap.RolapLevel; 16 import mondrian.rolap.RolapMember; 17 18 import java.util.List ; 19 import java.util.ArrayList ; 20 import java.util.Map ; 21 import java.util.Arrays ; 22 23 30 public class MemberTuplePredicate implements StarPredicate { 31 private final Bound[] bounds; 32 private final List <RolapStar.Column> columnList; 33 34 49 public MemberTuplePredicate( 50 Map <RolapLevel, RolapStar.Column> levelToColumnMap, 51 RolapMember lower, 52 boolean lowerStrict, 53 RolapMember upper, 54 boolean upperStrict) 55 { 56 this.columnList = 57 computeColumnList( 58 lower != null ? lower : upper, 59 levelToColumnMap); 60 61 if (lower == null) { 62 assert upper != null; 63 bounds = new Bound[] { 64 new Bound(upper, upperStrict ? RelOp.LT : RelOp.LE) 65 }; 66 } else if (upper == null) { 67 bounds = new Bound[] { 68 new Bound(lower, lowerStrict ? RelOp.GT : RelOp.GE) 69 }; 70 } else { 71 bounds = new Bound[] { 72 new Bound(lower, lowerStrict ? RelOp.GT : RelOp.GE), 73 new Bound(upper, upperStrict ? RelOp.LT : RelOp.LE) 74 }; 75 } 76 } 77 78 85 public MemberTuplePredicate( 86 Map <RolapLevel, RolapStar.Column> levelToColumnMap, 87 RolapMember member) 88 { 89 this.columnList = 90 computeColumnList( 91 member, 92 levelToColumnMap); 93 94 this.bounds = new Bound[] { 95 new Bound(member, RelOp.EQ) 96 }; 97 } 98 99 public int hashCode() { 100 return this.columnList.hashCode() * 31 + 101 Arrays.hashCode(this.bounds) * 31; 102 } 103 104 public boolean equals(Object obj) { 105 if (obj instanceof MemberTuplePredicate) { 106 MemberTuplePredicate that = 107 (MemberTuplePredicate) obj; 108 return this.columnList.equals(that.columnList) && 109 Arrays.equals(this.bounds, that.bounds); 110 } else { 111 return false; 112 } 113 } 114 115 private List <RolapStar.Column> computeColumnList( 116 RolapMember member, 117 Map <RolapLevel, RolapStar.Column> levelToColumnMap) 118 { 119 List <RolapStar.Column> columnList = new ArrayList <RolapStar.Column>(); 120 while (true) { 121 RolapLevel level = member.getLevel(); 122 columnList.add(0, levelToColumnMap.get(level)); 123 if (level.isUnique()) { 124 return columnList; 125 } 126 member = member.getParentMember(); 127 } 128 } 129 130 135 public List <RolapStar.Column> getConstrainedColumnList() { 136 return columnList; 137 } 138 139 public boolean equalConstraint(StarPredicate that) { 140 throw new UnsupportedOperationException (); 141 } 142 143 public StarPredicate minus(StarPredicate predicate) { 144 throw new UnsupportedOperationException (); 145 } 146 147 153 public boolean evaluate(List <Object > valueList) { 154 for (Bound bound : bounds) { 155 for (int k = 0; k < bound.values.length; ++k) { 156 Object value = valueList.get(k); 157 if (value == WILDCARD) { 158 return false; 159 } 160 Object boundValue = bound.values[k]; 161 RelOp relOp = bound.relOps[k]; 162 int c = Util.compareKey(value, boundValue); 163 switch (relOp) { 164 case GT: 165 if (c > 0) { 166 break; 167 } else { 168 return false; 169 } 170 case GE: 171 if (c > 0) { 172 return true; 173 } else if (c == 0) { 174 break; 175 } else { 176 return false; 177 } 178 case LT: 179 if (c < 0) { 180 break; 181 } else { 182 return false; 183 } 184 case LE: 185 if (c < 0) { 186 return true; 187 } if (c == 0) { 188 break; 189 } else { 190 return false; 191 } 192 } 193 } 194 } 195 return true; 196 } 197 198 public void describe(StringBuilder buf) { 199 int k = 0; 200 for (Bound bound : bounds) { 201 if (k++ > 0) { 202 buf.append(" AND "); 203 } 204 buf.append(bound.relOps[bound.relOps.length - 1].getOp()); 205 buf.append(' '); 206 buf.append(bound.member); 207 } 208 } 209 210 private enum RelOp { 211 LT("<"), 212 LE("<="), 213 GT(">"), 214 GE(">="), 215 EQ("="); 216 217 private final String op; 218 219 RelOp(String op) { 220 this.op = op; 221 } 222 223 String getOp() { 224 return op; 225 } 226 } 227 228 private static class Bound { 229 private final RolapMember member; 230 private final Object [] values; 231 private final RelOp[] relOps; 232 233 Bound(RolapMember member, RelOp relOp) { 234 this.member = member; 235 List <Object > valueList = new ArrayList <Object >(); 236 List <RelOp> relOpList = new ArrayList <RelOp>(); 237 while (true) { 238 valueList.add(0, member.getKey()); 239 relOpList.add(0, relOp); 240 if (member.getLevel().isUnique()) { 241 break; 242 } 243 member = member.getParentMember(); 244 switch (relOp) { 245 case GT: 246 relOp = RelOp.GE; 247 break; 248 case LT: 249 relOp = RelOp.LE; 250 break; 251 } 252 } 253 this.values = valueList.toArray(new Object [valueList.size()]); 254 this.relOps = relOpList.toArray(new RelOp[relOpList.size()]); 255 } 256 257 258 public int hashCode() { 259 int h = member.hashCode(); 260 h = h * 31 + Arrays.hashCode(values); 261 h = h * 31 + Arrays.hashCode(relOps); 262 return h; 263 } 264 265 public boolean equals(Object obj) { 266 if (obj instanceof Bound) { 267 Bound that = (Bound) obj; 268 return this.member.equals(that.member) && 269 Arrays.equals(this.values, that.values) && 270 Arrays.equals(this.relOps, that.relOps); 271 } else { 272 return false; 273 } 274 } 275 } 276 } 277 278 | Popular Tags |