Author: bstansberry(a)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;
+ }
+
+ }
}
Show replies by date