[hibernate-commits] Hibernate SVN: r14123 - core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp.

hibernate-commits at lists.jboss.org hibernate-commits at lists.jboss.org
Fri Oct 19 15:29:57 EDT 2007


Author: bstansberry at jboss.com
Date: 2007-10-19 15:29:57 -0400 (Fri, 19 Oct 2007)
New Revision: 14123

Modified:
   core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
Log:
Get rid of "never" go backwards enforcement, as preinvalidate()/invalidate() sequence is 99.99% likely to go backwards

Modified: core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java
===================================================================
--- core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2007-10-19 19:27:21 UTC (rev 14122)
+++ core/trunk/cache-jbosscache2/src/main/java/org/hibernate/cache/jbc2/timestamp/TimestampsRegionImpl.java	2007-10-19 19:29:57 UTC (rev 14123)
@@ -38,15 +38,13 @@
 
 /**
  * Defines the behavior of the timestamps cache region for JBossCache 2.x.
- * <p>
- * Maintains a local (authoritative) cache of timestamps along with the
- * distributed cache held in JBoss Cache. Listens for changes in the distributed
- * cache and updates the local cache accordingly. Ensures that any changes in
- * the local cache represent an increase in the timestamp. This approach allows
- * timestamp changes to be replicated asynchronously by JBoss Cache while still
- * preventing backward changes in timestamps.
- * </p>
  * 
+ * TODO Need to define a way to ensure asynchronous replication events
+ * do not result in timestamps moving backward, while dealing with the fact
+ * that the normal sequence of UpdateTimestampsCache.preinvalidate() then
+ * UpdateTimestampsCache.invalidate() will result in 2 calls to put() with
+ * the latter call having an earlier timestamp.
+ * 
  * @author Brian Stansberry
  * @version $Revision$
  */
@@ -54,9 +52,9 @@
 public class TimestampsRegionImpl extends TransactionalDataRegionAdapter implements TimestampsRegion {
 
     public static final String TYPE = "TS";
-    
-    private final Map localCache = new ConcurrentHashMap();
 
+    private Map localCache = new ConcurrentHashMap();
+    
     /**
      * Create a new TimestampsRegionImpl.
      * 
@@ -81,14 +79,12 @@
 
     public void evict(Object key) throws CacheException {
         // TODO Is this a valid operation on a timestamps cache?
-        localCache.remove(key);
         Option opt = getNonLockingDataVersionOption(true);
         CacheHelper.removeNode(getCacheInstance(), getRegionFqn(), key, opt);
     }
 
     public void evictAll() throws CacheException {
         // TODO Is this a valid operation on a timestamps cache?
-        localCache.clear();
         Option opt = getNonLockingDataVersionOption(true);
         CacheHelper.removeAll(getCacheInstance(), getRegionFqn(), opt);
         // Restore the region root node
@@ -97,50 +93,35 @@
 
     public Object get(Object key) throws CacheException {
 
-        Object timestamp = localCache.get(key);
-        if (timestamp == null) {
-            // Check the cluster-wide cache
-            // Don't hold the cache node lock throughout the tx, as that
-            // prevents updates
-            timestamp = suspendAndGet(key, null, false);
-            updateLocalCache(key, timestamp);
+        Object value = localCache.get(key);
+        if (value == null) {
+            value = suspendAndGet(key, null, false);
+            if (value != null)
+                localCache.put(key, value);
         }
-        return timestamp;
+        return value;
     }
 
     public void put(Object key, Object value) throws CacheException {
 
-        // Immediately update the local cache
-        boolean incremented = updateLocalCache(key, value);
-
-        if (incremented) {
-            // Now the cluster-wide cache
-
-            // TODO there's a race here where 2 threads can get through
-            // updateLocalCache() in proper sequence but then the earlier
-            // one updates JBC *later*. This should only affect newly
-            // joined nodes who populate their initial localCache from JBC.
-
-            // Don't hold the JBC node lock throughout the tx, as that
-            // prevents reads and other updates
-            Transaction tx = suspend();
-            try {
-                // TODO Why not use the timestamp in a DataVersion?
-                Option opt = getNonLockingDataVersionOption(false);
-                // We ensure ASYNC semantics (JBCACHE-1175)
-                opt.setForceAsynchronous(true);
-                CacheHelper.put(getCacheInstance(), getRegionFqn(), key, value, opt);
-            } catch (Exception e) {
-                throw new CacheException(e);
-            } finally {
-                resume(tx);
-            }
+        // Don't hold the JBC node lock throughout the tx, as that
+        // prevents reads and other updates
+        Transaction tx = suspend();
+        try {
+            // TODO Why not use the timestamp in a DataVersion?
+            Option opt = getNonLockingDataVersionOption(false);
+            // We ensure ASYNC semantics (JBCACHE-1175)
+            opt.setForceAsynchronous(true);
+            CacheHelper.put(getCacheInstance(), getRegionFqn(), key, value, opt);
+        } catch (Exception e) {
+            throw new CacheException(e);
+        } finally {
+            resume(tx);
         }
     }
 
     @Override
     public void destroy() throws CacheException {
-
         localCache.clear();
         getCacheInstance().removeCacheListener(this);
         super.destroy();
@@ -153,14 +134,14 @@
      */
     @NodeModified
     public void nodeModified(NodeModifiedEvent event) {
-        if (event.isOriginLocal() || event.isPre())
+        if (event.isPre())
             return;
 
         Fqn fqn = event.getFqn();
         Fqn regFqn = getRegionFqn();
         if (fqn.size() == regFqn.size() + 1 && fqn.isChildOf(regFqn)) {
             Object key = fqn.get(regFqn.size());
-            updateLocalCache(key, event.getData().get(ITEM));
+            localCache.put(key, event.getData().get(ITEM));
         }
     }
 
@@ -171,7 +152,7 @@
      */
     @NodeRemoved
     public void nodeRemoved(NodeRemovedEvent event) {
-        if (event.isOriginLocal() || event.isPre())
+        if (event.isPre())
             return;
 
         Fqn fqn = event.getFqn();
@@ -194,43 +175,4 @@
             get(key);
         }
     }
-
-    /**
-     * Updates the local cache, ensuring that the new value represents a higher
-     * value than the old (i.e. timestamp never goes back in time).
-     * 
-     * @param key
-     * @param value
-     */
-    private boolean updateLocalCache(Object key, Object value) {
-        if (value == null)
-            return false;
-
-        boolean increase = true;
-
-        long newVal = 0;
-        try {
-            newVal = ((Long) value).longValue();
-
-            Long oldVal = (Long) localCache.get(key);
-            increase = oldVal == null || newVal > oldVal.longValue();
-            if (increase) {
-                oldVal = (Long) localCache.put(key, value);
-                // Double check that it was an increase
-                if (oldVal != null && oldVal.longValue() > newVal) {                    
-                    // Nope; Restore the old value
-                    updateLocalCache(key, oldVal);
-                    increase = false;
-                }
-            }
-        } catch (ClassCastException cce) {
-            // TODO -- this is stupid; look into changing TimestampsRegion API
-            // not using Long; just store it
-            localCache.put(key, value);
-        }
-
-        return increase;
-
-    }
-
 }




More information about the hibernate-commits mailing list