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 2012/02/07 20:11:21 UTC

[3/4] git commit: optimize calculateNaturalEndpoints by batch-updating TokenMetadata patch by Peter Schuller; reviewed by jbellis for CASSANDRA-3831

optimize calculateNaturalEndpoints by batch-updating TokenMetadata
patch by Peter Schuller; reviewed by jbellis for CASSANDRA-3831


Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/7b1dd3d8
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/7b1dd3d8
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/7b1dd3d8

Branch: refs/heads/cassandra-1.1
Commit: 7b1dd3d8f0191c7d53211a6312e591cd29128184
Parents: 7236465
Author: Jonathan Ellis <jb...@apache.org>
Authored: Tue Feb 7 13:06:31 2012 -0600
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Tue Feb 7 13:09:43 2012 -0600

----------------------------------------------------------------------
 .../cassandra/locator/NetworkTopologyStrategy.java |   10 ++-
 .../apache/cassandra/locator/TokenMetadata.java    |   52 +++++++++++----
 2 files changed, 47 insertions(+), 15 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/7b1dd3d8/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
index 2ae0a98..ffbabd6 100644
--- a/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
+++ b/src/java/org/apache/cassandra/locator/NetworkTopologyStrategy.java
@@ -35,6 +35,7 @@ import org.apache.cassandra.dht.Token;
 import org.apache.cassandra.service.*;
 import org.apache.cassandra.thrift.ConsistencyLevel;
 import org.apache.cassandra.utils.FBUtilities;
+import org.apache.cassandra.utils.Pair;
 
 /**
  * This Replication Strategy takes a property file that gives the intended
@@ -86,13 +87,16 @@ public class NetworkTopologyStrategy extends AbstractReplicationStrategy
             String dcName = dcEntry.getKey();
             int dcReplicas = dcEntry.getValue();
 
-            // collect endpoints in this DC
-            TokenMetadata dcTokens = new TokenMetadata();
+            // collect endpoints in this DC; add in bulk to token meta data for computational complexity
+            // reasons (CASSANDRA-3831).
+            Set<Pair<Token, InetAddress>> dcTokensToUpdate = new HashSet<Pair<Token, InetAddress>>();
             for (Entry<Token, InetAddress> tokenEntry : tokenMetadata.entrySet())
             {
                 if (snitch.getDatacenter(tokenEntry.getValue()).equals(dcName))
-                    dcTokens.updateNormalToken(tokenEntry.getKey(), tokenEntry.getValue());
+                    dcTokensToUpdate.add(Pair.create(tokenEntry.getKey(), tokenEntry.getValue()));
             }
+            TokenMetadata dcTokens = new TokenMetadata();
+            dcTokens.updateNormalTokens(dcTokensToUpdate);
 
             List<InetAddress> dcEndpoints = new ArrayList<InetAddress>(dcReplicas);
             Set<String> racks = new HashSet<String>();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/7b1dd3d8/src/java/org/apache/cassandra/locator/TokenMetadata.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/locator/TokenMetadata.java b/src/java/org/apache/cassandra/locator/TokenMetadata.java
index bf8e190..b02daae 100644
--- a/src/java/org/apache/cassandra/locator/TokenMetadata.java
+++ b/src/java/org/apache/cassandra/locator/TokenMetadata.java
@@ -118,26 +118,54 @@ public class TokenMetadata
         return n;
     }
 
+    /**
+     * Update token map with a single token/endpoint pair in normal state.
+     */
     public void updateNormalToken(Token token, InetAddress endpoint)
     {
-        assert token != null;
-        assert endpoint != null;
+        updateNormalTokens(Collections.singleton(Pair.create(token, endpoint)));
+    }
+
+    /**
+     * Update token map with a set of token/endpoint pairs in normal state.
+     *
+     * Prefer this whenever there are multiple pairs to update, as each update (whether a single or multiple)
+     * is expensive (CASSANDRA-3831).
+     *
+     * @param tokenPairs
+     */
+    public void updateNormalTokens(Set<Pair<Token, InetAddress>> tokenPairs)
+    {
+        if (tokenPairs.isEmpty())
+            return;
 
         lock.writeLock().lock();
         try
         {
-            bootstrapTokens.inverse().remove(endpoint);
-            tokenToEndpointMap.inverse().remove(endpoint);
-            InetAddress prev = tokenToEndpointMap.put(token, endpoint);
-            if (!endpoint.equals(prev))
+            boolean shouldSortTokens = false;
+            for (Pair<Token, InetAddress> tokenEndpointPair : tokenPairs)
             {
-                if (prev != null)
-                    logger.warn("Token " + token + " changing ownership from " + prev + " to " + endpoint);
-                sortedTokens = sortTokens();
+                Token token = tokenEndpointPair.left;
+                InetAddress endpoint = tokenEndpointPair.right;
+
+                assert token != null;
+                assert endpoint != null;
+
+                bootstrapTokens.inverse().remove(endpoint);
+                tokenToEndpointMap.inverse().remove(endpoint);
+                InetAddress prev = tokenToEndpointMap.put(token, endpoint);
+                if (!endpoint.equals(prev))
+                {
+                    if (prev != null)
+                        logger.warn("Token " + token + " changing ownership from " + prev + " to " + endpoint);
+                    shouldSortTokens = true;
+                }
+                leavingEndpoints.remove(endpoint);
+                removeFromMoving(endpoint); // also removing this endpoint from moving
             }
-            leavingEndpoints.remove(endpoint);
-            removeFromMoving(endpoint); // also removing this endpoint from moving
-            invalidateCaches();
+
+            if (shouldSortTokens)
+                sortedTokens = sortTokens();
         }
         finally
         {