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 2009/12/05 01:27:19 UTC

svn commit: r887466 - in /incubator/cassandra/trunk/src/java/org/apache/cassandra: db/ dht/ service/ utils/

Author: jbellis
Date: Sat Dec  5 00:27:18 2009
New Revision: 887466

URL: http://svn.apache.org/viewvc?rev=887466&view=rev
Log:
convert range slice to use DecoratedKeys
patch by jbellis; reviewed by Stu Hood for CASSANDRA-568

Modified:
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/DecoratedKey.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/db/RangeSliceCommand.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/Token.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/service/RangeSliceVerbHandler.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageProxy.java
    incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/ColumnFamilyStore.java Sat Dec  5 00:27:18 2009
@@ -1334,11 +1334,9 @@
        range_slice.  still opens one randomaccessfile per key, which sucks.  something like compactioniterator
        would be better.
      */
-    public RangeReply getKeyRangeRaw(final String startWith, final String stopAt, int maxResults)
+    public RangeReply getKeyRangeRaw(final DecoratedKey startWith, final DecoratedKey stopAt, int maxResults)
     throws IOException, ExecutionException, InterruptedException
     {
-        final DecoratedKey startWithDK = partitioner.decorateKey(startWith);
-        final DecoratedKey stopAtDK = partitioner.decorateKey(stopAt);
         // (OPP key decoration is a no-op so using the "decorated" comparator against raw keys is fine)
         final Comparator<DecoratedKey> comparator = partitioner.getDecoratedKeyComparator();
 
@@ -1352,8 +1350,8 @@
         {
             public boolean apply(DecoratedKey key)
             {
-                return comparator.compare(startWithDK, key) <= 0
-                       && (stopAt.isEmpty() || comparator.compare(key, stopAtDK) <= 0);
+                return comparator.compare(startWith, key) <= 0
+                       && (stopAt.isEmpty() || comparator.compare(key,  stopAt) <= 0);
             }
         };
 
@@ -1369,7 +1367,7 @@
         for (SSTableReader sstable : ssTables_)
         {
             final SSTableScanner scanner = sstable.getScanner();
-            scanner.seekTo(startWithDK);
+            scanner.seekTo(startWith);
             Iterator<DecoratedKey> iter = new CloseableIterator<DecoratedKey>()
             {
                 public boolean hasNext()
@@ -1415,7 +1413,7 @@
             boolean rangeCompletedLocally = false;
             for (DecoratedKey current : reduced)
             {
-                if (!stopAt.isEmpty() && comparator.compare(stopAtDK, current) < 0)
+                if (!stopAt.isEmpty() && comparator.compare( stopAt, current) < 0)
                 {
                     rangeCompletedLocally = true;
                     break;
@@ -1453,7 +1451,7 @@
      * @throws ExecutionException
      * @throws InterruptedException
      */
-    public RangeSliceReply getRangeSlice(byte[] super_column, final String startKey, final String finishKey, int keyMax, SliceRange sliceRange, List<byte[]> columnNames)
+    public RangeSliceReply getRangeSlice(byte[] super_column, final DecoratedKey startKey, final DecoratedKey finishKey, int keyMax, SliceRange sliceRange, List<byte[]> columnNames)
     throws IOException, ExecutionException, InterruptedException
     {
         RangeReply rr = getKeyRangeRaw(startKey, finishKey, keyMax);

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/DecoratedKey.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/DecoratedKey.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/DecoratedKey.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/DecoratedKey.java Sat Dec  5 00:27:18 2009
@@ -18,21 +18,39 @@
 
 package org.apache.cassandra.db;
 
+import java.io.DataOutput;
+import java.io.IOException;
+import java.io.DataInput;
+
 import org.apache.cassandra.dht.Token;
+import org.apache.cassandra.io.ICompactSerializer2;
+import org.apache.cassandra.utils.FBUtilities;
 
 /**
  * Represents a decorated key, handy for certain operations
  * where just working with strings gets slow.
+ *
+ * We do a lot of sorting of DecoratedKeys, so for speed, we assume that tokens correspond one-to-one with keys.
+ * This is not quite correct in the case of RandomPartitioner (which uses MD5 to hash keys to tokens);
+ * if this matters, you can subclass RP to use a stronger hash, or use a non-lossy tokenization scheme (as in the
+ * OrderPreservingPartitioner classes).
  */
 public class DecoratedKey<T extends Token> implements Comparable<DecoratedKey>
 {
+    private static DecoratedKeySerializer serializer = new DecoratedKeySerializer();
+
+    public static DecoratedKeySerializer serializer()
+    {
+        return serializer;
+    }
+
     public final T token;
     public final String key;
 
     public DecoratedKey(T token, String key)
     {
         super();
-        assert key != null;
+        assert token != null;
         this.token = token;
         this.key = key;
     }
@@ -58,20 +76,17 @@
             return false;
 
         DecoratedKey other = (DecoratedKey) obj;
-        // either both should be of a class where all tokens are null, or neither
-        assert (token == null) == (other.token == null);
-        if (token == null)
-            return key.equals(other.key);
-        return token.equals(other.token) && key.equals(other.key);
+        return token.equals(other.token);
     }
 
     public int compareTo(DecoratedKey other)
     {
-        assert (token == null) == (other.token == null);
-        if (token == null)
-            return key.compareTo(other.key);
-        int i = token.compareTo(other.token);
-        return i == 0 ? key.compareTo(other.key) : i;
+        return token.compareTo(other.token);
+    }
+
+    public boolean isEmpty()
+    {
+        return key != null && key.isEmpty();
     }
 
     @Override
@@ -80,3 +95,17 @@
         return "DecoratedKey(" + token + ", " + key + ")";
     }
 }
+
+class DecoratedKeySerializer implements ICompactSerializer2<DecoratedKey>
+{
+    public void serialize(DecoratedKey dk, DataOutput dos) throws IOException
+    {
+        Token.serializer().serialize(dk.token, dos);
+        FBUtilities.writeNullableString(dk.key, dos);
+    }
+
+    public DecoratedKey deserialize(DataInput dis) throws IOException
+    {
+        return new DecoratedKey(Token.serializer().deserialize(dis), FBUtilities.readNullableString(dis));
+    }
+}
\ No newline at end of file

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/db/RangeSliceCommand.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/db/RangeSliceCommand.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/db/RangeSliceCommand.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/db/RangeSliceCommand.java Sat Dec  5 00:27:18 2009
@@ -37,15 +37,12 @@
 package org.apache.cassandra.db;
 
 import org.apache.cassandra.concurrent.StageManager;
-import org.apache.cassandra.db.filter.QueryFilter;
-import org.apache.cassandra.db.filter.SliceQueryFilter;
 import org.apache.cassandra.io.DataInputBuffer;
 import org.apache.cassandra.io.DataOutputBuffer;
 import org.apache.cassandra.io.ICompactSerializer;
 import org.apache.cassandra.net.Message;
 import org.apache.cassandra.service.ColumnParent;
 import org.apache.cassandra.service.SlicePredicate;
-import org.apache.cassandra.service.SliceRange;
 import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.utils.FBUtilities;
 import org.apache.thrift.TDeserializer;
@@ -56,10 +53,7 @@
 import java.io.DataInputStream;
 import java.io.DataOutputStream;
 import java.io.IOException;
-import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.List;
 
 public class RangeSliceCommand
 {
@@ -72,32 +66,21 @@
 
     public final SlicePredicate predicate;
 
-    public final String start_key;
-    public final String finish_key;
+    public final DecoratedKey startKey;
+    public final DecoratedKey finishKey;
     public final int max_keys;
 
-    public RangeSliceCommand(String keyspace, ColumnParent column_parent, SlicePredicate predicate, String start_key, String finish_key, int max_keys)
+    public RangeSliceCommand(String keyspace, ColumnParent column_parent, SlicePredicate predicate, DecoratedKey startKey, DecoratedKey finishKey, int max_keys)
     {
         this.keyspace = keyspace;
         column_family = column_parent.getColumn_family();
         super_column = column_parent.getSuper_column();
         this.predicate = predicate;
-        this.start_key = start_key;
-        this.finish_key = finish_key;
+        this.startKey = startKey;
+        this.finishKey = finishKey;
         this.max_keys = max_keys;
     }
 
-    public RangeSliceCommand(RangeSliceCommand cmd, int max_keys)
-    {
-        this(cmd.keyspace,
-             new ColumnParent(cmd.column_family, cmd.super_column),
-             new SlicePredicate(cmd.predicate),
-             cmd.start_key,
-             cmd.finish_key,
-             max_keys);
-
-    }
-
     public Message getMessage() throws IOException
     {
         DataOutputBuffer dob = new DataOutputBuffer();
@@ -139,8 +122,8 @@
             throw new IOException(ex);
         }
 
-        dos.writeUTF(sliceCommand.start_key);
-        dos.writeUTF(sliceCommand.finish_key);
+        DecoratedKey.serializer().serialize(sliceCommand.startKey, dos);
+        DecoratedKey.serializer().serialize(sliceCommand.finishKey, dos);
         dos.writeInt(sliceCommand.max_keys);
     }
 
@@ -167,14 +150,14 @@
             throw new IOException(ex);
         }
 
-        String start_key = dis.readUTF();
-        String finish_key = dis.readUTF();
+        DecoratedKey startKey = DecoratedKey.serializer().deserialize(dis);
+        DecoratedKey finishKey = DecoratedKey.serializer().deserialize(dis);
         int max_keys = dis.readInt();
         return new RangeSliceCommand(keyspace,
                                      new ColumnParent(column_family, super_column),
                                      pred,
-                                     start_key,
-                                     finish_key,
+                                     startKey,
+                                     finishKey,
                                      max_keys);
 
     }

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/CollatingOrderPreservingPartitioner.java Sat Dec  5 00:27:18 2009
@@ -39,7 +39,7 @@
     private static final Comparator<DecoratedKey<BytesToken>> comparator = new Comparator<DecoratedKey<BytesToken>>() {
         public int compare(DecoratedKey<BytesToken> o1, DecoratedKey<BytesToken> o2)
         {
-            return collator.compare(o1.key, o2.key);
+            return FBUtilities.compareByteArrays(o1.token.token, o2.token.token);
         }
     };
 

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/Token.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/Token.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/Token.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/dht/Token.java Sat Dec  5 00:27:18 2009
@@ -18,12 +18,12 @@
 */
 package org.apache.cassandra.dht;
 
-import java.io.DataInputStream;
-import java.io.DataOutputStream;
+import java.io.DataInput;
+import java.io.DataOutput;
 import java.io.IOException;
 import java.io.Serializable;
 
-import org.apache.cassandra.io.ICompactSerializer;
+import org.apache.cassandra.io.ICompactSerializer2;
 import org.apache.cassandra.service.StorageService;
 
 public abstract class Token<T> implements Comparable<Token<T>>, Serializable
@@ -72,9 +72,9 @@
         public abstract Token<T> fromString(String string); // deserialize
     }
 
-    public static class TokenSerializer implements ICompactSerializer<Token>
+    public static class TokenSerializer implements ICompactSerializer2<Token>
     {
-        public void serialize(Token token, DataOutputStream dos) throws IOException
+        public void serialize(Token token, DataOutput dos) throws IOException
         {
             IPartitioner p = StorageService.getPartitioner();
             byte[] b = p.getTokenFactory().toByteArray(token);
@@ -82,7 +82,7 @@
             dos.write(b);
         }
 
-        public Token deserialize(DataInputStream dis) throws IOException
+        public Token deserialize(DataInput dis) throws IOException
         {
             IPartitioner p = StorageService.getPartitioner();
             int size = dis.readInt();

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/service/CassandraServer.java Sat Dec  5 00:27:18 2009
@@ -572,7 +572,9 @@
         List<Pair<String,Collection<IColumn>>> rows;
         try
         {
-            rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_parent, predicate, start_key, finish_key, maxRows), consistency_level);
+            DecoratedKey startKey = StorageService.getPartitioner().decorateKey(start_key);
+            DecoratedKey finishKey = StorageService.getPartitioner().decorateKey(finish_key);
+            rows = StorageProxy.getRangeSlice(new RangeSliceCommand(keyspace, column_parent, predicate, startKey, finishKey, maxRows), consistency_level);
             assert rows != null;
         }
         catch (IOException e)

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/service/RangeSliceVerbHandler.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/RangeSliceVerbHandler.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/service/RangeSliceVerbHandler.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/service/RangeSliceVerbHandler.java Sat Dec  5 00:27:18 2009
@@ -38,8 +38,8 @@
             RangeSliceCommand command = RangeSliceCommand.read(message);
             RangeSliceReply reply = Table.open(command.keyspace).getColumnFamilyStore(command.column_family).getRangeSlice(
                     command.super_column,
-                    command.start_key,
-                    command.finish_key,
+                    command.startKey,
+                    command.finishKey,
                     command.max_keys,
                     command.predicate.slice_range,
                     command.predicate.column_names);

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageProxy.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageProxy.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageProxy.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/service/StorageProxy.java Sat Dec  5 00:27:18 2009
@@ -533,7 +533,7 @@
         long startTime = System.currentTimeMillis();
         TokenMetadata tokenMetadata = StorageService.instance().getTokenMetadata();
 
-        InetAddress endPoint = StorageService.instance().findSuitableEndPoint(command.start_key);
+        InetAddress endPoint = StorageService.instance().findSuitableEndPoint(command.startKey.key);
         InetAddress startEndpoint = endPoint;
 
         Map<String, ColumnFamily> rows = new HashMap<String, ColumnFamily>(command.max_keys);

Modified: incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java
URL: http://svn.apache.org/viewvc/incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java?rev=887466&r1=887465&r2=887466&view=diff
==============================================================================
--- incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java (original)
+++ incubator/cassandra/trunk/src/java/org/apache/cassandra/utils/FBUtilities.java Sat Dec  5 00:27:18 2009
@@ -231,4 +231,20 @@
 
         return sb.append("}").toString();
     }
+
+    public static void writeNullableString(String key, DataOutput dos) throws IOException
+    {
+        dos.writeBoolean(key == null);
+        if (key != null)
+        {
+            dos.writeUTF(key);
+        }
+    }
+
+    public static String readNullableString(DataInput dis) throws IOException
+    {
+        if (dis.readBoolean())
+            return null;
+        return dis.readUTF();
+    }
 }