FileDocCategorySizeDatePackage
UpdateTimestampsCache.javaAPI DocHibernate 3.2.53955Wed Nov 15 07:44:34 GMT 2006org.hibernate.cache

UpdateTimestampsCache

public class UpdateTimestampsCache extends Object
Tracks the timestamps of the most recent updates to particular tables. It is important that the cache timeout of the underlying cache implementation be set to a higher value than the timeouts of any of the query caches. In fact, we recommend that the the underlying cache not be configured for expiry at all. Note, in particular, that an LRU cache expiry policy is never appropriate.
author
Gavin King
author
Mikheil Kapanadze

Fields Summary
public static final String
REGION_NAME
private static final Log
log
private Cache
updateTimestamps
private final String
regionName
Constructors Summary
public UpdateTimestampsCache(org.hibernate.cfg.Settings settings, Properties props)

		String prefix = settings.getCacheRegionPrefix();
		regionName = prefix == null ? REGION_NAME : prefix + '." + REGION_NAME;
		log.info( "starting update timestamps cache at region: " + regionName );
		this.updateTimestamps = settings.getCacheProvider().buildCache( regionName, props );
	
Methods Summary
public voidclear()


	     
		updateTimestamps.clear();
	
public voiddestroy()

		try {
			updateTimestamps.destroy();
		}
		catch (Exception e) {
			log.warn("could not destroy UpdateTimestamps cache", e);
		}
	
public CachegetCache()

		return updateTimestamps;
	
public java.lang.StringgetRegionName()

		return regionName;
	
public synchronized voidinvalidate(java.io.Serializable[] spaces)

	 	//TODO: to handle concurrent writes correctly, the client should pass in a Lock
		Long ts = new Long( updateTimestamps.nextTimestamp() );
		//TODO: if lock.getTimestamp().equals(ts)
		for ( int i=0; i<spaces.length; i++ ) {
			if ( log.isDebugEnabled() ) {
				log.debug( "Invalidating space [" + spaces[i] + "], timestamp: " + ts);
			}
			//put() has nowait semantics, is this really appropriate?
			//note that it needs to be async replication, never local or sync
			updateTimestamps.put( spaces[i], ts );
		}
	
public synchronized booleanisUpToDate(java.util.Set spaces, java.lang.Long timestamp)

		Iterator iter = spaces.iterator();
		while ( iter.hasNext() ) {
			Serializable space = (Serializable) iter.next();
			Long lastUpdate = (Long) updateTimestamps.get(space);
			if ( lastUpdate==null ) {
				//the last update timestamp was lost from the cache
				//(or there were no updates since startup!)
				//updateTimestamps.put( space, new Long( updateTimestamps.nextTimestamp() ) );
				//result = false; // safer
			}
			else {
				if ( log.isDebugEnabled() ) {
					log.debug("[" + space + "] last update timestamp: " + lastUpdate + ", result set timestamp: " + timestamp );
				}
				if ( lastUpdate.longValue() >= timestamp.longValue() ) {
					return false;
				}
			}
		}
		return true;
	
public synchronized voidpreinvalidate(java.io.Serializable[] spaces)

		//TODO: to handle concurrent writes correctly, this should return a Lock to the client
		Long ts = new Long( updateTimestamps.nextTimestamp() + updateTimestamps.getTimeout() );
		for ( int i=0; i<spaces.length; i++ ) {
			if ( log.isDebugEnabled() ) {
				log.debug( "Pre-invalidating space [" + spaces[i] + "]" );
			}
			//put() has nowait semantics, is this really appropriate?
			//note that it needs to be async replication, never local or sync
			updateTimestamps.put( spaces[i], ts );
		}
		//TODO: return new Lock(ts);
	
public java.lang.StringtoString()

		return "UpdateTimestampeCache";