[jbosscache-commits] JBoss Cache SVN: r5697 - in core/trunk/src: main/java/org/jboss/cache/buddyreplication and 4 other directories.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Apr 25 13:50:41 EDT 2008


Author: manik.surtani at jboss.com
Date: 2008-04-25 13:50:41 -0400 (Fri, 25 Apr 2008)
New Revision: 5697

Added:
   core/trunk/src/main/java/org/jboss/cache/interceptors/BuddyRegionAwareEvictionInterceptor.java
   core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyFqnTransformerTest.java
   core/trunk/src/test/java/org/jboss/cache/buddyreplication/EvictionOfBuddyBackupsTest.java
Modified:
   core/trunk/src/main/java/org/jboss/cache/Fqn.java
   core/trunk/src/main/java/org/jboss/cache/Region.java
   core/trunk/src/main/java/org/jboss/cache/RegionImpl.java
   core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java
   core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java
   core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
Log:
JBCACHE-1190 -  Eviction configuration should consider buddy backup regions as well.

Modified: core/trunk/src/main/java/org/jboss/cache/Fqn.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Fqn.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/Fqn.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -413,7 +413,11 @@
     */
    public Fqn<E> getSubFqn(int startIndex, int endIndex)
    {
-      return new Fqn<E>(true, elements.subList(startIndex, endIndex), true);
+      List el = elements.subList(startIndex, endIndex);
+      if (containsStrings(el))
+         return new StringFqn(el);
+      else
+         return new Fqn<E>(true, el, true);
    }
 
    /**
@@ -639,7 +643,7 @@
             builder.append(e);
          }
       }
-      return builder.toString();
+      return builder.length() == 0 ? SEPARATOR : builder.toString();
    }
 
 

Modified: core/trunk/src/main/java/org/jboss/cache/Region.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/Region.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/Region.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -31,7 +31,7 @@
  * @see org.jboss.cache.RegionManager
  * @since 2.0.0
  */
-public interface Region extends Comparable<Region>
+public interface Region extends Comparable<Region>, Cloneable
 {
 
    /**
@@ -203,6 +203,7 @@
 
    /**
     * A mechanism to set status of a region, more fine grained control than just setActive();
+    *
     * @param status status of the region
     * @since 2.1.0
     */
@@ -213,4 +214,6 @@
     */
    Status getStatus();
 
+   Region clone(Fqn cloneFqn);
+
 }

Modified: core/trunk/src/main/java/org/jboss/cache/RegionImpl.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/RegionImpl.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/RegionImpl.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -30,7 +30,7 @@
    private static final Log log = LogFactory.getLog(RegionImpl.class);
 
    private final RegionManager regionManager;
-   private final Fqn fqn;
+   private Fqn fqn;
    private Status status;
    private ClassLoader classLoader;
    private BlockingQueue<EvictedEventNode> nodeEventQueue = null;
@@ -259,4 +259,29 @@
          return null;
       }
    }
+
+   public RegionImpl clone(Fqn newRoot)
+   {
+      RegionImpl clone = null;
+      try
+      {
+         clone = (RegionImpl) super.clone();
+         clone.policy = policy;
+         clone.configuration = configuration;
+         clone.status = status;
+         clone.fqn = Fqn.fromRelativeFqn(newRoot, fqn);
+         // we also need to copy all of the eviction event nodes to the clone's queue
+         clone.createQueue();
+         for (EvictedEventNode een : this.nodeEventQueue)
+         {
+            EvictedEventNode cloneEEN = een.clone(newRoot);
+            clone.putNodeEvent(cloneEEN);
+         }
+      }
+      catch (CloneNotSupportedException e)
+      {
+         // problems cloning?  Should never get here.
+      }
+      return clone;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/buddyreplication/BuddyFqnTransformer.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -378,4 +378,21 @@
    {
       return address.toString().replace(':', '_');
    }
+
+   /**
+    * Returns the buddy backp root portion of a given Fqn, provided it is a backup Fqn.  If it is not a backup Fqn, Fqn.ROOT is returned.
+    *
+    * @param fqn fqn
+    */
+   public static Fqn getBackupRootFromFqn(Fqn fqn)
+   {
+      if (isBackupFqn(fqn))
+      {
+         return fqn.getSubFqn(0, isDeadBackupFqn(fqn) ? 3 : 2);
+      }
+      else
+      {
+         return Fqn.ROOT;
+      }
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/eviction/EvictedEventNode.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -15,7 +15,7 @@
  * @author Daniel Huang (dhuang at jboss.org)
  * @see org.jboss.cache.Region
  */
-public class EvictedEventNode
+public class EvictedEventNode implements Cloneable
 {
    private Fqn fqn_;
    private NodeEventType type_;
@@ -98,4 +98,19 @@
    {
       return "EvictedEN[fqn=" + fqn_ + " event=" + type_ + " diff=" + elementDifference_ + "]";
    }
+
+   public EvictedEventNode clone(Fqn cloneFqn)
+   {
+      EvictedEventNode clone = null;
+      try
+      {
+         clone = (EvictedEventNode) super.clone();
+         clone.setFqn(Fqn.fromRelativeFqn(cloneFqn, fqn_));
+      }
+      catch (CloneNotSupportedException e)
+      {
+         // should never get here
+      }
+      return clone;
+   }
 }

Modified: core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/factories/InterceptorChainFactory.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -41,7 +41,8 @@
       {
          chainedInterceptor = clazz.newInstance();
          componentRegistry.registerComponent(clazz.getName(), chainedInterceptor, clazz);
-      } else
+      }
+      else
       {
          // wipe next/last chaining!!
          chainedInterceptor.setNext(null);
@@ -92,7 +93,8 @@
          {
             interceptorChain.appendIntereceptor(createInterceptor(ActivationInterceptor.class));
             interceptorChain.appendIntereceptor(createInterceptor(PassivationInterceptor.class));
-         } else
+         }
+         else
          {
             interceptorChain.appendIntereceptor(createInterceptor(CacheLoaderInterceptor.class));
             interceptorChain.appendIntereceptor(createInterceptor(CacheStoreInterceptor.class));
@@ -110,7 +112,7 @@
       }
       // eviction interceptor to come before the optimistic node interceptor
       if (configuration.getEvictionConfig() != null && configuration.getEvictionConfig().isValidConfig())
-         interceptorChain.appendIntereceptor(createInterceptor(EvictionInterceptor.class));
+         interceptorChain.appendIntereceptor(createInterceptor(configuration.isUsingBuddyReplication() ? BuddyRegionAwareEvictionInterceptor.class : EvictionInterceptor.class));
 
       if (optimistic) interceptorChain.appendIntereceptor(createInterceptor(OptimisticNodeInterceptor.class));
       ChainedInterceptor callInterceptor = createInterceptor(CallInterceptor.class);

Added: core/trunk/src/main/java/org/jboss/cache/interceptors/BuddyRegionAwareEvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/BuddyRegionAwareEvictionInterceptor.java	                        (rev 0)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/BuddyRegionAwareEvictionInterceptor.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -0,0 +1,41 @@
+package org.jboss.cache.interceptors;
+
+import org.jboss.cache.Fqn;
+import org.jboss.cache.Region;
+import org.jboss.cache.buddyreplication.BuddyFqnTransformer;
+import org.jboss.cache.eviction.NodeEventType;
+
+/**
+ * A subclass of EvictionInterceptor that is aware of and able to deal with buddy regions.
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.2.0
+ */
+public class BuddyRegionAwareEvictionInterceptor extends EvictionInterceptor
+{
+   @Override
+   protected Region getRegion(Fqn fqn, NodeEventType type)
+   {
+      Region r = super.getRegion(fqn, type);
+      if (r != null)
+         return r;
+      else if (BuddyFqnTransformer.isBackupFqn(fqn))
+      {
+         // try and grab a backup region, creating one if need be.
+         Fqn actualFqn = BuddyFqnTransformer.getActualFqn(fqn);
+         Fqn backupRoot = BuddyFqnTransformer.getBackupRootFromFqn(fqn);
+
+         // the actual region could be a few levels higher than actualFqn
+         Region actualRegion = regionManager.getRegion(actualFqn, Region.Type.EVICTION, false);
+
+         if (actualRegion == null) return null;
+
+         //create a new region for this backup
+         Region newRegion = regionManager.getRegion(Fqn.fromRelativeFqn(backupRoot, actualRegion.getFqn()), Region.Type.EVICTION, true);
+         newRegion.setEvictionPolicy(actualRegion.getEvictionPolicyConfig());
+
+         return newRegion;
+      }
+      else return null;
+   }
+}

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2008-04-25 15:11:04 UTC (rev 5696)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/EvictionInterceptor.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -70,9 +70,10 @@
       boolean complete = (retVal != null && (Boolean) retVal);
       if (!complete)
       {
-         if (fqn != null && !canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT))
+         Region r;
+         if (fqn != null && (r = getRegion(fqn, NodeEventType.ADD_NODE_EVENT)) != null)
          {
-            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, 0), ctx);
+            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, 0), r);
          }
       }
       return retVal;
@@ -82,9 +83,10 @@
    public Object handlePutKeyValueCommand(InvocationContext ctx, PutKeyValueCommand command) throws Throwable
    {
       Object retVal = invokeNextInterceptor(ctx, command);
-      if (command.getFqn() != null && command.getKey() != null && !canIgnoreEvent(command.getFqn(), NodeEventType.ADD_ELEMENT_EVENT))
+      Region r;
+      if (command.getFqn() != null && command.getKey() != null && (r = getRegion(command.getFqn(), NodeEventType.ADD_ELEMENT_EVENT)) != null)
       {
-         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.ADD_ELEMENT_EVENT, 1), ctx);
+         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.ADD_ELEMENT_EVENT, 1), r);
       }
       return retVal;
    }
@@ -94,7 +96,8 @@
    {
       Object retVal = invokeNextInterceptor(ctx, command);
       Fqn fqn = command.getFqn();
-      if (fqn != null && !canIgnoreEvent(fqn, NodeEventType.ADD_NODE_EVENT))
+      Region r;
+      if (fqn != null && (r = getRegion(fqn, NodeEventType.ADD_NODE_EVENT)) != null)
       {
          if (command.getData() == null)
          {
@@ -112,7 +115,7 @@
             }
             EvictedEventNode event = new EvictedEventNode(fqn, NodeEventType.ADD_NODE_EVENT, size);
             event.setResetElementCount(command.isEraseContents());
-            registerEvictionEventToRegionManager(event, ctx);
+            registerEvictionEventToRegionManager(event, r);
          }
       }
       return retVal;
@@ -133,9 +136,10 @@
       else
       {
          Fqn fqn = command.getFqn();
-         if (fqn != null && command.getKey() != null && !canIgnoreEvent(fqn, NodeEventType.REMOVE_ELEMENT_EVENT))
+         Region r = null;
+         if (fqn != null && command.getKey() != null && (r = getRegion(fqn, NodeEventType.REMOVE_ELEMENT_EVENT)) != null)
          {
-            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.REMOVE_ELEMENT_EVENT, 1), ctx);
+            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.REMOVE_ELEMENT_EVENT, 1), r);
          }
       }
       return retVal;
@@ -159,9 +163,10 @@
       }
       else
       {
-         if (fqn != null && !canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
+         Region r;
+         if (fqn != null && (r = getRegion(fqn, NodeEventType.VISIT_NODE_EVENT)) != null)
          {
-            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT), ctx);
+            registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT), r);
          }
       }
       return retVal;
@@ -179,6 +184,7 @@
    {
       Object retVal = invokeNextInterceptor(ctx, command);
       Fqn fqn = command.getFqn();
+      Region r;
       if (retVal == null)
       {
          if (trace)
@@ -186,9 +192,9 @@
             log.trace("No event added. Element does not exist");
          }
       }
-      else if (fqn != null && command.getKey() != null && !canIgnoreEvent(fqn, NodeEventType.VISIT_NODE_EVENT))
+      else if (fqn != null && command.getKey() != null && (r = getRegion(fqn, NodeEventType.VISIT_NODE_EVENT)) != null)
       {
-         registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT), ctx);
+         registerEvictionEventToRegionManager(new EvictedEventNode(fqn, NodeEventType.VISIT_NODE_EVENT), r);
       }
       return retVal;
    }
@@ -197,9 +203,10 @@
    public Object handleRemoveNodeCommand(InvocationContext ctx, RemoveNodeCommand command) throws Throwable
    {
       Object retVal = invokeNextInterceptor(ctx, command);
-      if (command.getFqn() != null && !canIgnoreEvent(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT))
+      Region r;
+      if (command.getFqn() != null && (r = getRegion(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT)) != null)
       {
-         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT), ctx);
+         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT), r);
       }
       return retVal;
    }
@@ -208,14 +215,15 @@
    public Object handleRemoveDataCommand(InvocationContext ctx, RemoveDataCommand command) throws Throwable
    {
       Object retVal = invokeNextInterceptor(ctx, command);
-      if (command.getFqn() != null && !canIgnoreEvent(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT))
+      Region r;
+      if (command.getFqn() != null && (r = getRegion(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT)) != null)
       {
-         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT), ctx);
+         registerEvictionEventToRegionManager(new EvictedEventNode(command.getFqn(), NodeEventType.REMOVE_NODE_EVENT), r);
       }
       return retVal;
    }
 
-   private void registerEvictionEventToRegionManager(EvictedEventNode event, InvocationContext ctx)
+   private void registerEvictionEventToRegionManager(EvictedEventNode event, Region region)
    {
       if (event == null)
       {
@@ -230,7 +238,6 @@
          return;
       }
 
-      Region region = regionManager.getRegion(event.getFqn(), false);
       region.putNodeEvent(event);
 
       if (trace)
@@ -244,10 +251,10 @@
       }
    }
 
-   protected boolean canIgnoreEvent(Fqn fqn, NodeEventType type)
+   protected Region getRegion(Fqn fqn, NodeEventType type)
    {
       Region r = regionManager.getRegion(fqn, Region.Type.EVICTION, false);
-      // should never happen, we should at least get the default region.
-      return r == null || r.getEvictionPolicy().canIgnoreEvent(fqn, type);
+      if (r != null && r.getEvictionPolicy().canIgnoreEvent(fqn, type)) return null;
+      return r;
    }
 }

Added: core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyFqnTransformerTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyFqnTransformerTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/buddyreplication/BuddyFqnTransformerTest.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -0,0 +1,30 @@
+package org.jboss.cache.buddyreplication;
+
+import org.jboss.cache.Fqn;
+import org.testng.annotations.Test;
+
+/**
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.2.0
+ */
+ at Test(groups = "functional")
+public class BuddyFqnTransformerTest
+{
+   public void testActualFqn()
+   {
+      Fqn backupFqn = Fqn.fromString("/_BUDDY_BACKUP_/1.2.3.4_5678/a/b/c/d");
+      assert BuddyFqnTransformer.getActualFqn(backupFqn).equals(Fqn.fromString("/a/b/c/d"));
+
+      backupFqn = Fqn.fromString("/_BUDDY_BACKUP_/1.2.3.4_5678");
+
+      Fqn actual = BuddyFqnTransformer.getActualFqn(backupFqn);
+
+      assert actual.equals(Fqn.ROOT);
+   }
+
+   public void testBackupRootFqn()
+   {
+      Fqn backupFqn = Fqn.fromString("/_BUDDY_BACKUP_/1.2.3.4_5678/a/b/c/d");
+      assert BuddyFqnTransformer.getBackupRootFromFqn(backupFqn).equals(Fqn.fromString("/_BUDDY_BACKUP_/1.2.3.4_5678")) : "Got " + BuddyFqnTransformer.getBackupRootFromFqn(backupFqn);
+   }
+}

Added: core/trunk/src/test/java/org/jboss/cache/buddyreplication/EvictionOfBuddyBackupsTest.java
===================================================================
--- core/trunk/src/test/java/org/jboss/cache/buddyreplication/EvictionOfBuddyBackupsTest.java	                        (rev 0)
+++ core/trunk/src/test/java/org/jboss/cache/buddyreplication/EvictionOfBuddyBackupsTest.java	2008-04-25 17:50:41 UTC (rev 5697)
@@ -0,0 +1,73 @@
+package org.jboss.cache.buddyreplication;
+
+import org.jboss.cache.CacheSPI;
+import org.jboss.cache.DefaultCacheFactory;
+import org.jboss.cache.Fqn;
+import org.jboss.cache.config.EvictionConfig;
+import org.jboss.cache.config.EvictionRegionConfig;
+import org.jboss.cache.eviction.LRUConfiguration;
+import org.jboss.cache.eviction.NullEvictionPolicy;
+import org.jboss.cache.misc.TestingUtil;
+import org.testng.annotations.AfterTest;
+import org.testng.annotations.BeforeTest;
+import org.testng.annotations.Test;
+
+import java.util.Collections;
+
+/**
+ * Tests the eviction of buddy backup regions
+ *
+ * @author Manik Surtani (<a href="mailto:manik at jboss.org">manik at jboss.org</a>)
+ * @since 2.2.0
+ */
+ at Test(groups = "functional")
+public class EvictionOfBuddyBackupsTest extends BuddyReplicationTestsBase
+{
+   private CacheSPI cache1, cache2;
+   private Fqn fqn = Fqn.fromString("/a/b/c");
+
+   @BeforeTest
+   public void setUp() throws Exception
+   {
+      cache1 = createCache(1, null, true, false);
+      cache1.getConfiguration().setEvictionConfig(getEvictionConfig());
+      cache1.start();
+
+      cache2 = (CacheSPI) new DefaultCacheFactory().createCache(cache1.getConfiguration().clone());
+
+      TestingUtil.blockUntilViewsReceived(60000, cache1, cache2);
+   }
+
+   @AfterTest
+   public void tearDown()
+   {
+      TestingUtil.killCaches(cache1, cache2);
+   }
+
+   private EvictionConfig getEvictionConfig()
+   {
+      EvictionConfig c = new EvictionConfig();
+      c.setDefaultEvictionPolicyClass(NullEvictionPolicy.class.getName());
+      c.setWakeupIntervalSeconds(1);
+      LRUConfiguration epc = new LRUConfiguration();
+      epc.setMaxAgeSeconds(1);
+      epc.setTimeToLiveSeconds(1);
+      EvictionRegionConfig erc = new EvictionRegionConfig(fqn, epc);
+      c.setEvictionRegionConfigs(Collections.singletonList(erc));
+      return c;
+   }
+
+
+   public void testEvictionOfBackupRegions() throws Exception
+   {
+      cache1.put(fqn, "k", "v");
+      assert cache1.peek(fqn, false, false) != null : "Node should exist";
+      assert cache2.peek(BuddyFqnTransformer.getBackupFqn(cache1.getLocalAddress(), fqn), false, false) != null : "Node should exist on backup";
+
+      // now wait for eviction to kick in - for up to 2 secs
+      TestingUtil.sleepThread(2000);
+
+      assert cache1.peek(fqn, false, false) == null : "Node should have evicted";
+      assert cache2.peek(BuddyFqnTransformer.getBackupFqn(cache1.getLocalAddress(), fqn), false, false) == null : "Node should have evicted on backup";
+   }
+}




More information about the jbosscache-commits mailing list