Cache invalidation patch from Zell.

git-svn-id: https://samskivert.googlecode.com/svn/trunk@2055 6335cc39-0255-0410-8fd6-9bcaacd3b74c
This commit is contained in:
mdb
2007-02-19 19:30:48 +00:00
parent 028d9ebfe8
commit e37cc33d68
@@ -52,16 +52,28 @@ public class PersistenceContext
public HashMap<String, TableGenerator> tableGenerators = new HashMap<String, TableGenerator>();
/**
* A cache listener is notified when cache entries are invalited through creation, deletion,
* or modification. Its purpose is typically to do further invalidation of dependent entries
* in other caches.
* A cache listener is notified when cache entries change. Its purpose is typically to do
* further invalidation of dependent entries in other caches.
*/
public static interface CacheListener<T>
{
/**
* The given entry has just been deleted, modified or created. Do what thou wilt.
* The given entry (which is never null) has just been evicted from the cache slot
* indicated by the given key.
*
* This method is most commonly used to trigger custom cache invalidation of records that
* depend on the one that was just invalidated.
*/
public void entryModified (CacheKey key, T entry);
public void entryInvalidated (CacheKey key, T oldEntry);
/**
* The given entry, which may be an explicit null, has just been placed into the cache
* under the given key. The previous cache entry, if any, is also supplied.
*
* This method is most likely used by repositories to index entries by attribute for quick
* cache invalidation when brute force is unrealistically time consuming.
*/
public void entryCached (CacheKey key, T newEntry, T oldEntry);
}
/**
@@ -222,25 +234,33 @@ public class PersistenceContext
/**
* Stores a new entry indexed by the given key.
*/
public <T> void cacheStore (CacheKey key, T value)
public <T> void cacheStore (CacheKey key, T entry)
{
Log.debug("cacheStore: entry [key=" + key + ", value=" + value + "]");
getCache(key.getCacheId()).put(new Element(key.getCacheKey(), value));
Log.debug("cacheStore: entry [key=" + key + ", value=" + entry + "]");
// first do cascading invalidations
// find the old entry, if any
Cache cache = getCache(key.getCacheId());
Element element = cache.get(key.getCacheKey());
@SuppressWarnings("unchecked") T oldEntry =
(element != null ? (T) element.getValue() : null);
// update the cache
cache.put(new Element(key.getCacheKey(), entry));
// then do cache invalidations
Set<CacheListener<?>> listeners = _listenerSets.get(key.getCacheId());
if (listeners != null && listeners.size() > 0) {
for (CacheListener<?> listener : listeners) {
Log.debug("cacheInvalidate: cascading [listener=" + listener + "]");
@SuppressWarnings("unchecked") CacheListener<T> casted = (CacheListener<T>)listener;
casted.entryModified(key, value);
casted.entryCached(key, entry, oldEntry);
}
}
}
/**
* Evicts the cache entry indexed under the given key, if there is one.
* The eviction may trigger further cache invalidations.
* Evicts the cache entry indexed under the given key, if there is one. The eviction may
* trigger further cache invalidations.
*/
public void cacheInvalidate (CacheKey key)
{
@@ -248,8 +268,8 @@ public class PersistenceContext
}
/**
* Evicts the cache entry indexed under the given class and cache key, if there is one.
* The eviction may trigger further cache invalidations.
* Evicts the cache entry indexed under the given class and cache key, if there is one. The
* eviction may trigger further cache invalidations.
*/
public void cacheInvalidate (Class pClass, Serializable cacheKey)
{
@@ -257,33 +277,38 @@ public class PersistenceContext
}
/**
* Evicts the cache entry indexed under the given cache id and cache key, if there is one.
* The eviction may trigger further cache invalidations.
* Evicts the cache entry indexed under the given cache id and cache key, if there is one. The
* eviction may trigger further cache invalidations.
*/
public <T extends Serializable> void cacheInvalidate (String cacheId, Serializable cacheKey)
{
Log.debug("cacheInvalidate: entry [cacheId=" + cacheId + ", cacheKey=" + cacheKey + "]");
Cache cache = getCache(cacheId);
Element element = cache.get(cacheKey);
if (element == null) {
return;
}
// first do cascading invalidations
Set<CacheListener<?>> listeners = _listenerSets.get(cacheId);
if (listeners != null && listeners.size() > 0) {
CacheKey key = new SimpleCacheKey(cacheId, cacheKey);
for (CacheListener<?> listener : listeners) {
Log.debug("cacheInvalidate: cascading [listener=" + listener + "]");
@SuppressWarnings("unchecked") CacheListener<T> casted = (CacheListener<T>)listener;
@SuppressWarnings("unchecked") T value =
(element != null ? (T) element.getValue() : null);
casted.entryModified(key, value);
// find the old entry, if any
@SuppressWarnings("unchecked") T oldEntry = (T) element.getValue();
if (oldEntry != null) {
// if there was one, do (possibly cascading) cache invalidations
Set<CacheListener<?>> listeners = _listenerSets.get(cacheId);
if (listeners != null && listeners.size() > 0) {
CacheKey key = new SimpleCacheKey(cacheId, cacheKey);
for (CacheListener<?> listener : listeners) {
Log.debug("cacheInvalidate: cascading [listener=" + listener + "]");
@SuppressWarnings("unchecked") CacheListener<T> casted =
(CacheListener<T>)listener;
casted.entryInvalidated(key, oldEntry);
}
}
}
// then evict the keyed entry, if needed
if (element != null) {
Log.debug("cacheInvalidate: evicting [cacheKey=" + cacheKey + "]");
cache.remove(cacheKey);
}
Log.debug("cacheInvalidate: evicting [cacheKey=" + cacheKey + "]");
cache.remove(cacheKey);
}
/**