You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by jb...@apache.org on 2010/11/17 20:41:51 UTC

svn commit: r1036176 - in /cassandra/branches/cassandra-0.6: CHANGES.txt src/java/org/apache/cassandra/service/AntiEntropyService.java test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java

Author: jbellis
Date: Wed Nov 17 19:41:50 2010
New Revision: 1036176

URL: http://svn.apache.org/viewvc?rev=1036176&view=rev
Log:
limit repaired ranges to what the nodes have in common
patch by Stu Hood; reviewed by jbellis for CASSANDRA-1674

Modified:
    cassandra/branches/cassandra-0.6/CHANGES.txt
    cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/AntiEntropyService.java
    cassandra/branches/cassandra-0.6/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java

Modified: cassandra/branches/cassandra-0.6/CHANGES.txt
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/CHANGES.txt?rev=1036176&r1=1036175&r2=1036176&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/CHANGES.txt (original)
+++ cassandra/branches/cassandra-0.6/CHANGES.txt Wed Nov 17 19:41:50 2010
@@ -4,6 +4,7 @@
  * reject range queries received during bootstrap (CASSANDRA-1739)
  * fix wrapping-range queries on non-minimum token (CASSANDRA-1700)
  * add nodetool cfhistogram (CASSANDRA-1698)
+ * limit repaired ranges to what the nodes have in common (CASSAHDRA-1674)
 
 
 0.6.8

Modified: cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/AntiEntropyService.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/AntiEntropyService.java?rev=1036176&r1=1036175&r2=1036176&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/AntiEntropyService.java (original)
+++ cassandra/branches/cassandra-0.6/src/java/org/apache/cassandra/service/AntiEntropyService.java Wed Nov 17 19:41:50 2010
@@ -420,7 +420,7 @@ public class AntiEntropyService
         public final InetAddress remote;
         public final MerkleTree ltree;
         public final MerkleTree rtree;
-        public final List<MerkleTree.TreeRange> differences;
+        public final List<Range> differences;
 
         public Differencer(CFPair cf, InetAddress local, InetAddress remote, MerkleTree ltree, MerkleTree rtree)
         {
@@ -429,7 +429,7 @@ public class AntiEntropyService
             this.remote = remote;
             this.ltree = ltree;
             this.rtree = rtree;
-            differences = new ArrayList<MerkleTree.TreeRange>();
+            differences = new ArrayList<Range>();
         }
 
         /**
@@ -449,24 +449,15 @@ public class AntiEntropyService
             Set<Range> interesting = new HashSet(ss.getRangesForEndPoint(cf.left, local));
             interesting.retainAll(ss.getRangesForEndPoint(cf.left, remote));
 
-            // compare trees, and filter out uninteresting differences
+            // compare trees, and collect interesting differences
             for (MerkleTree.TreeRange diff : MerkleTree.difference(ltree, rtree))
-            {
                 for (Range localrange: interesting)
-                {
-                    if (diff.intersects(localrange))
-                    {
-                        differences.add(diff);
-                        break; // the inner loop
-                    }
-                }
-            }
+                    differences.addAll(diff.intersectionWith(localrange));
             
             // choose a repair method based on the significance of the difference
-            float difference = differenceFraction();
             try
             {
-                if (difference == 0.0)
+                if (differences.isEmpty())
                 {
                     logger.debug("Endpoints " + local + " and " + remote + " are consistent for " + cf);
                     return;
@@ -481,18 +472,6 @@ public class AntiEntropyService
         }
         
         /**
-         * @return the fraction of the keyspace that is different, as represented by our
-         * list of different ranges. A range at depth 0 == 1.0, at depth 1 == 0.5, etc.
-         */
-        float differenceFraction()
-        {
-            double fraction = 0.0;
-            for (MerkleTree.TreeRange diff : differences)
-                fraction += 1.0 / Math.pow(2, diff.depth);
-            return (float)fraction;
-        }
-
-        /**
          * Sends our list of differences to the remote endpoint using the
          * Streaming API.
          */

Modified: cassandra/branches/cassandra-0.6/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java
URL: http://svn.apache.org/viewvc/cassandra/branches/cassandra-0.6/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java?rev=1036176&r1=1036175&r2=1036176&view=diff
==============================================================================
--- cassandra/branches/cassandra-0.6/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java (original)
+++ cassandra/branches/cassandra-0.6/test/unit/org/apache/cassandra/service/AntiEntropyServiceTest.java Wed Nov 17 19:41:50 2010
@@ -73,7 +73,7 @@ public class AntiEntropyServiceTest exte
         aes = AntiEntropyService.instance;
         TokenMetadata tmd = StorageService.instance.getTokenMetadata();
         tmd.clearUnsafe();
-        tmd.updateNormalToken(StorageService.getPartitioner().getRandomToken(), LOCAL);
+        StorageService.instance.setToken(StorageService.getPartitioner().getRandomToken());
         tmd.updateNormalToken(StorageService.getPartitioner().getMinimumToken(), REMOTE);
         assert tmd.isMember(REMOTE);
     }
@@ -229,11 +229,16 @@ public class AntiEntropyServiceTest exte
         validator.complete();
         MerkleTree rtree = validator.tree;
 
-        // change a range in one of the trees
-        Token min = StorageService.instance.getPartitioner().getMinimumToken();
-        ltree.invalidate(min);
-        MerkleTree.TreeRange changed = ltree.invalids(new Range(min, min)).next();
+        // change a range we own in one of the trees
+        Token ltoken = StorageService.instance.getLocalToken();
+        ltree.invalidate(ltoken);
+        MerkleTree.TreeRange changed = ltree.invalids(StorageService.instance.getLocalPrimaryRange()).next();
         changed.hash("non-empty hash!".getBytes());
+        // the changed range has two halves, split on our local token: both will be repaired
+        // (since this keyspace has RF > N, so every node is responsible for the entire ring)
+        Set<Range> interesting = new HashSet<Range>();
+        interesting.add(new Range(changed.left, ltoken));
+        interesting.add(new Range(ltoken, changed.right));
 
         // difference the trees
         Differencer diff = new Differencer(new CFPair(tablename, cfname),
@@ -241,8 +246,7 @@ public class AntiEntropyServiceTest exte
         diff.run();
         
         // ensure that the changed range was recorded
-        assertEquals("Wrong number of differing ranges", 1, diff.differences.size());
-        assertEquals("Wrong differing range", changed, diff.differences.get(0));
+        assertEquals("Wrong differing ranges", interesting, new HashSet<Range>(diff.differences));
     }
 
     Set<InetAddress> addTokens(int max) throws Throwable