001 /* 002 // $Id: //open/mondrian/src/main/mondrian/rolap/SmartMemberListCache.java#6 $ 003 // This software is subject to the terms of the Common Public License 004 // Agreement, available at the following URL: 005 // http://www.opensource.org/licenses/cpl.html. 006 // Copyright (C) 2004-2005 TONBELLER AG 007 // All Rights Reserved. 008 // You must accept the terms of that agreement to use this software. 009 */ 010 package mondrian.rolap; 011 012 import mondrian.rolap.cache.SmartCache; 013 import mondrian.rolap.cache.SoftSmartCache; 014 import mondrian.rolap.sql.SqlConstraint; 015 016 /** 017 * Uses a {@link mondrian.rolap.cache.SmartCache} to store lists of members, 018 * where the key depends on a {@link mondrian.rolap.sql.SqlConstraint}. 019 * <p> 020 * Example 1 021 * <pre> 022 * select ... 023 * [Customer].[Name].members on rows 024 * ... 025 * </pre> 026 * Example 2 027 * <pre> 028 * select ... 029 * NON EMPTY [Customer].[Name].members on rows 030 * ... 031 * WHERE ([Store#14], [Product].[Product#1]) 032 * </pre> 033 * 034 * The first set, <em>all</em> customers are computed, in the second only those, who 035 * have bought Product#1 in Store#14. We want to put both results into the cache. Then the 036 * key for the cache entry is the Level that the members belong to <em>plus</em> the 037 * costraint that restricted the amount of members fetched. For Level.Members the key 038 * consists of the Level and the cacheKey of the {@link mondrian.rolap.sql.SqlConstraint} 039 * 040 * @see mondrian.rolap.sql.SqlConstraint#getCacheKey 041 * 042 * @author av 043 * @since Nov 21, 2005 044 * @version $Id: //open/mondrian/src/main/mondrian/rolap/SmartMemberListCache.java#6 $ 045 */ 046 public class SmartMemberListCache <K, V> { 047 SmartCache<Key2<K, Object>, V> cache; 048 049 /** 050 * a HashMap key that consists of two components. 051 */ 052 static class Key2 <T1, T2> { 053 T1 o1; 054 T2 o2; 055 056 public Key2(T1 o1, T2 o2) { 057 this.o1 = o1; 058 this.o2 = o2; 059 } 060 061 public boolean equals(Object obj) { 062 if (!(obj instanceof Key2)) { 063 return false; 064 } 065 Key2 that = (Key2) obj; 066 return equals(this.o1, that.o1) && equals(this.o2, that.o2); 067 } 068 069 private boolean equals(Object o1, Object o2) { 070 return o1 == null ? o2 == null : o1.equals(o2); 071 } 072 073 public int hashCode() { 074 int c = 1; 075 if (o1 != null) { 076 c = o1.hashCode(); 077 } 078 if (o2 != null) { 079 c = 31 * c + o2.hashCode(); 080 } 081 return c; 082 } 083 084 public String toString() { 085 return "key(" + o1 + "," + o2 + ")"; 086 } 087 } 088 089 public SmartMemberListCache() { 090 cache = new SoftSmartCache<Key2<K, Object>, V>(); 091 } 092 093 public Object put(K key, SqlConstraint constraint, V value) { 094 Object cacheKey = constraint.getCacheKey(); 095 if (cacheKey == null) { 096 return null; 097 } 098 Key2<K, Object> key2 = new Key2<K, Object>(key, cacheKey); 099 return cache.put(key2, value); 100 } 101 102 public V get(K key, SqlConstraint constraint) { 103 Key2<K, Object> key2 = new Key2<K, Object>(key, constraint.getCacheKey()); 104 return cache.get(key2); 105 } 106 107 public void clear() { 108 cache.clear(); 109 } 110 111 SmartCache<Key2<K, Object>, V> getCache() { 112 return cache; 113 } 114 115 void setCache(SmartCache<Key2<K, Object>, V> cache) { 116 this.cache = cache; 117 } 118 } 119 120 // End SmartMemberListCache.java