[jbosscache-commits] JBoss Cache SVN: r8182 - in core/trunk/src/main/java/org/jboss/cache: interceptors and 1 other directory.

jbosscache-commits at lists.jboss.org jbosscache-commits at lists.jboss.org
Fri Aug 14 15:31:20 EDT 2009


Author: bstansberry at jboss.com
Date: 2009-08-14 15:31:20 -0400 (Fri, 14 Aug 2009)
New Revision: 8182

Modified:
   core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java
   core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyDataGravitatorInterceptor.java
Log:
[JBCACHE-1530] Give preference to non-DEAD owner backup data

Modified: core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java	2009-08-11 11:35:33 UTC (rev 8181)
+++ core/trunk/src/main/java/org/jboss/cache/commands/read/GravitateDataCommand.java	2009-08-14 19:31:20 UTC (rev 8182)
@@ -38,6 +38,7 @@
 import org.jboss.cache.marshall.NodeData;
 import org.jgroups.Address;
 
+import java.util.ArrayList;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Set;
@@ -121,7 +122,9 @@
             Set allGroupNames = getBackupRoots();
             if (allGroupNames != null)
             {
-               for (Object groupName : allGroupNames)
+               // JBCACHE-1530 -- give preference to non-dead owners
+               List<Object> sortedGroupNames = sortBackupRoots(allGroupNames);
+               for (Object groupName : sortedGroupNames)
                {
                   // groupName is the name of a buddy group since all child names in this
                   // collection are direct children of BUDDY_BACKUP_SUBTREE_FQN
@@ -214,6 +217,24 @@
       return backupSubtree.getChildrenNames();
    }
 
+   protected List<Object> sortBackupRoots(Set<Object> allGroupNames)
+   {
+      List<Object> sorted = new ArrayList<Object>(allGroupNames.size());
+      for (Object child : allGroupNames)
+      {
+         if (child instanceof String && ((String) child).endsWith(":DEAD") == false)
+         {
+            sorted.add(0, child);
+         }
+         else
+         {
+            sorted.add(child);
+         }
+            
+      }
+      return sorted;
+   }
+
    public Object acceptVisitor(InvocationContext ctx, Visitor visitor) throws Throwable
    {
       return visitor.visitGravitateDataCommand(ctx, this);

Modified: core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyDataGravitatorInterceptor.java
===================================================================
--- core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyDataGravitatorInterceptor.java	2009-08-11 11:35:33 UTC (rev 8181)
+++ core/trunk/src/main/java/org/jboss/cache/interceptors/LegacyDataGravitatorInterceptor.java	2009-08-14 19:31:20 UTC (rev 8182)
@@ -52,6 +52,7 @@
 import org.jgroups.blocks.GroupRequest;
 import org.jgroups.blocks.RspFilter;
 
+import java.util.Comparator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
@@ -378,10 +379,10 @@
          }
          else if (o instanceof GravitateResult)
          {
-            result = (GravitateResult) o;
-            if (result.isDataFound())
+            GravitateResult candidate = (GravitateResult) o;
+            if (isPreferable(candidate, result))
             {
-               break;
+               result = candidate;
             }
          } 
          else if (o == null)
@@ -404,6 +405,88 @@
       return result;
    }
 
+   /**
+    * JBCACHE-1530. Compares GravitateResults in order to prefer those not
+    * from dead owner trees.
+    * 
+    * @param candidate a result that might be preferable to <code>existing</code.  
+    *                  Cannot be <code>null</code>
+    * @param existing the currently preferred result. Cannot be <code>null</code>
+    * 
+    * @return <code>true</code> if <code>candidate</code> is preferable.
+    */
+   private boolean isPreferable(GravitateResult candidate, GravitateResult existing)
+   {
+      if (existing.isDataFound() == false)
+      {
+         return true;
+      }
+      else if (candidate.isDataFound() == false)
+      {
+         return false;
+      }
+      else 
+      {         
+         int ownerIndex = BuddyManager.BUDDY_BACKUP_SUBTREE_FQN.size();
+         
+         Fqn<?> existingFqn = existing.getBuddyBackupFqn();
+         String existingOwner = (existingFqn.size() > ownerIndex ? (String) existingFqn.get(ownerIndex) : null);
+         if (existingOwner == null)
+         {
+            return true;
+         }
+         
+         boolean existingDead = existingOwner.endsWith(":DEAD");
+         
+         Fqn<?> candidateFqn = candidate.getBuddyBackupFqn();
+         String candidateOwner = (candidateFqn.size() > ownerIndex ? (String) candidateFqn.get(ownerIndex) : null);
+         if (candidateOwner == null)
+         {
+            log.warn("Could not find a data owner in backupFqn from " + candidate);
+            return false;
+         }
+         else if (candidateOwner.endsWith(":DEAD"))
+         {
+            if (existingDead)
+            {
+               // Both are dead. See if generational match matters
+               if (candidateOwner.equals(existingOwner))
+               {
+                  int genIndex = ownerIndex + 1;
+                  Object existGen = (existingFqn.size() > genIndex ? existingFqn.get(genIndex) : null);
+                  if ((existGen instanceof Integer) == false)
+                  {
+                     return true;                     
+                  }
+                  Object candGen = (candidateFqn.size() > genIndex ? candidateFqn.get(genIndex) : null);
+                  if ((candGen instanceof Integer) == false)
+                  {
+                     log.warn("Could not find a dead data owner generation in backupFqn from " + candidate);
+                     return false;                     
+                  }
+                  return ((Integer) candGen).intValue() > ((Integer) existGen).intValue();
+               }
+               else
+               {
+                  // No poing comparing generations of different dead owners
+                  // Just prefer what we already have
+                  return false;
+               }
+            }
+            else               
+            {
+               // Prefer non-dead existing
+               return false;
+            }
+         }
+         else
+         {
+            // Candidate isn't dead but we prefer what we already have if it's not dead
+            return existingDead;
+         }         
+      }
+   }
+
    @SuppressWarnings("unchecked")
    private void createNode(List<NodeData> nodeData) throws CacheException
    {
@@ -488,4 +571,42 @@
          return memberCount > 1;
       }
    }
+   
+   private static class GravitationResponseComparator implements Comparator<Object>
+   {
+      public int compare(Object o1, Object o2)
+      {
+         if (o1 instanceof GravitateResult)
+         {
+            if (o2 instanceof GravitateResult)
+            {
+               GravitateResult g2 = (GravitateResult) o2;
+               if (g2.isDataFound() == false)
+               {
+                  return -1;
+               }
+               else
+               {
+                  return comparePositiveResults((GravitateResult) o1, g2);
+               }
+            }
+            else
+            {
+               return -1; // put GR before non-GR
+            }
+         }
+         else
+         {
+            return 1; // put misc stuff at the end
+         }
+      }
+
+      private int comparePositiveResults(GravitateResult g1, GravitateResult g2)
+      {
+         Fqn<?> f1 = g1.getBuddyBackupFqn();
+         Fqn<?> f2 = g2.getBuddyBackupFqn();
+         return -1;
+      }
+      
+   }
 }



More information about the jbosscache-commits mailing list