1 package org.hibernate.cache; 3 4 import java.io.Serializable ; 5 import java.util.ArrayList ; 6 import java.util.List ; 7 import java.util.Properties ; 8 import java.util.Set ; 9 10 import org.apache.commons.logging.Log; 11 import org.apache.commons.logging.LogFactory; 12 13 import org.hibernate.HibernateException; 14 import org.hibernate.cfg.Settings; 15 import org.hibernate.engine.SessionImplementor; 16 import org.hibernate.type.Type; 17 import org.hibernate.type.TypeFactory; 18 19 27 public class StandardQueryCache implements QueryCache { 28 29 private static final Log log = LogFactory.getLog(StandardQueryCache.class); 30 31 private Cache queryCache; 32 private UpdateTimestampsCache updateTimestampsCache; 33 private final String regionName; 34 35 public void clear() throws CacheException { 36 queryCache.clear(); 37 } 38 39 public StandardQueryCache( 40 final Settings settings, 41 final Properties props, 42 final UpdateTimestampsCache updateTimestampsCache, 43 String regionName) 44 throws HibernateException { 45 46 if (regionName==null) regionName = StandardQueryCache.class.getName(); 47 String prefix = settings.getCacheRegionPrefix(); 48 if (prefix!=null) regionName = prefix + '.' + regionName; 49 50 log.info("starting query cache at region: " + regionName); 51 52 this.queryCache = settings.getCacheProvider().buildCache(regionName, props); 53 this.updateTimestampsCache = updateTimestampsCache; 54 this.regionName = regionName; 55 } 56 57 public void put(QueryKey key, Type[] returnTypes, List result, SessionImplementor session) 58 throws HibernateException { 59 if ( log.isDebugEnabled() ) log.debug("caching query results in region: " + regionName); 60 List cacheable = new ArrayList ( result.size()+1 ); 61 cacheable.add( new Long ( session.getTimestamp() ) ); 62 for ( int i=0; i<result.size(); i++ ) { 63 if ( returnTypes.length==1 ) { 64 cacheable.add( returnTypes[0].disassemble( result.get(i), session, null ) ); 65 } 66 else { 67 cacheable.add( TypeFactory.disassemble( (Object []) result.get(i), returnTypes, session, null ) ); 68 } 69 } 70 queryCache.put(key, cacheable); 71 } 72 73 public List get(QueryKey key, Type[] returnTypes, boolean isNaturalKeyLookup, Set spaces, SessionImplementor session) 74 throws HibernateException { 75 if ( log.isDebugEnabled() ) log.debug("checking cached query results in region: " + regionName); 76 List cacheable = (List ) queryCache.get(key); 77 if (cacheable==null) { 78 log.debug("query results were not found in cache"); 79 return null; 80 } 81 List result = new ArrayList ( cacheable.size()-1 ); 82 Long timestamp = (Long ) cacheable.get(0); 83 log.debug("Checking query spaces for up-to-dateness: [" + spaces + "]"); 84 if ( !isNaturalKeyLookup && !isUpToDate(spaces, timestamp) ) { 85 log.debug("cached query results were not up to date"); 86 return null; 87 } 88 log.debug("returning cached query results"); 89 for ( int i=1; i<cacheable.size(); i++ ) { 90 if ( returnTypes.length==1 ) { 91 result.add( returnTypes[0].assemble( (Serializable ) cacheable.get(i), session, null ) ); 92 } 93 else { 94 result.add( TypeFactory.assemble( (Serializable []) cacheable.get(i), returnTypes, session, null ) ); 95 } 96 } 97 return result; 98 } 99 100 protected boolean isUpToDate(Set spaces, Long timestamp) { 101 return updateTimestampsCache.isUpToDate(spaces, timestamp); 102 } 103 104 public void destroy() { 105 try { 106 queryCache.destroy(); 107 } 108 catch (Exception e) { 109 log.warn("could not destroy query cache: " + regionName, e); 110 } 111 } 112 113 public Cache getCache() { 114 return queryCache; 115 } 116 117 public String getRegionName() { 118 return regionName; 119 } 120 121 public String toString() { 122 return "StandardQueryCache(" + regionName + ')'; 123 } 124 125 } 126 | Popular Tags |