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 2013/04/11 17:58:59 UTC

[1/4] initial CAS support patch by jbellis and slebresne for CASSANDRA-5062

Updated Branches:
  refs/heads/trunk f5ec4c7c3 -> 8b0e1868e


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/test/system/test_thrift_server.py
----------------------------------------------------------------------
diff --git a/test/system/test_thrift_server.py b/test/system/test_thrift_server.py
index bcb75e8..8fecd29 100644
--- a/test/system/test_thrift_server.py
+++ b/test/system/test_thrift_server.py
@@ -230,6 +230,18 @@ class TestMutations(ThriftTester):
         assert _big_slice('key1', ColumnParent('Standard2')) == []
         assert _big_slice('key1', ColumnParent('Super1')) == []
 
+    def test_cas(self):
+        _set_keyspace('Keyspace1')
+        assert not client.cas('key1', 'Standard1', _SIMPLE_COLUMNS, _SIMPLE_COLUMNS)
+
+        assert client.cas('key1', 'Standard1', None, _SIMPLE_COLUMNS)
+
+        result = [cosc.column for cosc in _big_slice('key1', ColumnParent('Standard1'))]
+        # CAS will use its own timestamp, so we can't just compare result == _SIMPLE_COLUMNS
+        assert dict((c.name, c.value) for c in result) == dict((c.name, c.value) for c in _SIMPLE_COLUMNS), result
+
+        assert not client.cas('key1', 'Standard1', None, _SIMPLE_COLUMNS)
+
     def test_missing_super(self):
         _set_keyspace('Keyspace1')
         _expect_missing(lambda: client.get('key1', ColumnPath('Super1', 'sc1', _i64(1)), ConsistencyLevel.ONE))

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
index c986c7b..c11fcf2 100644
--- a/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
+++ b/test/unit/org/apache/cassandra/db/ColumnFamilyStoreTest.java
@@ -138,12 +138,12 @@ public class ColumnFamilyStoreTest extends SchemaLoader
                 QueryFilter sliceFilter = QueryFilter.getSliceFilter(Util.dk("key1"), "Standard2", ByteBufferUtil.EMPTY_BYTE_BUFFER, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, 1);
                 ColumnFamily cf = store.getColumnFamily(sliceFilter);
                 assert cf.isMarkedForDelete();
-                assert cf.isEmpty();
+                assert cf.getColumnCount() == 0;
 
                 QueryFilter namesFilter = QueryFilter.getNamesFilter(Util.dk("key1"), "Standard2", ByteBufferUtil.bytes("a"));
                 cf = store.getColumnFamily(namesFilter);
                 assert cf.isMarkedForDelete();
-                assert cf.isEmpty();
+                assert cf.getColumnCount() == 0;
             }
         };
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
index 218b0fa..1f3aef0 100644
--- a/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
+++ b/test/unit/org/apache/cassandra/db/compaction/CompactionsTest.java
@@ -316,7 +316,7 @@ public class CompactionsTest extends SchemaLoader
         Collection<SSTableReader> sstablesBefore = cfs.getSSTables();
 
         QueryFilter filter = QueryFilter.getIdentityFilter(key, cfname);
-        assert !cfs.getColumnFamily(filter).isEmpty();
+        assert !(cfs.getColumnFamily(filter).getColumnCount() == 0);
 
         // Remove key
         rm = new RowMutation(TABLE1, key.key);
@@ -324,7 +324,7 @@ public class CompactionsTest extends SchemaLoader
         rm.apply();
 
         ColumnFamily cf = cfs.getColumnFamily(filter);
-        assert cf == null || cf.isEmpty() : "should be empty: " + cf;
+        assert cf == null || cf.getColumnCount() == 0 : "should be empty: " + cf;
 
         // Sleep one second so that the removal is indeed purgeable even with gcgrace == 0
         Thread.sleep(1000);
@@ -340,6 +340,6 @@ public class CompactionsTest extends SchemaLoader
         Util.compact(cfs, toCompact);
 
         cf = cfs.getColumnFamily(filter);
-        assert cf == null || cf.isEmpty() : "should be empty: " + cf;
+        assert cf == null || cf.getColumnCount() == 0 : "should be empty: " + cf;
     }
 }


[2/4] initial CAS support patch by jbellis and slebresne for CASSANDRA-5062

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/interface/thrift/gen-java/org/apache/cassandra/thrift/cassandraConstants.java
----------------------------------------------------------------------
diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/cassandraConstants.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/cassandraConstants.java
index c17fde4..7508d7c 100644
--- a/interface/thrift/gen-java/org/apache/cassandra/thrift/cassandraConstants.java
+++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/cassandraConstants.java
@@ -54,6 +54,6 @@ import org.slf4j.LoggerFactory;
 
 public class cassandraConstants {
 
-  public static final String VERSION = "19.36.0";
+  public static final String VERSION = "19.37.0";
 
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/config/CFMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java
index 79a75d5..31b16a0 100644
--- a/src/java/org/apache/cassandra/config/CFMetaData.java
+++ b/src/java/org/apache/cassandra/config/CFMetaData.java
@@ -243,6 +243,16 @@ public final class CFMetaData
                                                                  + "inputs set<int>"
                                                                  + ") WITH COMMENT='unfinished compactions'");
 
+    public static final CFMetaData PaxosCf = compile(18, "CREATE TABLE " + SystemTable.PAXOS_CF + " ("
+                                                                 + "row_key blob,"
+                                                                 + "cf_id UUID,"
+                                                                 + "in_progress_ballot timeuuid,"
+                                                                 + "proposal blob,"
+                                                                 + "most_recent_commit_at timeuuid,"
+                                                                 + "most_recent_commit blob,"
+                                                                 + "PRIMARY KEY (row_key, cf_id)"
+                                                                 + ") WITH COMMENT='in-progress paxos proposals'");
+
     public enum Caching
     {
         ALL, KEYS_ONLY, ROWS_ONLY, NONE;
@@ -889,7 +899,7 @@ public final class CFMetaData
     {
         Row cfDefRow = SystemTable.readSchemaRow(ksName, cfName);
 
-        if (cfDefRow.cf == null || cfDefRow.cf.isEmpty())
+        if (cfDefRow.cf == null || cfDefRow.cf.getColumnCount() == 0)
             throw new RuntimeException(String.format("%s not found in the schema definitions table.", ksName + ":" + cfName));
 
         try

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/config/Config.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java
index cca7745..a9f0194 100644
--- a/src/java/org/apache/cassandra/config/Config.java
+++ b/src/java/org/apache/cassandra/config/Config.java
@@ -61,6 +61,8 @@ public class Config
 
     public Long write_request_timeout_in_ms = new Long(10000);
 
+    public Long cas_contention_timeout_in_ms = new Long(1000);
+
     public Long truncate_request_timeout_in_ms = new Long(60000);
 
     public Integer streaming_socket_timeout_in_ms = new Integer(0);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 3ed7b81..7048975 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -752,6 +752,16 @@ public class DatabaseDescriptor
         conf.write_request_timeout_in_ms = timeOutInMillis;
     }
 
+    public static long getCasContentionTimeout()
+    {
+        return conf.cas_contention_timeout_in_ms;
+    }
+
+    public static void setCasContentionTimeout(Long timeOutInMillis)
+    {
+        conf.cas_contention_timeout_in_ms = timeOutInMillis;
+    }
+
     public static long getTruncateRpcTimeout()
     {
         return conf.truncate_request_timeout_in_ms;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/config/KSMetaData.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/KSMetaData.java b/src/java/org/apache/cassandra/config/KSMetaData.java
index e8b9e06..b954b32 100644
--- a/src/java/org/apache/cassandra/config/KSMetaData.java
+++ b/src/java/org/apache/cassandra/config/KSMetaData.java
@@ -89,6 +89,7 @@ public final class KSMetaData
                                                 CFMetaData.SchemaColumnFamiliesCf,
                                                 CFMetaData.SchemaColumnsCf,
                                                 CFMetaData.CompactionLogCf,
+                                                CFMetaData.PaxosCf,
                                                 CFMetaData.OldStatusCf,
                                                 CFMetaData.OldHintsCf,
                                                 CFMetaData.OldMigrationsCf,

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/config/Schema.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/Schema.java b/src/java/org/apache/cassandra/config/Schema.java
index 19a7e51..9d670c0 100644
--- a/src/java/org/apache/cassandra/config/Schema.java
+++ b/src/java/org/apache/cassandra/config/Schema.java
@@ -449,7 +449,7 @@ public class Schema
 
     public static boolean invalidSchemaRow(Row row)
     {
-        return row.cf == null || (row.cf.isMarkedForDelete() && row.cf.isEmpty());
+        return row.cf == null || (row.cf.isMarkedForDelete() && row.cf.getColumnCount() == 0);
     }
 
     public static boolean ignoredSchemaRow(Row row)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/cql3/QueryProcessor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/QueryProcessor.java b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
index d926175..423e188 100644
--- a/src/java/org/apache/cassandra/cql3/QueryProcessor.java
+++ b/src/java/org/apache/cassandra/cql3/QueryProcessor.java
@@ -179,7 +179,7 @@ public class QueryProcessor
         }
         catch (RequestValidationException e)
         {
-            throw new AssertionError(e);
+            throw new RuntimeException("Error validating " + query, e);
         }
     }
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
index 87843d2..7fb7786 100644
--- a/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
+++ b/src/java/org/apache/cassandra/cql3/statements/ModificationStatement.java
@@ -172,7 +172,7 @@ public abstract class ModificationStatement extends CFStatement implements CQLSt
         Map<ByteBuffer, ColumnGroupMap> map = new HashMap<ByteBuffer, ColumnGroupMap>();
         for (Row row : rows)
         {
-            if (row.cf == null || row.cf.isEmpty())
+            if (row.cf == null || row.cf.getColumnCount() == 0)
                 continue;
 
             ColumnGroupMap.Builder groupBuilder = new ColumnGroupMap.Builder(composite, true);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/AbstractThreadUnsafeSortedColumns.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/AbstractThreadUnsafeSortedColumns.java b/src/java/org/apache/cassandra/db/AbstractThreadUnsafeSortedColumns.java
index 1c2fb54..46fa2d9 100644
--- a/src/java/org/apache/cassandra/db/AbstractThreadUnsafeSortedColumns.java
+++ b/src/java/org/apache/cassandra/db/AbstractThreadUnsafeSortedColumns.java
@@ -53,9 +53,4 @@ public abstract class AbstractThreadUnsafeSortedColumns extends ColumnFamily
     {
         deletionInfo = deletionInfo.purge(gcBefore);
     }
-
-    public boolean isEmpty()
-    {
-        return getColumnCount() == 0;
-    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
index b80883a..602edd1 100644
--- a/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
+++ b/src/java/org/apache/cassandra/db/ArrayBackedSortedColumns.java
@@ -186,7 +186,7 @@ public class ArrayBackedSortedColumns extends AbstractThreadUnsafeSortedColumns
     public void addAll(ColumnFamily cm, Allocator allocator, Function<Column, Column> transformation)
     {
         delete(cm.deletionInfo());
-        if (cm.isEmpty())
+        if (cm.getColumnCount() == 0)
             return;
 
         Column[] copy = columns.toArray(new Column[getColumnCount()]);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/AtomicSortedColumns.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/AtomicSortedColumns.java b/src/java/org/apache/cassandra/db/AtomicSortedColumns.java
index a7ef029..fa0a82a 100644
--- a/src/java/org/apache/cassandra/db/AtomicSortedColumns.java
+++ b/src/java/org/apache/cassandra/db/AtomicSortedColumns.java
@@ -231,11 +231,6 @@ public class AtomicSortedColumns extends ColumnFamily
         return ref.get().map.size();
     }
 
-    public boolean isEmpty()
-    {
-        return ref.get().map.isEmpty();
-    }
-
     public Iterator<Column> iterator(ColumnSlice[] slices)
     {
         return new ColumnSlice.NavigableMapIterator(ref.get().map, slices);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/ColumnFamily.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ColumnFamily.java b/src/java/org/apache/cassandra/db/ColumnFamily.java
index 2e33a29..7498d25 100644
--- a/src/java/org/apache/cassandra/db/ColumnFamily.java
+++ b/src/java/org/apache/cassandra/db/ColumnFamily.java
@@ -17,14 +17,18 @@
  */
 package org.apache.cassandra.db;
 
+import java.io.DataInputStream;
+import java.io.IOException;
 import java.nio.ByteBuffer;
 import java.security.MessageDigest;
 import java.util.Collection;
 import java.util.Iterator;
+import java.util.Map;
 import java.util.UUID;
 
 import com.google.common.base.Function;
 import com.google.common.base.Functions;
+import com.google.common.collect.ImmutableMap;
 
 import org.apache.commons.lang.builder.HashCodeBuilder;
 
@@ -35,6 +39,8 @@ import org.apache.cassandra.db.filter.ColumnSlice;
 import org.apache.cassandra.db.marshal.AbstractType;
 import org.apache.cassandra.io.sstable.ColumnStats;
 import org.apache.cassandra.io.sstable.SSTable;
+import org.apache.cassandra.io.util.DataOutputBuffer;
+import org.apache.cassandra.net.MessagingService;
 import org.apache.cassandra.utils.*;
 
 /**
@@ -209,9 +215,12 @@ public abstract class ColumnFamily implements Iterable<Column>, IRowCacheEntry
     public abstract int getColumnCount();
 
     /**
-     * Returns true if this map is empty, false otherwise.
+     * Returns true if this contains no columns or deletion info
      */
-    public abstract boolean isEmpty();
+    public boolean isEmpty()
+    {
+        return deletionInfo().isLive() && getColumnCount() == 0;
+    }
 
     /**
      * Returns an iterator over the columns of this map that returns only the matching @param slices.
@@ -271,7 +280,7 @@ public abstract class ColumnFamily implements Iterable<Column>, IRowCacheEntry
             }
         }
 
-        if (!cfDiff.isEmpty() || cfDiff.isMarkedForDelete())
+        if (!cfDiff.isEmpty())
             return cfDiff;
         return null;
     }
@@ -418,6 +427,36 @@ public abstract class ColumnFamily implements Iterable<Column>, IRowCacheEntry
         return false;
     }
 
+    public Map<ByteBuffer, ByteBuffer> asMap()
+    {
+        ImmutableMap.Builder<ByteBuffer, ByteBuffer> builder = ImmutableMap.builder();
+        for (Column column : this)
+            builder.put(column.name, column.value);
+        return builder.build();
+    }
+
+    public static ColumnFamily fromBytes(ByteBuffer bytes)
+    {
+        if (bytes == null)
+            return null;
+
+        try
+        {
+            return serializer.deserialize(new DataInputStream(ByteBufferUtil.inputStream(bytes)), MessagingService.current_version);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+    }
+
+    public ByteBuffer toBytes()
+    {
+        DataOutputBuffer out = new DataOutputBuffer();
+        serializer.serialize(this, out, MessagingService.current_version);
+        return ByteBuffer.wrap(out.getData(), 0, out.getLength());
+    }
+
     public abstract static class Factory <T extends ColumnFamily>
     {
         /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/ConsistencyLevel.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/ConsistencyLevel.java b/src/java/org/apache/cassandra/db/ConsistencyLevel.java
index 56a7896..9f4fc49 100644
--- a/src/java/org/apache/cassandra/db/ConsistencyLevel.java
+++ b/src/java/org/apache/cassandra/db/ConsistencyLevel.java
@@ -47,7 +47,8 @@ public enum ConsistencyLevel
     QUORUM      (4),
     ALL         (5),
     LOCAL_QUORUM(6),
-    EACH_QUORUM (7);
+    EACH_QUORUM (7),
+    SERIAL      (8);
 
     private static final Logger logger = LoggerFactory.getLogger(ConsistencyLevel.class);
 

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/DefsTable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/DefsTable.java b/src/java/org/apache/cassandra/db/DefsTable.java
index dadf140..878248c 100644
--- a/src/java/org/apache/cassandra/db/DefsTable.java
+++ b/src/java/org/apache/cassandra/db/DefsTable.java
@@ -347,7 +347,7 @@ public class DefsTable
             ColumnFamily ksAttrs = entry.getValue();
 
             // we don't care about nested ColumnFamilies here because those are going to be processed separately
-            if (!ksAttrs.isEmpty())
+            if (!(ksAttrs.getColumnCount() == 0))
                 addKeyspace(KSMetaData.fromSchema(new Row(entry.getKey(), entry.getValue()), Collections.<CFMetaData>emptyList()));
         }
 
@@ -367,7 +367,7 @@ public class DefsTable
             ColumnFamily prevValue = entry.getValue().leftValue();
             ColumnFamily newValue = entry.getValue().rightValue();
 
-            if (prevValue.isEmpty())
+            if (prevValue.getColumnCount() == 0)
             {
                 addKeyspace(KSMetaData.fromSchema(new Row(entry.getKey(), newValue), Collections.<CFMetaData>emptyList()));
                 continue;
@@ -391,7 +391,7 @@ public class DefsTable
 
             ColumnFamily newState = valueDiff.rightValue();
 
-            if (newState.isEmpty())
+            if (newState.getColumnCount() == 0)
                 keyspacesToDrop.add(AsciiType.instance.getString(key.key));
             else
                 updateKeyspace(KSMetaData.fromSchema(new Row(key, newState), Collections.<CFMetaData>emptyList()));
@@ -411,7 +411,7 @@ public class DefsTable
         {
             ColumnFamily cfAttrs = entry.getValue();
 
-            if (!cfAttrs.isEmpty())
+            if (!(cfAttrs.getColumnCount() == 0))
             {
                Map<String, CFMetaData> cfDefs = KSMetaData.deserializeColumnFamilies(new Row(entry.getKey(), cfAttrs));
 
@@ -432,12 +432,12 @@ public class DefsTable
 
             Row newRow = new Row(keyspace, newValue);
 
-            if (prevValue.isEmpty()) // whole keyspace was deleted and now it's re-created
+            if (prevValue.getColumnCount() == 0) // whole keyspace was deleted and now it's re-created
             {
                 for (CFMetaData cfm : KSMetaData.deserializeColumnFamilies(newRow).values())
                     addColumnFamily(cfm);
             }
-            else if (newValue.isEmpty()) // whole keyspace is deleted
+            else if (newValue.getColumnCount() == 0) // whole keyspace is deleted
             {
                 for (CFMetaData cfm : KSMetaData.deserializeColumnFamilies(new Row(keyspace, prevValue)).values())
                     dropColumnFamily(cfm.ksName, cfm.cfName);

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/Memtable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java
index 25c99f3..32bb588 100644
--- a/src/java/org/apache/cassandra/db/Memtable.java
+++ b/src/java/org/apache/cassandra/db/Memtable.java
@@ -467,7 +467,7 @@ public class Memtable
                         // and BL data is strictly local, so we don't need to preserve tombstones for repair.
                         // If we have a data row + row level tombstone, then writing it is effectively an expensive no-op so we skip it.
                         // See CASSANDRA-4667.
-                        if (cfs.name.equals(SystemTable.BATCHLOG_CF) && cfs.table.getName().equals(Table.SYSTEM_KS) && !cf.isEmpty())
+                        if (cfs.name.equals(SystemTable.BATCHLOG_CF) && cfs.table.getName().equals(Table.SYSTEM_KS) && !(cf.getColumnCount() == 0))
                             continue;
 
                         // Pedantically, you could purge column level tombstones that are past GcGRace when writing to the SSTable.

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/Row.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/Row.java b/src/java/org/apache/cassandra/db/Row.java
index 785b058..dc5d08b 100644
--- a/src/java/org/apache/cassandra/db/Row.java
+++ b/src/java/org/apache/cassandra/db/Row.java
@@ -18,9 +18,12 @@
 package org.apache.cassandra.db;
 
 import java.io.*;
+import java.nio.ByteBuffer;
 
 import org.apache.cassandra.db.filter.IDiskAtomFilter;
 import org.apache.cassandra.io.IVersionedSerializer;
+import org.apache.cassandra.io.util.DataOutputBuffer;
+import org.apache.cassandra.net.MessagingService;
 import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.utils.ByteBufferUtil;
 
@@ -39,6 +42,11 @@ public class Row
         this.cf = cf;
     }
 
+    public Row(ByteBuffer key, ColumnFamily updates)
+    {
+        this(StorageService.getPartitioner().decorateKey(key), updates);
+    }
+
     @Override
     public String toString()
     {

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/RowMutation.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/RowMutation.java b/src/java/org/apache/cassandra/db/RowMutation.java
index e945138..dcc62c5 100644
--- a/src/java/org/apache/cassandra/db/RowMutation.java
+++ b/src/java/org/apache/cassandra/db/RowMutation.java
@@ -40,7 +40,7 @@ public class RowMutation implements IMutation
     public static final String FORWARD_TO = "FWD_TO";
     public static final String FORWARD_FROM = "FWD_FRM";
 
-    private final String table;
+    private final String table; // todo this is redundant
     private final ByteBuffer key;
     // map of column family id to mutations for that column family.
     private final Map<UUID, ColumnFamily> modifications;
@@ -67,6 +67,11 @@ public class RowMutation implements IMutation
         this.modifications = modifications;
     }
 
+    public RowMutation(ByteBuffer key, ColumnFamily cf)
+    {
+        this(Schema.instance.getCFMetaData(cf.id()).ksName, key, cf);
+    }
+
     public String getTable()
     {
         return table;
@@ -230,7 +235,6 @@ public class RowMutation implements IMutation
         return buff.append("])").toString();
     }
 
-
     public static class RowMutationSerializer implements IVersionedSerializer<RowMutation>
     {
         public void serialize(RowMutation rm, DataOutput out, int version) throws IOException

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/SystemTable.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/SystemTable.java b/src/java/org/apache/cassandra/db/SystemTable.java
index 2117f2c..5a18314 100644
--- a/src/java/org/apache/cassandra/db/SystemTable.java
+++ b/src/java/org/apache/cassandra/db/SystemTable.java
@@ -34,6 +34,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.KSMetaData;
 import org.apache.cassandra.config.Schema;
@@ -50,6 +51,8 @@ import org.apache.cassandra.io.util.DataOutputBuffer;
 import org.apache.cassandra.io.sstable.SSTableReader;
 import org.apache.cassandra.locator.IEndpointSnitch;
 import org.apache.cassandra.service.StorageService;
+import org.apache.cassandra.service.paxos.Commit;
+import org.apache.cassandra.service.paxos.PaxosState;
 import org.apache.cassandra.thrift.cassandraConstants;
 import org.apache.cassandra.utils.*;
 
@@ -73,6 +76,7 @@ public class SystemTable
     public static final String SCHEMA_COLUMNFAMILIES_CF = "schema_columnfamilies";
     public static final String SCHEMA_COLUMNS_CF = "schema_columns";
     public static final String COMPACTION_LOG = "compactions_in_progress";
+    public static final String PAXOS_CF = "paxos";
 
     @Deprecated
     public static final String OLD_STATUS_CF = "LocationInfo";
@@ -793,4 +797,59 @@ public class SystemTable
 
         return new Row(key, result);
     }
+
+    public static PaxosState loadPaxosState(ByteBuffer key, CFMetaData metadata)
+    {
+        String req = "SELECT * FROM system.%s WHERE row_key = 0x%s AND cf_id = %s";
+        UntypedResultSet results = processInternal(String.format(req, PAXOS_CF, ByteBufferUtil.bytesToHex(key), metadata.cfId));
+        if (results.isEmpty())
+            return new PaxosState(key, metadata);
+        UntypedResultSet.Row row = results.one();
+        Commit inProgress = new Commit(key,
+                                       row.getUUID("in_progress_ballot"),
+                                       row.has("proposal") ? ColumnFamily.fromBytes(row.getBytes("proposal")) : EmptyColumns.factory.create(metadata));
+        // either most_recent_commit and most_recent_commit_at will both be set, or neither
+        Commit mostRecent = row.has("most_recent_commit")
+                          ? new Commit(key, row.getUUID("most_recent_commit_at"), ColumnFamily.fromBytes(row.getBytes("most_recent_commit")))
+                          : Commit.emptyCommit(key, metadata);
+        return new PaxosState(inProgress, mostRecent);
+    }
+
+    public static void savePaxosPromise(Commit promise)
+    {
+        String req = "UPDATE %s USING TIMESTAMP %d AND TTL %d SET in_progress_ballot = %s WHERE row_key = 0x%s AND cf_id = %s";
+        processInternal(String.format(req,
+                                      PAXOS_CF,
+                                      UUIDGen.microsTimestamp(promise.ballot),
+                                      promise.update.metadata().getGcGraceSeconds(),
+                                      promise.ballot,
+                                      ByteBufferUtil.bytesToHex(promise.key),
+                                      promise.update.id()));
+    }
+
+    public static void savePaxosProposal(Commit commit)
+    {
+        processInternal(String.format("UPDATE %s USING TIMESTAMP %d AND TTL %d SET proposal = 0x%s WHERE row_key = 0x%s AND cf_id = %s",
+                                      PAXOS_CF,
+                                      UUIDGen.microsTimestamp(commit.ballot),
+                                      commit.update.metadata().getGcGraceSeconds(),
+                                      ByteBufferUtil.bytesToHex(commit.update.toBytes()),
+                                      ByteBufferUtil.bytesToHex(commit.key),
+                                      commit.update.id()));
+    }
+
+    public static void savePaxosCommit(Commit commit, boolean eraseInProgressProposal)
+    {
+        String preserveCql = "UPDATE %s USING TIMESTAMP %d AND TTL %d SET most_recent_commit_at = %s, most_recent_commit = 0x%s WHERE row_key = 0x%s AND cf_id = %s";
+        // identical except adds proposal = null
+        String eraseCql = "UPDATE %s USING TIMESTAMP %d AND TTL %d SET proposal = null, most_recent_commit_at = %s, most_recent_commit = 0x%s WHERE row_key = 0x%s AND cf_id = %s";
+        processInternal(String.format(eraseInProgressProposal ? eraseCql : preserveCql,
+                                      PAXOS_CF,
+                                      UUIDGen.microsTimestamp(commit.ballot),
+                                      commit.update.metadata().getGcGraceSeconds(),
+                                      commit.ballot,
+                                      ByteBufferUtil.bytesToHex(commit.update.toBytes()),
+                                      ByteBufferUtil.bytesToHex(commit.key),
+                                      commit.update.id()));
+    }
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/WriteType.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/WriteType.java b/src/java/org/apache/cassandra/db/WriteType.java
index b96585d..4f4c88d 100644
--- a/src/java/org/apache/cassandra/db/WriteType.java
+++ b/src/java/org/apache/cassandra/db/WriteType.java
@@ -23,5 +23,6 @@ public enum WriteType
     BATCH,
     UNLOGGED_BATCH,
     COUNTER,
-    BATCH_LOG;
+    BATCH_LOG,
+    CAS;
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java b/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
index 992061d..e24078e 100644
--- a/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
+++ b/src/java/org/apache/cassandra/db/index/composites/CompositesSearcher.java
@@ -165,7 +165,7 @@ public class CompositesSearcher extends SecondaryIndexSearcher
                                                                              false,
                                                                              rowsPerQuery);
                         ColumnFamily indexRow = index.getIndexCfs().getColumnFamily(indexFilter);
-                        if (indexRow == null || indexRow.isEmpty())
+                        if (indexRow == null || indexRow.getColumnCount() == 0)
                             return makeReturn(currentKey, data);
 
                         Collection<Column> sortedColumns = indexRow.getSortedColumns();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/net/IAsyncCallback.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/IAsyncCallback.java b/src/java/org/apache/cassandra/net/IAsyncCallback.java
index 1d83fbc..a29260c 100644
--- a/src/java/org/apache/cassandra/net/IAsyncCallback.java
+++ b/src/java/org/apache/cassandra/net/IAsyncCallback.java
@@ -17,6 +17,12 @@
  */
 package org.apache.cassandra.net;
 
+import java.net.InetAddress;
+
+import com.google.common.base.Predicate;
+
+import org.apache.cassandra.gms.FailureDetector;
+
 /**
  * implementors of IAsyncCallback need to make sure that any public methods
  * are threadsafe with respect to response() being called from the message
@@ -25,6 +31,14 @@ package org.apache.cassandra.net;
  */
 public interface IAsyncCallback<T>
 {
+    public static Predicate<InetAddress> isAlive = new Predicate<InetAddress>()
+    {
+        public boolean apply(InetAddress endpoint)
+        {
+            return FailureDetector.instance.isAlive(endpoint);
+        }
+    };
+
     /**
      * @param msg response received.
      */

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/net/MessageIn.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/MessageIn.java b/src/java/org/apache/cassandra/net/MessageIn.java
index 5c43035..b9d94b5 100644
--- a/src/java/org/apache/cassandra/net/MessageIn.java
+++ b/src/java/org/apache/cassandra/net/MessageIn.java
@@ -25,6 +25,9 @@ import java.util.Map;
 
 import com.google.common.collect.ImmutableMap;
 
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
 import org.apache.cassandra.concurrent.Stage;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.io.IVersionedSerializer;
@@ -32,6 +35,8 @@ import org.apache.cassandra.io.util.FileUtils;
 
 public class MessageIn<T>
 {
+    private static final Logger logger = LoggerFactory.getLogger(MessageIn.class);
+
     public final InetAddress from;
     public final T payload;
     public final Map<String, byte[]> parameters;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/net/MessagingService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/MessagingService.java b/src/java/org/apache/cassandra/net/MessagingService.java
index a32500d..d9688a9 100644
--- a/src/java/org/apache/cassandra/net/MessagingService.java
+++ b/src/java/org/apache/cassandra/net/MessagingService.java
@@ -60,6 +60,8 @@ import org.apache.cassandra.metrics.DroppedMessageMetrics;
 import org.apache.cassandra.net.sink.SinkManager;
 import org.apache.cassandra.security.SSLFactory;
 import org.apache.cassandra.service.*;
+import org.apache.cassandra.service.paxos.Commit;
+import org.apache.cassandra.service.paxos.PrepareResponse;
 import org.apache.cassandra.streaming.*;
 import org.apache.cassandra.streaming.compress.CompressedFileStreamTask;
 import org.apache.cassandra.tracing.Tracing;
@@ -119,33 +121,49 @@ public final class MessagingService implements MessagingServiceMBean
         _TRACE, // dummy verb so we can use MS.droppedMessages
         ECHO,
         // use as padding for backwards compatability where a previous version needs to validate a verb from the future.
+        PAXOS_PREPARE,
+        PAXOS_PROPOSE,
+        PAXOS_COMMIT,
+        // remember to add new verbs at the end, since we serialize by ordinal
         UNUSED_1,
         UNUSED_2,
         UNUSED_3,
         ;
-        // remember to add new verbs at the end, since we serialize by ordinal
     }
 
     public static final EnumMap<MessagingService.Verb, Stage> verbStages = new EnumMap<MessagingService.Verb, Stage>(MessagingService.Verb.class)
     {{
         put(Verb.MUTATION, Stage.MUTATION);
-        put(Verb.BINARY, Stage.MUTATION);
         put(Verb.READ_REPAIR, Stage.MUTATION);
         put(Verb.TRUNCATE, Stage.MUTATION);
+        put(Verb.COUNTER_MUTATION, Stage.MUTATION);
+        put(Verb.PAXOS_PREPARE, Stage.MUTATION);
+        put(Verb.PAXOS_PROPOSE, Stage.MUTATION);
+        put(Verb.PAXOS_COMMIT, Stage.MUTATION);
+
         put(Verb.READ, Stage.READ);
+        put(Verb.RANGE_SLICE, Stage.READ);
+        put(Verb.INDEX_SCAN, Stage.READ);
+
         put(Verb.REQUEST_RESPONSE, Stage.REQUEST_RESPONSE);
+        put(Verb.INTERNAL_RESPONSE, Stage.INTERNAL_RESPONSE);
+
         put(Verb.STREAM_REPLY, Stage.MISC); // actually handled by FileStreamTask and streamExecutors
         put(Verb.STREAM_REQUEST, Stage.MISC);
-        put(Verb.RANGE_SLICE, Stage.READ);
         put(Verb.BOOTSTRAP_TOKEN, Stage.MISC);
+        put(Verb.REPLICATION_FINISHED, Stage.MISC);
+        put(Verb.SNAPSHOT, Stage.MISC);
+
         put(Verb.TREE_REQUEST, Stage.ANTI_ENTROPY);
         put(Verb.TREE_RESPONSE, Stage.ANTI_ENTROPY);
         put(Verb.STREAMING_REPAIR_REQUEST, Stage.ANTI_ENTROPY);
         put(Verb.STREAMING_REPAIR_RESPONSE, Stage.ANTI_ENTROPY);
+
         put(Verb.GOSSIP_DIGEST_ACK, Stage.GOSSIP);
         put(Verb.GOSSIP_DIGEST_ACK2, Stage.GOSSIP);
         put(Verb.GOSSIP_DIGEST_SYN, Stage.GOSSIP);
         put(Verb.GOSSIP_SHUTDOWN, Stage.GOSSIP);
+
         put(Verb.DEFINITIONS_UPDATE, Stage.MIGRATION);
         put(Verb.SCHEMA_CHECK, Stage.MIGRATION);
         put(Verb.MIGRATION_REQUEST, Stage.MIGRATION);
@@ -155,6 +173,7 @@ public final class MessagingService implements MessagingServiceMBean
         put(Verb.COUNTER_MUTATION, Stage.MUTATION);
         put(Verb.SNAPSHOT, Stage.MISC);
         put(Verb.ECHO, Stage.GOSSIP);
+
         put(Verb.UNUSED_1, Stage.INTERNAL_RESPONSE);
         put(Verb.UNUSED_2, Stage.INTERNAL_RESPONSE);
         put(Verb.UNUSED_3, Stage.INTERNAL_RESPONSE);
@@ -194,6 +213,9 @@ public final class MessagingService implements MessagingServiceMBean
         put(Verb.REPLICATION_FINISHED, null);
         put(Verb.COUNTER_MUTATION, CounterMutation.serializer);
         put(Verb.ECHO, EchoMessage.serializer);
+        put(Verb.PAXOS_PREPARE, Commit.serializer);
+        put(Verb.PAXOS_PROPOSE, Commit.serializer);
+        put(Verb.PAXOS_COMMIT, Commit.serializer);
     }};
 
     /**
@@ -213,6 +235,9 @@ public final class MessagingService implements MessagingServiceMBean
         put(Verb.SCHEMA_CHECK, UUIDSerializer.serializer);
         put(Verb.BOOTSTRAP_TOKEN, BootStrapper.StringSerializer.instance);
         put(Verb.REPLICATION_FINISHED, null);
+
+        put(Verb.PAXOS_PREPARE, PrepareResponse.serializer);
+        put(Verb.PAXOS_PROPOSE, BooleanSerializer.serializer);
     }};
 
     /* This records all the results mapped by message Id */

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java b/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java
index 4df9e1f..a97eec0 100644
--- a/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java
+++ b/src/java/org/apache/cassandra/service/AbstractWriteResponseHandler.java
@@ -21,7 +21,6 @@ import java.net.InetAddress;
 import java.util.Collection;
 import java.util.concurrent.TimeUnit;
 
-import com.google.common.base.Predicate;
 import com.google.common.collect.Iterables;
 
 import org.apache.cassandra.config.DatabaseDescriptor;
@@ -29,21 +28,12 @@ import org.apache.cassandra.db.ConsistencyLevel;
 import org.apache.cassandra.db.Table;
 import org.apache.cassandra.db.WriteType;
 import org.apache.cassandra.exceptions.*;
-import org.apache.cassandra.gms.FailureDetector;
 import org.apache.cassandra.net.IAsyncCallback;
 import org.apache.cassandra.net.MessageIn;
 import org.apache.cassandra.utils.SimpleCondition;
 
 public abstract class AbstractWriteResponseHandler implements IAsyncCallback
 {
-    private static Predicate<InetAddress> isAlive = new Predicate<InetAddress>()
-    {
-        public boolean apply(InetAddress endpoint)
-        {
-            return FailureDetector.instance.isAlive(endpoint);
-        }
-    };
-
     private final SimpleCondition condition = new SimpleCondition();
     protected final Table table;
     protected final long startTime;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/StorageProxy.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java
index a42fb87..caffaaf 100644
--- a/src/java/org/apache/cassandra/service/StorageProxy.java
+++ b/src/java/org/apache/cassandra/service/StorageProxy.java
@@ -37,12 +37,14 @@ import org.slf4j.LoggerFactory;
 
 import org.apache.cassandra.concurrent.Stage;
 import org.apache.cassandra.concurrent.StageManager;
+import org.apache.cassandra.config.CFMetaData;
 import org.apache.cassandra.config.DatabaseDescriptor;
 import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.Table;
 import org.apache.cassandra.db.filter.ColumnSlice;
 import org.apache.cassandra.db.filter.IDiskAtomFilter;
+import org.apache.cassandra.db.filter.NamesQueryFilter;
 import org.apache.cassandra.db.filter.SliceQueryFilter;
 import org.apache.cassandra.db.marshal.UUIDType;
 import org.apache.cassandra.dht.AbstractBounds;
@@ -58,10 +60,9 @@ import org.apache.cassandra.locator.IEndpointSnitch;
 import org.apache.cassandra.locator.TokenMetadata;
 import org.apache.cassandra.metrics.ClientRequestMetrics;
 import org.apache.cassandra.net.*;
+import org.apache.cassandra.service.paxos.*;
 import org.apache.cassandra.tracing.Tracing;
-import org.apache.cassandra.utils.ByteBufferUtil;
-import org.apache.cassandra.utils.FBUtilities;
-import org.apache.cassandra.utils.Pair;
+import org.apache.cassandra.utils.*;
 
 public class StorageProxy implements StorageProxyMBean
 {
@@ -163,6 +164,168 @@ public class StorageProxy implements StorageProxyMBean
     }
 
     /**
+     * Apply @param updates if and only if the current values in the row for @param key
+     * match the ones given by @param old.  The algorithm is "raw" Paxos: that is, Paxos
+     * minus leader election -- any node in the cluster may propose changes for any row,
+     * which (that is, the row) is the unit of values being proposed, not single columns.
+     *
+     * The Paxos cohort is only the replicas for the given key, not the entire cluster.
+     * So we expect performance to be reasonable, but CAS is still intended to be used
+     * "when you really need it," not for all your updates.
+     *
+     * There are three phases to Paxos:
+     *  1. Prepare: the coordinator generates a ballot (timeUUID in our case) and asks replicas to (a) promise
+     *     not to accept updates from older ballots and (b) tell us about the most recent update it has already
+     *     accepted.
+     *  2. Accept: if a majority of replicas reply, the coordinator asks replicas to accept the value of the
+     *     highest proposal ballot it heard about, or a new value if no in-progress proposals were reported.
+     *  3. Commit (Learn): if a majority of replicas acknowledge the accept request, we can commit the new
+     *     value.
+     *
+     *  Commit procedure is not covered in "Paxos Made Simple," and only briefly mentioned in "Paxos Made Live,"
+     *  so here is our approach:
+     *   3a. The coordinator sends a commit message to all replicas with the ballot and value.
+     *   3b. Because of 1-2, this will be the highest-seen commit ballot.  The replicas will note that,
+     *       and send it with subsequent promise replies.  This allows us to discard acceptance records
+     *       for successfully committed replicas, without allowing incomplete proposals to commit erroneously
+     *       later on.
+     *
+     *  Note that since we are performing a CAS rather than a simple update, we perform a read (of committed
+     *  values) between the prepare and accept phases.  This gives us a slightly longer window for another
+     *  coordinator to come along and trump our own promise with a newer one but is otherwise safe.
+     *
+     * @return true if the operation succeeds in updating the row
+     */
+    public static boolean cas(String table, String cfName, ByteBuffer key, ColumnFamily expected, ColumnFamily updates)
+    throws UnavailableException, IOException, IsBootstrappingException, ReadTimeoutException, WriteTimeoutException
+    {
+        CFMetaData metadata = Schema.instance.getCFMetaData(table, cfName);
+
+        long timedOut = System.currentTimeMillis() + DatabaseDescriptor.getCasContentionTimeout();
+        while (System.currentTimeMillis() < timedOut)
+        {
+            // begin a paxos round
+            UUID ballot = UUIDGen.getTimeUUID();
+            Token tk = StorageService.getPartitioner().getToken(key);
+            List<InetAddress> naturalEndpoints = StorageService.instance.getNaturalEndpoints(table, tk);
+            Collection<InetAddress> pendingEndpoints = StorageService.instance.getTokenMetadata().pendingEndpointsFor(tk, table);
+            int requiredParticipants = pendingEndpoints.size() + 1 + naturalEndpoints.size() / 2; // See CASSANDRA-833
+            // for simplicity, we'll do a single liveness check at the start.  the gains from repeating this check
+            // are not large enough to bother with.
+            List<InetAddress> liveEndpoints = ImmutableList.copyOf(Iterables.filter(Iterables.concat(naturalEndpoints, pendingEndpoints), IAsyncCallback.isAlive));
+            if (liveEndpoints.size() < requiredParticipants)
+               throw new UnavailableException(ConsistencyLevel.SERIAL, requiredParticipants, liveEndpoints.size());
+
+            // prepare
+            logger.debug("Preparing {}", ballot);
+            Commit toPrepare = Commit.newPrepare(key, metadata, ballot);
+            PrepareCallback summary = preparePaxos(toPrepare, liveEndpoints, requiredParticipants);
+            if (!summary.promised)
+            {
+                logger.debug("Some replicas have already promised a higher ballot than ours; aborting");
+                // sleep a random amount to give the other proposer a chance to finish
+                FBUtilities.sleep(FBUtilities.threadLocalRandom().nextInt(100));
+                continue;
+            }
+
+            Commit inProgress = summary.inProgressCommit;
+            Commit mostRecent = summary.mostRecentCommit;
+
+            // If we have an in-progress ballot greater than the MRC we know, then it's an in-progress round that
+            // needs to be completed, so do it.
+            if (!inProgress.update.isEmpty() && inProgress.isAfter(mostRecent))
+            {
+                logger.debug("Finishing incomplete paxos round {}", inProgress);
+                if (proposePaxos(inProgress, liveEndpoints, requiredParticipants))
+                    commitPaxos(inProgress, liveEndpoints);
+                // no need to sleep here
+                continue;
+            }
+
+            // To be able to propose our value on a new round, we need a quorum of replica to have learn the previous one. Why is explained at:
+            // https://issues.apache.org/jira/browse/CASSANDRA-5062?focusedCommentId=13619810&page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel#comment-13619810)
+            // Since we waited for quorum nodes, if some of them haven't seen the last commit (which may just be a timing issue, but may also
+            // mean we lost messages), we pro-actively "repair" those nodes, and retry.
+            Iterable<InetAddress> missingMRC = summary.replicasMissingMostRecentCommit();
+            if (Iterables.size(missingMRC) > 0)
+            {
+                logger.debug("Repairing replicas that missed the most recent commit");
+                commitPaxos(mostRecent, missingMRC);
+                // TODO: provided commits don't invalid the prepare we just did above (which they don't), we could just wait
+                // for all the missingMRC to acknowledge this commit and then move on with proposing our value. But that means
+                // adding the ability to have commitPaxos block, which is exactly CASSANDRA-5442 will do. So once we have that
+                // latter ticket, we can pass CL.ALL to the commit above and remove the 'continue'.
+                continue;
+            }
+
+            // read the current value and compare with expected
+            logger.debug("Reading existing values for CAS precondition");
+            ReadCommand readCommand = expected == null
+                                    ? new SliceFromReadCommand(table, key, cfName, new SliceQueryFilter(ByteBufferUtil.EMPTY_BYTE_BUFFER, ByteBufferUtil.EMPTY_BYTE_BUFFER, false, 1))
+                                    : new SliceByNamesReadCommand(table, key, cfName, new NamesQueryFilter(ImmutableSortedSet.copyOf(expected.getColumnNames())));
+            List<Row> rows = read(Arrays.asList(readCommand), ConsistencyLevel.QUORUM);
+            ColumnFamily current = rows.get(0).cf;
+            if ((current == null) != (expected == null))
+            {
+                logger.debug("CAS precondition {} does not match current values {}", expected, current);
+                return false;
+            }
+            if (current != null && !com.google.common.base.Objects.equal(current.asMap(), expected.asMap()))
+            {
+                logger.debug("CAS precondition {} does not match current values {}", expected, current);
+                return false;
+            }
+
+            // finish the paxos round w/ the desired updates
+            // TODO turn null updates into delete?
+            Commit proposal = toPrepare.makeProposal(updates);
+            logger.debug("CAS precondition is met; proposing client-requested updates for {}", ballot);
+            if (proposePaxos(proposal, liveEndpoints, requiredParticipants))
+            {
+                commitPaxos(proposal, liveEndpoints);
+                logger.debug("Paxos CAS successful");
+                return true;
+            }
+
+            logger.debug("Paxos proposal not accepted (pre-empted by a higher ballot)");
+            FBUtilities.sleep(FBUtilities.threadLocalRandom().nextInt(100));
+            // continue to retry
+        }
+
+        throw new WriteTimeoutException(WriteType.CAS, ConsistencyLevel.SERIAL, -1, -1);
+    }
+
+    private static PrepareCallback preparePaxos(Commit toPrepare, List<InetAddress> endpoints, int requiredParticipants)
+    throws WriteTimeoutException, UnavailableException
+    {
+        PrepareCallback callback = new PrepareCallback(toPrepare.key, toPrepare.update.metadata(), requiredParticipants);
+        MessageOut<Commit> message = new MessageOut<Commit>(MessagingService.Verb.PAXOS_PREPARE, toPrepare, Commit.serializer);
+        for (InetAddress target : endpoints)
+            MessagingService.instance().sendRR(message, target, callback);
+        callback.await();
+        return callback;
+    }
+
+    private static boolean proposePaxos(Commit proposal, List<InetAddress> endpoints, int requiredParticipants)
+    throws WriteTimeoutException
+    {
+        ProposeCallback callback = new ProposeCallback(requiredParticipants);
+        MessageOut<Commit> message = new MessageOut<Commit>(MessagingService.Verb.PAXOS_PROPOSE, proposal, Commit.serializer);
+        for (InetAddress target : endpoints)
+            MessagingService.instance().sendRR(message, target, callback);
+        callback.await();
+
+        return callback.getSuccessful() >= requiredParticipants;
+    }
+
+    private static void commitPaxos(Commit proposal, Iterable<InetAddress> endpoints)
+    {
+        MessageOut<Commit> message = new MessageOut<Commit>(MessagingService.Verb.PAXOS_COMMIT, proposal, Commit.serializer);
+        for (InetAddress target : endpoints)
+            MessagingService.instance().sendOneWay(message, target);
+    }
+
+    /**
      * Use this method to have these Mutations applied
      * across all replicas. This method will take care
      * of the possibility of a replica being down and hint
@@ -1642,9 +1805,13 @@ public class StorageProxy implements StorageProxyMBean
     public Long getWriteRpcTimeout() { return DatabaseDescriptor.getWriteRpcTimeout(); }
     public void setWriteRpcTimeout(Long timeoutInMillis) { DatabaseDescriptor.setWriteRpcTimeout(timeoutInMillis); }
 
+    public Long getCasContentionTimeout() { return DatabaseDescriptor.getCasContentionTimeout(); }
+    public void setCasContentionTimeout(Long timeoutInMillis) { DatabaseDescriptor.setCasContentionTimeout(timeoutInMillis); }
+
     public Long getRangeRpcTimeout() { return DatabaseDescriptor.getRangeRpcTimeout(); }
     public void setRangeRpcTimeout(Long timeoutInMillis) { DatabaseDescriptor.setRangeRpcTimeout(timeoutInMillis); }
 
     public Long getTruncateRpcTimeout() { return DatabaseDescriptor.getTruncateRpcTimeout(); }
     public void setTruncateRpcTimeout(Long timeoutInMillis) { DatabaseDescriptor.setTruncateRpcTimeout(timeoutInMillis); }
+
 }

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/StorageProxyMBean.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageProxyMBean.java b/src/java/org/apache/cassandra/service/StorageProxyMBean.java
index 1bbfd1f..18e5da1 100644
--- a/src/java/org/apache/cassandra/service/StorageProxyMBean.java
+++ b/src/java/org/apache/cassandra/service/StorageProxyMBean.java
@@ -82,6 +82,8 @@ public interface StorageProxyMBean
     public void setReadRpcTimeout(Long timeoutInMillis);
     public Long getWriteRpcTimeout();
     public void setWriteRpcTimeout(Long timeoutInMillis);
+    public Long getCasContentionTimeout();
+    public void setCasContentionTimeout(Long timeoutInMillis);
     public Long getRangeRpcTimeout();
     public void setRangeRpcTimeout(Long timeoutInMillis);
     public Long getTruncateRpcTimeout();

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/StorageService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java
index eed16b9..855c69a 100644
--- a/src/java/org/apache/cassandra/service/StorageService.java
+++ b/src/java/org/apache/cassandra/service/StorageService.java
@@ -35,9 +35,7 @@ import javax.management.NotificationBroadcasterSupport;
 import javax.management.ObjectName;
 
 import com.google.common.collect.*;
-
 import com.google.common.util.concurrent.AtomicDouble;
-import org.apache.cassandra.db.index.SecondaryIndex;
 import org.apache.log4j.Level;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
@@ -54,6 +52,7 @@ import org.apache.cassandra.config.Schema;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.Table;
 import org.apache.cassandra.db.commitlog.CommitLog;
+import org.apache.cassandra.db.index.SecondaryIndex;
 import org.apache.cassandra.dht.*;
 import org.apache.cassandra.dht.Range;
 import org.apache.cassandra.exceptions.ConfigurationException;
@@ -63,14 +62,23 @@ import org.apache.cassandra.gms.*;
 import org.apache.cassandra.io.sstable.SSTableDeletingTask;
 import org.apache.cassandra.io.sstable.SSTableLoader;
 import org.apache.cassandra.io.util.FileUtils;
-import org.apache.cassandra.locator.*;
+import org.apache.cassandra.locator.AbstractReplicationStrategy;
+import org.apache.cassandra.locator.DynamicEndpointSnitch;
+import org.apache.cassandra.locator.IEndpointSnitch;
+import org.apache.cassandra.locator.TokenMetadata;
 import org.apache.cassandra.metrics.StorageMetrics;
-import org.apache.cassandra.net.*;
+import org.apache.cassandra.net.AsyncOneResponse;
+import org.apache.cassandra.net.MessageOut;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.net.ResponseVerbHandler;
 import org.apache.cassandra.service.ActiveRepairService.TreeRequestVerbHandler;
+import org.apache.cassandra.service.paxos.CommitVerbHandler;
+import org.apache.cassandra.service.paxos.PrepareVerbHandler;
+import org.apache.cassandra.service.paxos.ProposeVerbHandler;
 import org.apache.cassandra.streaming.*;
-import org.apache.cassandra.thrift.cassandraConstants;
 import org.apache.cassandra.thrift.EndpointDetails;
 import org.apache.cassandra.thrift.TokenRange;
+import org.apache.cassandra.thrift.cassandraConstants;
 import org.apache.cassandra.tracing.Tracing;
 import org.apache.cassandra.utils.*;
 
@@ -233,6 +241,9 @@ public class StorageService extends NotificationBroadcasterSupport implements IE
         MessagingService.instance().registerVerbHandlers(MessagingService.Verb.INDEX_SCAN, new IndexScanVerbHandler());
         MessagingService.instance().registerVerbHandlers(MessagingService.Verb.COUNTER_MUTATION, new CounterMutationVerbHandler());
         MessagingService.instance().registerVerbHandlers(MessagingService.Verb.TRUNCATE, new TruncateVerbHandler());
+        MessagingService.instance().registerVerbHandlers(MessagingService.Verb.PAXOS_PREPARE, new PrepareVerbHandler());
+        MessagingService.instance().registerVerbHandlers(MessagingService.Verb.PAXOS_PROPOSE, new ProposeVerbHandler());
+        MessagingService.instance().registerVerbHandlers(MessagingService.Verb.PAXOS_COMMIT, new CommitVerbHandler());
 
         // see BootStrapper for a summary of how the bootstrap verbs interact
         MessagingService.instance().registerVerbHandlers(MessagingService.Verb.BOOTSTRAP_TOKEN, new BootStrapper.BootstrapTokenVerbHandler());

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/AbstractPaxosCallback.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/AbstractPaxosCallback.java b/src/java/org/apache/cassandra/service/paxos/AbstractPaxosCallback.java
new file mode 100644
index 0000000..628f6ea
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/AbstractPaxosCallback.java
@@ -0,0 +1,45 @@
+package org.apache.cassandra.service.paxos;
+
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.cassandra.config.DatabaseDescriptor;
+import org.apache.cassandra.db.ConsistencyLevel;
+import org.apache.cassandra.db.WriteType;
+import org.apache.cassandra.exceptions.WriteTimeoutException;
+import org.apache.cassandra.net.IAsyncCallback;
+
+public abstract class AbstractPaxosCallback<T> implements IAsyncCallback<T>
+{
+    protected final CountDownLatch latch;
+    protected final int targets;
+
+    public AbstractPaxosCallback(int targets)
+    {
+        this.targets = targets;
+        latch = new CountDownLatch(targets);
+    }
+
+    public boolean isLatencyForSnitch()
+    {
+        return false;
+    }
+
+    public int getResponseCount()
+    {
+        return (int) (targets - latch.getCount());
+    }
+
+    public void await() throws WriteTimeoutException
+    {
+        try
+        {
+            if (!latch.await(DatabaseDescriptor.getWriteRpcTimeout(), TimeUnit.MILLISECONDS))
+                throw new WriteTimeoutException(WriteType.CAS, ConsistencyLevel.SERIAL, getResponseCount(), targets);
+        }
+        catch (InterruptedException ex)
+        {
+            throw new AssertionError("This latch shouldn't have been interrupted.");
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/Commit.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/Commit.java b/src/java/org/apache/cassandra/service/paxos/Commit.java
new file mode 100644
index 0000000..b12a6f7
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/Commit.java
@@ -0,0 +1,130 @@
+package org.apache.cassandra.service.paxos;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.UUID;
+import java.nio.ByteBuffer;
+
+import com.google.common.base.Objects;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.db.Column;
+import org.apache.cassandra.db.ColumnFamily;
+import org.apache.cassandra.db.EmptyColumns;
+import org.apache.cassandra.db.RowMutation;
+import org.apache.cassandra.io.IVersionedSerializer;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.UUIDGen;
+import org.apache.cassandra.utils.UUIDSerializer;
+
+public class Commit
+{
+    public static final CommitSerializer serializer = new CommitSerializer();
+
+    public final ByteBuffer key;
+    public final UUID ballot;
+    public final ColumnFamily update;
+
+    public Commit(ByteBuffer key, UUID ballot, ColumnFamily update)
+    {
+        assert key != null;
+        assert ballot != null;
+        assert update != null;
+
+        this.key = key;
+        this.ballot = ballot;
+        this.update = update;
+    }
+
+    public static Commit newPrepare(ByteBuffer key, CFMetaData metadata, UUID ballot)
+    {
+        return new Commit(key, ballot, EmptyColumns.factory.create(metadata));
+    }
+
+    public Commit makeProposal(ColumnFamily update)
+    {
+        return new Commit(key, ballot, updatesWithPaxosTime(update, ballot));
+    }
+
+    public static Commit emptyCommit(ByteBuffer key, CFMetaData metadata)
+    {
+        return new Commit(key, UUIDGen.minTimeUUID(0), EmptyColumns.factory.create(metadata));
+    }
+
+    public boolean isAfter(Commit other)
+    {
+        return ballot.timestamp() > other.ballot.timestamp();
+    }
+
+    public boolean hasBallot(UUID ballot)
+    {
+        return this.ballot.equals(ballot);
+    }
+
+    public RowMutation makeMutation()
+    {
+        assert update != null;
+        return new RowMutation(key, update);
+    }
+
+    @Override
+    public boolean equals(Object o)
+    {
+        if (this == o) return true;
+        if (o == null || getClass() != o.getClass()) return false;
+
+        Commit commit = (Commit) o;
+
+        if (!ballot.equals(commit.ballot)) return false;
+        if (!key.equals(commit.key)) return false;
+        if (!update.equals(commit.update)) return false;
+
+        return true;
+    }
+
+    @Override
+    public int hashCode()
+    {
+        return Objects.hashCode(key, ballot, update);
+    }
+
+    private static ColumnFamily updatesWithPaxosTime(ColumnFamily updates, UUID ballot)
+    {
+        ColumnFamily cf = updates.cloneMeShallow();
+        long t = UUIDGen.microsTimestamp(ballot);
+        for (Column column : updates)
+            cf.addColumn(column.name(), column.value(), t);
+        return cf;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("Commit(%s, %s, %s)", ByteBufferUtil.bytesToHex(key), ballot, update);
+    }
+
+    public static class CommitSerializer implements IVersionedSerializer<Commit>
+    {
+        public void serialize(Commit commit, DataOutput out, int version) throws IOException
+        {
+            ByteBufferUtil.writeWithShortLength(commit.key, out);
+            UUIDSerializer.serializer.serialize(commit.ballot, out, version);
+            ColumnFamily.serializer.serialize(commit.update, out, version);
+        }
+
+        public Commit deserialize(DataInput in, int version) throws IOException
+        {
+            return new Commit(ByteBufferUtil.readWithShortLength(in),
+                              UUIDSerializer.serializer.deserialize(in, version),
+                              ColumnFamily.serializer.deserialize(in, version));
+        }
+
+        public long serializedSize(Commit commit, int version)
+        {
+            return 2 + commit.key.remaining()
+                   + UUIDSerializer.serializer.serializedSize(commit.ballot, version)
+                   + ColumnFamily.serializer.serializedSize(commit.update, version);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/CommitVerbHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/CommitVerbHandler.java b/src/java/org/apache/cassandra/service/paxos/CommitVerbHandler.java
new file mode 100644
index 0000000..d7944b6
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/CommitVerbHandler.java
@@ -0,0 +1,12 @@
+package org.apache.cassandra.service.paxos;
+
+import org.apache.cassandra.net.IVerbHandler;
+import org.apache.cassandra.net.MessageIn;
+
+public class CommitVerbHandler implements IVerbHandler<Commit>
+{
+    public void doVerb(MessageIn<Commit> message, int id)
+    {
+        PaxosState.commit(message.payload);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/PaxosState.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/PaxosState.java b/src/java/org/apache/cassandra/service/paxos/PaxosState.java
new file mode 100644
index 0000000..e7685b2
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/PaxosState.java
@@ -0,0 +1,100 @@
+package org.apache.cassandra.service.paxos;
+
+import java.nio.ByteBuffer;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.db.RowMutation;
+import org.apache.cassandra.db.SystemTable;
+import org.apache.cassandra.db.Table;
+
+public class PaxosState
+{
+    private static final Logger logger = LoggerFactory.getLogger(PaxosState.class);
+
+    private static final Object[] locks;
+    static
+    {
+        locks = new Object[1024];
+        for (int i = 0; i < locks.length; i++)
+            locks[i] = new Object();
+    }
+    private static Object lockFor(ByteBuffer key)
+    {
+        return locks[key.hashCode() % locks.length];
+    }
+
+    private final Commit inProgressCommit;
+    private final Commit mostRecentCommit;
+
+    public PaxosState(ByteBuffer key, CFMetaData metadata)
+    {
+        this(Commit.emptyCommit(key, metadata), Commit.emptyCommit(key, metadata));
+    }
+
+    public PaxosState(Commit inProgressCommit, Commit mostRecentCommit)
+    {
+        assert inProgressCommit.key == mostRecentCommit.key;
+        assert inProgressCommit.update.metadata() == inProgressCommit.update.metadata();
+
+        this.inProgressCommit = inProgressCommit;
+        this.mostRecentCommit = mostRecentCommit;
+    }
+
+    public static PrepareResponse prepare(Commit toPrepare)
+    {
+        synchronized (lockFor(toPrepare.key))
+        {
+            PaxosState state = SystemTable.loadPaxosState(toPrepare.key, toPrepare.update.metadata());
+            if (toPrepare.isAfter(state.inProgressCommit))
+            {
+                logger.debug("promising ballot {}", toPrepare.ballot);
+                SystemTable.savePaxosPromise(toPrepare);
+                // return the pre-promise ballot so coordinator can pick the most recent in-progress value to resume
+                return new PrepareResponse(true, state.inProgressCommit, state.mostRecentCommit);
+            }
+            else
+            {
+                logger.debug("promise rejected; {} is not sufficiently newer than {}", toPrepare, state.inProgressCommit);
+                return new PrepareResponse(false, state.inProgressCommit, state.mostRecentCommit);
+            }
+        }
+    }
+
+    public static Boolean propose(Commit proposal)
+    {
+        synchronized (lockFor(proposal.key))
+        {
+            PaxosState state = SystemTable.loadPaxosState(proposal.key, proposal.update.metadata());
+            if (proposal.hasBallot(state.inProgressCommit.ballot) || proposal.isAfter(state.inProgressCommit))
+            {
+                logger.debug("accepting {}", proposal);
+                SystemTable.savePaxosProposal(proposal);
+                return true;
+            }
+
+            logger.debug("accept requested for {} but inProgress is now {}", proposal, state.inProgressCommit);
+            return false;
+        }
+    }
+
+    public static void commit(Commit proposal)
+    {
+        // There is no guarantee we will see commits in the right order, because messages
+        // can get delayed, so a proposal can be older than our current most recent ballot/commit.
+        // Committing it is however always safe due to column timestamps, so always do it. However,
+        // if our current in-progress ballot is strictly greater than the proposal one, we shouldn't
+        // erase the in-progress update.
+        logger.debug("committing {}", proposal);
+        RowMutation rm = proposal.makeMutation();
+        Table.open(rm.getTable()).apply(rm, true);
+
+        synchronized (lockFor(proposal.key))
+        {
+            PaxosState state = SystemTable.loadPaxosState(proposal.key, proposal.update.metadata());
+            SystemTable.savePaxosCommit(proposal, !state.inProgressCommit.isAfter(proposal));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/PrepareCallback.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/PrepareCallback.java b/src/java/org/apache/cassandra/service/paxos/PrepareCallback.java
new file mode 100644
index 0000000..28e2ca4
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/PrepareCallback.java
@@ -0,0 +1,66 @@
+package org.apache.cassandra.service.paxos;
+
+import java.net.InetAddress;
+import java.nio.ByteBuffer;
+import java.util.HashMap;
+import java.util.Map;
+
+import com.google.common.base.Predicate;
+import com.google.common.collect.Iterables;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.config.CFMetaData;
+import org.apache.cassandra.net.MessageIn;
+
+public class PrepareCallback extends AbstractPaxosCallback<PrepareResponse>
+{
+    private static final Logger logger = LoggerFactory.getLogger(PrepareCallback.class);
+
+    public boolean promised = true;
+    public Commit mostRecentCommit;
+    public Commit inProgressCommit;
+
+    private Map<InetAddress, Commit> commitsByReplica = new HashMap<InetAddress, Commit>();
+
+    public PrepareCallback(ByteBuffer key, CFMetaData metadata, int targets)
+    {
+        super(targets);
+        // need to inject the right key in the empty commit so comparing with empty commits in the reply works as expected
+        mostRecentCommit = Commit.emptyCommit(key, metadata);
+        inProgressCommit = Commit.emptyCommit(key, metadata);
+    }
+
+    public synchronized void response(MessageIn<PrepareResponse> message)
+    {
+        PrepareResponse response = message.payload;
+        logger.debug("Prepare response {} from {}", response, message.from);
+
+        if (!response.promised)
+        {
+            promised = false;
+            while (latch.getCount() > 0)
+                latch.countDown();
+            return;
+        }
+
+        if (response.mostRecentCommit.isAfter(mostRecentCommit))
+            mostRecentCommit = response.mostRecentCommit;
+
+        if (response.inProgressCommit.isAfter(inProgressCommit))
+            inProgressCommit = response.inProgressCommit;
+
+        latch.countDown();
+    }
+
+    public Iterable<InetAddress> replicasMissingMostRecentCommit()
+    {
+        return Iterables.filter(commitsByReplica.keySet(), new Predicate<InetAddress>()
+        {
+            public boolean apply(InetAddress inetAddress)
+            {
+                return (!commitsByReplica.get(inetAddress).ballot.equals(mostRecentCommit.ballot));
+            }
+        });
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/PrepareResponse.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/PrepareResponse.java b/src/java/org/apache/cassandra/service/paxos/PrepareResponse.java
new file mode 100644
index 0000000..ee2ed55
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/PrepareResponse.java
@@ -0,0 +1,72 @@
+package org.apache.cassandra.service.paxos;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+
+import org.apache.cassandra.db.ColumnFamily;
+import org.apache.cassandra.io.IVersionedSerializer;
+import org.apache.cassandra.utils.ByteBufferUtil;
+import org.apache.cassandra.utils.UUIDSerializer;
+
+public class PrepareResponse
+{
+    public static final PrepareResponseSerializer serializer = new PrepareResponseSerializer();
+
+    public final boolean promised;
+    public final Commit inProgressCommit;
+    public final Commit mostRecentCommit;
+
+    public PrepareResponse(boolean promised, Commit inProgressCommit, Commit mostRecentCommit)
+    {
+        assert inProgressCommit.key == mostRecentCommit.key;
+        assert inProgressCommit.update.metadata() == mostRecentCommit.update.metadata();
+
+        this.promised = promised;
+        this.mostRecentCommit = mostRecentCommit;
+        this.inProgressCommit = inProgressCommit;
+    }
+
+    @Override
+    public String toString()
+    {
+        return String.format("PrepareResponse(%s, %s, %s)", promised, mostRecentCommit, inProgressCommit);
+    }
+
+    public static class PrepareResponseSerializer implements IVersionedSerializer<PrepareResponse>
+    {
+        public void serialize(PrepareResponse response, DataOutput out, int version) throws IOException
+        {
+            out.writeBoolean(response.promised);
+            ByteBufferUtil.writeWithShortLength(response.inProgressCommit.key, out);
+            UUIDSerializer.serializer.serialize(response.inProgressCommit.ballot, out, version);
+            ColumnFamily.serializer.serialize(response.inProgressCommit.update, out, version);
+            UUIDSerializer.serializer.serialize(response.mostRecentCommit.ballot, out, version);
+            ColumnFamily.serializer.serialize(response.mostRecentCommit.update, out, version);
+        }
+
+        public PrepareResponse deserialize(DataInput in, int version) throws IOException
+        {
+            boolean success = in.readBoolean();
+            ByteBuffer key = ByteBufferUtil.readWithShortLength(in);
+            return new PrepareResponse(success,
+                                       new Commit(key,
+                                                  UUIDSerializer.serializer.deserialize(in, version),
+                                                  ColumnFamily.serializer.deserialize(in, version)),
+                                       new Commit(key,
+                                                  UUIDSerializer.serializer.deserialize(in, version),
+                                                  ColumnFamily.serializer.deserialize(in, version)));
+        }
+
+        public long serializedSize(PrepareResponse response, int version)
+        {
+            return 1
+                   + 2 + response.inProgressCommit.key.remaining()
+                   + UUIDSerializer.serializer.serializedSize(response.inProgressCommit.ballot, version)
+                   + ColumnFamily.serializer.serializedSize(response.inProgressCommit.update, version)
+                   + UUIDSerializer.serializer.serializedSize(response.mostRecentCommit.ballot, version)
+                   + ColumnFamily.serializer.serializedSize(response.mostRecentCommit.update, version);
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/PrepareVerbHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/PrepareVerbHandler.java b/src/java/org/apache/cassandra/service/paxos/PrepareVerbHandler.java
new file mode 100644
index 0000000..e82bb66
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/PrepareVerbHandler.java
@@ -0,0 +1,16 @@
+package org.apache.cassandra.service.paxos;
+
+import org.apache.cassandra.net.IVerbHandler;
+import org.apache.cassandra.net.MessageIn;
+import org.apache.cassandra.net.MessageOut;
+import org.apache.cassandra.net.MessagingService;
+
+public class PrepareVerbHandler implements IVerbHandler<Commit>
+{
+    public void doVerb(MessageIn<Commit> message, int id)
+    {
+        PrepareResponse response = PaxosState.prepare(message.payload);
+        MessageOut<PrepareResponse> reply = new MessageOut<PrepareResponse>(MessagingService.Verb.REQUEST_RESPONSE, response, PrepareResponse.serializer);
+        MessagingService.instance().sendReply(reply, id, message.from);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/ProposeCallback.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/ProposeCallback.java b/src/java/org/apache/cassandra/service/paxos/ProposeCallback.java
new file mode 100644
index 0000000..2842ca5
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/ProposeCallback.java
@@ -0,0 +1,34 @@
+package org.apache.cassandra.service.paxos;
+
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.cassandra.net.MessageIn;
+
+public class ProposeCallback extends AbstractPaxosCallback<Boolean>
+{
+    private static final Logger logger = LoggerFactory.getLogger(ProposeCallback.class);
+
+    private final AtomicInteger successful = new AtomicInteger(0);
+
+    public ProposeCallback(int targets)
+    {
+        super(targets);
+    }
+
+    public void response(MessageIn<Boolean> msg)
+    {
+        logger.debug("Propose response {} from {}", msg.payload, msg.from);
+
+        if (msg.payload)
+            successful.incrementAndGet();
+        latch.countDown();
+    }
+
+    public int getSuccessful()
+    {
+        return successful.get();
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/service/paxos/ProposeVerbHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/paxos/ProposeVerbHandler.java b/src/java/org/apache/cassandra/service/paxos/ProposeVerbHandler.java
new file mode 100644
index 0000000..be969db
--- /dev/null
+++ b/src/java/org/apache/cassandra/service/paxos/ProposeVerbHandler.java
@@ -0,0 +1,17 @@
+package org.apache.cassandra.service.paxos;
+
+import org.apache.cassandra.net.IVerbHandler;
+import org.apache.cassandra.net.MessageIn;
+import org.apache.cassandra.net.MessageOut;
+import org.apache.cassandra.net.MessagingService;
+import org.apache.cassandra.utils.BooleanSerializer;
+
+public class ProposeVerbHandler implements IVerbHandler<Commit>
+{
+    public void doVerb(MessageIn<Commit> message, int id)
+    {
+        Boolean response = PaxosState.propose(message.payload);
+        MessageOut<Boolean> reply = new MessageOut<Boolean>(MessagingService.Verb.REQUEST_RESPONSE, response, BooleanSerializer.serializer);
+        MessagingService.instance().sendReply(reply, id, message.from);
+    }
+}

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/thrift/CassandraServer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java
index 5b96859..6a70344 100644
--- a/src/java/org/apache/cassandra/thrift/CassandraServer.java
+++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java
@@ -26,8 +26,10 @@ import java.util.concurrent.TimeoutException;
 import java.util.zip.DataFormatException;
 import java.util.zip.Inflater;
 
+import com.google.common.base.Function;
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableMap;
+import com.google.common.collect.Iterables;
 import com.google.common.collect.Lists;
 import com.google.common.collect.Maps;
 import org.slf4j.Logger;
@@ -42,19 +44,21 @@ import org.apache.cassandra.cql.CQLStatement;
 import org.apache.cassandra.cql.QueryProcessor;
 import org.apache.cassandra.db.*;
 import org.apache.cassandra.db.context.CounterContext;
-import org.apache.cassandra.db.filter.*;
+import org.apache.cassandra.db.filter.IDiskAtomFilter;
+import org.apache.cassandra.db.filter.NamesQueryFilter;
+import org.apache.cassandra.db.filter.SliceQueryFilter;
 import org.apache.cassandra.db.marshal.CompositeType;
 import org.apache.cassandra.db.marshal.MarshalException;
 import org.apache.cassandra.db.marshal.TimeUUIDType;
 import org.apache.cassandra.dht.*;
-import org.apache.cassandra.exceptions.ReadTimeoutException;
-import org.apache.cassandra.exceptions.RequestExecutionException;
-import org.apache.cassandra.exceptions.RequestValidationException;
-import org.apache.cassandra.exceptions.UnauthorizedException;
+import org.apache.cassandra.exceptions.*;
 import org.apache.cassandra.io.util.DataOutputBuffer;
 import org.apache.cassandra.locator.DynamicEndpointSnitch;
 import org.apache.cassandra.scheduler.IRequestScheduler;
-import org.apache.cassandra.service.*;
+import org.apache.cassandra.service.ClientState;
+import org.apache.cassandra.service.MigrationManager;
+import org.apache.cassandra.service.StorageProxy;
+import org.apache.cassandra.service.StorageService;
 import org.apache.cassandra.tracing.Tracing;
 import org.apache.cassandra.utils.ByteBufferUtil;
 import org.apache.cassandra.utils.Pair;
@@ -308,7 +312,7 @@ public class CassandraServer implements Cassandra.Iface
 
     private List<ColumnOrSuperColumn> thriftifyColumnFamily(ColumnFamily cf, boolean subcolumnsOnly, boolean reverseOrder)
     {
-        if (cf == null || cf.isEmpty())
+        if (cf == null || cf.getColumnCount() == 0)
             return EMPTY_COLUMNS;
 
         if (cf.metadata().isSuper())
@@ -720,6 +724,87 @@ public class CassandraServer implements Cassandra.Iface
         }
     }
 
+    public boolean cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates)
+    throws InvalidRequestException, UnavailableException, TimedOutException
+    {
+        if (startSessionIfRequested())
+        {
+            Map<String, String> traceParameters = ImmutableMap.of("key", ByteBufferUtil.bytesToHex(key),
+                                                                  "column_family", column_family,
+                                                                  "old", expected.toString(),
+                                                                  "updates", updates.toString());
+            Tracing.instance().begin("cas", traceParameters);
+        }
+        else
+        {
+            logger.debug("cas");
+        }
+
+        try
+        {
+            ThriftClientState cState = state();
+            String keyspace = cState.getKeyspace();
+            cState.hasColumnFamilyAccess(keyspace, column_family, Permission.MODIFY);
+
+            CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_family, false);
+            ThriftValidation.validateKey(metadata, key);
+            if (metadata.cfType == ColumnFamilyType.Super)
+                throw new org.apache.cassandra.exceptions.InvalidRequestException("CAS does not support supercolumns");
+
+            Iterable<ByteBuffer> names = Iterables.transform(updates, new Function<Column, ByteBuffer>()
+            {
+                public ByteBuffer apply(Column column)
+                {
+                    return column.name;
+                }
+            });
+            ThriftValidation.validateColumnNames(metadata, new ColumnParent(column_family), names);
+            for (Column column : updates)
+                ThriftValidation.validateColumnData(metadata, column, false);
+
+            CFMetaData cfm = Schema.instance.getCFMetaData(cState.getKeyspace(), column_family);
+            UnsortedColumns cfUpdates = UnsortedColumns.factory.create(cfm);
+            for (Column column : updates)
+                cfUpdates.addColumn(column.name, column.value, column.timestamp);
+
+            ColumnFamily cfExpected;
+            if (expected == null)
+            {
+                cfExpected = null;
+            }
+            else
+            {
+                cfExpected = TreeMapBackedSortedColumns.factory.create(cfm);
+                for (Column column : expected)
+                    cfExpected.addColumn(column.name, column.value, column.timestamp);
+            }
+
+            schedule(DatabaseDescriptor.getWriteRpcTimeout());
+            return StorageProxy.cas(cState.getKeyspace(), column_family, key, cfExpected, cfUpdates);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+        catch (RequestTimeoutException e)
+        {
+            throw ThriftConversion.toThrift(e);
+        }
+        catch (RequestValidationException e)
+        {
+            throw ThriftConversion.toThrift(e);
+        }
+        catch (RequestExecutionException e)
+        {
+            ThriftConversion.rethrow(e);
+            return false; // makes javac happy -- it can't tell that rethrow always throws
+        }
+        finally
+        {
+            Tracing.instance().stopSession();
+        }
+    }
+
     private List<IMutation> createMutationList(ConsistencyLevel consistency_level,
                                                Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map,
                                                boolean allowCounterMutations)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/utils/BooleanSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/BooleanSerializer.java b/src/java/org/apache/cassandra/utils/BooleanSerializer.java
new file mode 100644
index 0000000..f7e6b92
--- /dev/null
+++ b/src/java/org/apache/cassandra/utils/BooleanSerializer.java
@@ -0,0 +1,46 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.cassandra.utils;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.UUID;
+
+import org.apache.cassandra.db.TypeSizes;
+import org.apache.cassandra.io.IVersionedSerializer;
+
+public class BooleanSerializer implements IVersionedSerializer<Boolean>
+{
+    public static BooleanSerializer serializer = new BooleanSerializer();
+
+    public void serialize(Boolean b, DataOutput out, int version) throws IOException
+    {
+        out.writeBoolean(b);
+    }
+
+    public Boolean deserialize(DataInput in, int version) throws IOException
+    {
+        return in.readBoolean();
+    }
+
+    public long serializedSize(Boolean aBoolean, int version)
+    {
+        return 1;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/utils/FBUtilities.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java
index 6a9eb88..b573573 100644
--- a/src/java/org/apache/cassandra/utils/FBUtilities.java
+++ b/src/java/org/apache/cassandra/utils/FBUtilities.java
@@ -37,6 +37,7 @@ import java.util.zip.Checksum;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.AbstractIterator;
+import com.google.common.primitives.Longs;
 import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/utils/UUIDGen.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/UUIDGen.java b/src/java/org/apache/cassandra/utils/UUIDGen.java
index b54a945..bb3afd8 100644
--- a/src/java/org/apache/cassandra/utils/UUIDGen.java
+++ b/src/java/org/apache/cassandra/utils/UUIDGen.java
@@ -128,16 +128,30 @@ public class UUIDGen
         return new UUID(createTime(uuidTstamp), MAX_CLOCK_SEQ_AND_NODE);
     }
 
-    public static long unixTimestamp(UUID uuid) {
-        if (uuid.version() != 1)
-            throw new IllegalArgumentException(String.format("Can only retrieve the unix timestamp for version 1 uuid (provided version %d)", uuid.version()));
+    /**
+     * @param uuid
+     * @return milliseconds since Unix epoch
+     */
+    public static long unixTimestamp(UUID uuid)
+    {
+        return (uuid.timestamp() / 10000) + START_EPOCH;
+    }
 
-        long timestamp = uuid.timestamp();
-        return (timestamp / 10000) + START_EPOCH;
+    /**
+     * @param uuid
+     * @return microseconds since Unix epoch
+     */
+    public static long microsTimestamp(UUID uuid)
+    {
+        return (uuid.timestamp() / 10) + START_EPOCH * 1000;
     }
 
-    private static long fromUnixTimestamp(long tstamp) {
-        return (tstamp - START_EPOCH) * 10000;
+    /**
+     * @param timestamp milliseconds since Unix epoch
+     * @return
+     */
+    private static long fromUnixTimestamp(long timestamp) {
+        return (timestamp - START_EPOCH) * 10000;
     }
 
     /**

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/src/java/org/apache/cassandra/utils/UUIDSerializer.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/utils/UUIDSerializer.java b/src/java/org/apache/cassandra/utils/UUIDSerializer.java
index 9c1df6e..afaed92 100644
--- a/src/java/org/apache/cassandra/utils/UUIDSerializer.java
+++ b/src/java/org/apache/cassandra/utils/UUIDSerializer.java
@@ -29,10 +29,6 @@ public class UUIDSerializer implements IVersionedSerializer<UUID>
 {
     public static UUIDSerializer serializer = new UUIDSerializer();
 
-    private UUIDSerializer()
-    {
-    }
-
     public void serialize(UUID uuid, DataOutput out, int version) throws IOException
     {
         out.writeLong(uuid.getMostSignificantBits());

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/test/cassandra.in.sh
----------------------------------------------------------------------
diff --git a/test/cassandra.in.sh b/test/cassandra.in.sh
index 682327f..936f47d 100644
--- a/test/cassandra.in.sh
+++ b/test/cassandra.in.sh
@@ -39,7 +39,7 @@ JVM_OPTS=" \
         -Xrunjdwp:transport=dt_socket,server=y,address=8898,suspend=n \
         -Xms128M \
         -Xmx1G \
-        -Xss128k \
+        -Xss180k \
         -XX:SurvivorRatio=8 \
         -XX:TargetSurvivorRatio=90 \
         -XX:+AggressiveOpts \

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/test/system/__init__.py
----------------------------------------------------------------------
diff --git a/test/system/__init__.py b/test/system/__init__.py
index 6dd6be9..183c399 100644
--- a/test/system/__init__.py
+++ b/test/system/__init__.py
@@ -65,7 +65,7 @@ class BaseTester(object):
             if os.path.exists(pid_fname):
                 pid_path = os.path.join(root, pid_fname)
                 print "Unclean shutdown detected, (%s found)" % pid_path
-                sys.exit()
+                raise Exception('damn it')
 
             # clean out old stuff
             import shutil
@@ -103,7 +103,7 @@ class BaseTester(object):
                     stdout_value, stderr_value = process.communicate()
                     print "Stdout: %s" % (stdout_value)
                     print "Stderr: %s" % (stderr_value)
-                sys.exit()
+                raise Exception('damn it')
         else:
             try:
                 self.open_client()


[4/4] git commit: initial CAS support patch by jbellis and slebresne for CASSANDRA-5062

Posted by jb...@apache.org.
initial CAS support
patch by jbellis and slebresne for CASSANDRA-5062


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

Branch: refs/heads/trunk
Commit: 8b0e1868e8cf813ddfc98d11448aa2ad363eccc1
Parents: f5ec4c7
Author: Jonathan Ellis <jb...@apache.org>
Authored: Thu Apr 11 10:57:48 2013 -0500
Committer: Jonathan Ellis <jb...@apache.org>
Committed: Thu Apr 11 10:57:48 2013 -0500

----------------------------------------------------------------------
 CHANGES.txt                                        |    1 +
 conf/cassandra.yaml                                |    3 +
 interface/cassandra.thrift                         |   11 +-
 .../org/apache/cassandra/thrift/Cassandra.java     | 6469 +++++++++------
 .../cassandra/thrift/cassandraConstants.java       |    2 +-
 .../org/apache/cassandra/config/CFMetaData.java    |   12 +-
 src/java/org/apache/cassandra/config/Config.java   |    2 +
 .../cassandra/config/DatabaseDescriptor.java       |   10 +
 .../org/apache/cassandra/config/KSMetaData.java    |    1 +
 src/java/org/apache/cassandra/config/Schema.java   |    2 +-
 .../org/apache/cassandra/cql3/QueryProcessor.java  |    2 +-
 .../cql3/statements/ModificationStatement.java     |    2 +-
 .../db/AbstractThreadUnsafeSortedColumns.java      |    5 -
 .../cassandra/db/ArrayBackedSortedColumns.java     |    2 +-
 .../apache/cassandra/db/AtomicSortedColumns.java   |    5 -
 src/java/org/apache/cassandra/db/ColumnFamily.java |   45 +-
 .../org/apache/cassandra/db/ConsistencyLevel.java  |    3 +-
 src/java/org/apache/cassandra/db/DefsTable.java    |   12 +-
 src/java/org/apache/cassandra/db/Memtable.java     |    2 +-
 src/java/org/apache/cassandra/db/Row.java          |    8 +
 src/java/org/apache/cassandra/db/RowMutation.java  |    8 +-
 src/java/org/apache/cassandra/db/SystemTable.java  |   59 +
 src/java/org/apache/cassandra/db/WriteType.java    |    3 +-
 .../db/index/composites/CompositesSearcher.java    |    2 +-
 .../org/apache/cassandra/net/IAsyncCallback.java   |   14 +
 src/java/org/apache/cassandra/net/MessageIn.java   |    5 +
 .../org/apache/cassandra/net/MessagingService.java |   31 +-
 .../service/AbstractWriteResponseHandler.java      |   10 -
 .../org/apache/cassandra/service/StorageProxy.java |  173 +-
 .../cassandra/service/StorageProxyMBean.java       |    2 +
 .../apache/cassandra/service/StorageService.java   |   21 +-
 .../service/paxos/AbstractPaxosCallback.java       |   45 +
 .../org/apache/cassandra/service/paxos/Commit.java |  130 +
 .../cassandra/service/paxos/CommitVerbHandler.java |   12 +
 .../apache/cassandra/service/paxos/PaxosState.java |  100 +
 .../cassandra/service/paxos/PrepareCallback.java   |   66 +
 .../cassandra/service/paxos/PrepareResponse.java   |   72 +
 .../service/paxos/PrepareVerbHandler.java          |   16 +
 .../cassandra/service/paxos/ProposeCallback.java   |   34 +
 .../service/paxos/ProposeVerbHandler.java          |   17 +
 .../apache/cassandra/thrift/CassandraServer.java   |   99 +-
 .../apache/cassandra/utils/BooleanSerializer.java  |   46 +
 .../org/apache/cassandra/utils/FBUtilities.java    |    1 +
 src/java/org/apache/cassandra/utils/UUIDGen.java   |   28 +-
 .../org/apache/cassandra/utils/UUIDSerializer.java |    4 -
 test/cassandra.in.sh                               |    2 +-
 test/system/__init__.py                            |    4 +-
 test/system/test_thrift_server.py                  |   12 +
 .../apache/cassandra/db/ColumnFamilyStoreTest.java |    4 +-
 .../cassandra/db/compaction/CompactionsTest.java   |    6 +-
 50 files changed, 5105 insertions(+), 2520 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index 848e843..667c901 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
 2.0
+ * CAS support (CASSANDRA-5062, )
  * Leveled compaction performs size-tiered compactions in L0 (CASSANDRA-5371)
  * Add yaml network topology snitch for mixed ec2/other envs (CASSANDRA-5339)
  * Log when a node is down longer than the hint window (CASSANDRA-4554)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/conf/cassandra.yaml
----------------------------------------------------------------------
diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml
index ed61a26..9c1eb11 100644
--- a/conf/cassandra.yaml
+++ b/conf/cassandra.yaml
@@ -475,6 +475,9 @@ read_request_timeout_in_ms: 10000
 range_request_timeout_in_ms: 10000
 # How long the coordinator should wait for writes to complete
 write_request_timeout_in_ms: 10000
+# how long a coordinator should continue to retry a CAS operation
+# that contends with other proposals for the same row
+cas_contention_timeout_in_ms: 1000
 # How long the coordinator should wait for truncates to complete
 # (This can be much longer, because unless auto_snapshot is disabled
 # we need to flush first so we can snapshot before removing the data.)

http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/interface/cassandra.thrift
----------------------------------------------------------------------
diff --git a/interface/cassandra.thrift b/interface/cassandra.thrift
index d26cc26..a57603c 100644
--- a/interface/cassandra.thrift
+++ b/interface/cassandra.thrift
@@ -55,7 +55,7 @@ namespace rb CassandraThrift
 # An effort should be made not to break forward-client-compatibility either
 # (e.g. one should avoid removing obsolete fields from the IDL), but no
 # guarantees in this respect are made by the Cassandra project.
-const string VERSION = "19.36.0"
+const string VERSION = "19.37.0"
 
 
 #
@@ -636,6 +636,15 @@ service Cassandra {
        throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
 
   /**
+   * Atomic compare and set
+   */
+  bool cas(1:required binary key, 
+           2:required string column_family,
+           3:list<Column> expected,
+           4:list<Column> updates)
+       throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te),
+
+  /**
     Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
     that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
     row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.


[3/4] initial CAS support patch by jbellis and slebresne for CASSANDRA-5062

Posted by jb...@apache.org.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/8b0e1868/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
----------------------------------------------------------------------
diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
index 300068c..ec8ffa4 100644
--- a/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
+++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java
@@ -164,6 +164,16 @@ public class Cassandra {
     public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;
 
     /**
+     * Atomic compare and set
+     * 
+     * @param key
+     * @param column_family
+     * @param expected
+     * @param updates
+     */
+    public boolean cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException;
+
+    /**
      * Remove data from the row specified by key at the granularity specified by column_path, and the given timestamp. Note
      * that all the values in column_path besides column_path.column_family are truly optional: you can remove the entire
      * row by just specifying the ColumnFamily, or you can remove a SuperColumn or a single Column by specifying those levels too.
@@ -414,6 +424,8 @@ public class Cassandra {
 
     public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.add_call> resultHandler) throws org.apache.thrift.TException;
 
+    public void cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.cas_call> resultHandler) throws org.apache.thrift.TException;
+
     public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.remove_call> resultHandler) throws org.apache.thrift.TException;
 
     public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback<AsyncClient.remove_counter_call> resultHandler) throws org.apache.thrift.TException;
@@ -891,6 +903,41 @@ public class Cassandra {
       return;
     }
 
+    public boolean cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
+    {
+      send_cas(key, column_family, expected, updates);
+      return recv_cas();
+    }
+
+    public void send_cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates) throws org.apache.thrift.TException
+    {
+      cas_args args = new cas_args();
+      args.setKey(key);
+      args.setColumn_family(column_family);
+      args.setExpected(expected);
+      args.setUpdates(updates);
+      sendBase("cas", args);
+    }
+
+    public boolean recv_cas() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
+    {
+      cas_result result = new cas_result();
+      receiveBase(result, "cas");
+      if (result.isSetSuccess()) {
+        return result.success;
+      }
+      if (result.ire != null) {
+        throw result.ire;
+      }
+      if (result.ue != null) {
+        throw result.ue;
+      }
+      if (result.te != null) {
+        throw result.te;
+      }
+      throw new org.apache.thrift.TApplicationException(org.apache.thrift.TApplicationException.MISSING_RESULT, "cas failed: unknown result");
+    }
+
     public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException
     {
       send_remove(key, column_path, timestamp, consistency_level);
@@ -2227,6 +2274,47 @@ public class Cassandra {
       }
     }
 
+    public void cas(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, org.apache.thrift.async.AsyncMethodCallback<cas_call> resultHandler) throws org.apache.thrift.TException {
+      checkReady();
+      cas_call method_call = new cas_call(key, column_family, expected, updates, resultHandler, this, ___protocolFactory, ___transport);
+      this.___currentMethod = method_call;
+      ___manager.call(method_call);
+    }
+
+    public static class cas_call extends org.apache.thrift.async.TAsyncMethodCall {
+      private ByteBuffer key;
+      private String column_family;
+      private List<Column> expected;
+      private List<Column> updates;
+      public cas_call(ByteBuffer key, String column_family, List<Column> expected, List<Column> updates, org.apache.thrift.async.AsyncMethodCallback<cas_call> resultHandler, org.apache.thrift.async.TAsyncClient client, org.apache.thrift.protocol.TProtocolFactory protocolFactory, org.apache.thrift.transport.TNonblockingTransport transport) throws org.apache.thrift.TException {
+        super(client, protocolFactory, transport, resultHandler, false);
+        this.key = key;
+        this.column_family = column_family;
+        this.expected = expected;
+        this.updates = updates;
+      }
+
+      public void write_args(org.apache.thrift.protocol.TProtocol prot) throws org.apache.thrift.TException {
+        prot.writeMessageBegin(new org.apache.thrift.protocol.TMessage("cas", org.apache.thrift.protocol.TMessageType.CALL, 0));
+        cas_args args = new cas_args();
+        args.setKey(key);
+        args.setColumn_family(column_family);
+        args.setExpected(expected);
+        args.setUpdates(updates);
+        args.write(prot);
+        prot.writeMessageEnd();
+      }
+
+      public boolean getResult() throws InvalidRequestException, UnavailableException, TimedOutException, org.apache.thrift.TException {
+        if (getState() != org.apache.thrift.async.TAsyncMethodCall.State.RESPONSE_READ) {
+          throw new IllegalStateException("Method call not finished!");
+        }
+        org.apache.thrift.transport.TMemoryInputTransport memoryTransport = new org.apache.thrift.transport.TMemoryInputTransport(getFrameBuffer().array());
+        org.apache.thrift.protocol.TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport);
+        return (new Client(prot)).recv_cas();
+      }
+    }
+
     public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, org.apache.thrift.async.AsyncMethodCallback<remove_call> resultHandler) throws org.apache.thrift.TException {
       checkReady();
       remove_call method_call = new remove_call(key, column_path, timestamp, consistency_level, resultHandler, this, ___protocolFactory, ___transport);
@@ -3251,6 +3339,7 @@ public class Cassandra {
       processMap.put("get_indexed_slices", new get_indexed_slices());
       processMap.put("insert", new insert());
       processMap.put("add", new add());
+      processMap.put("cas", new cas());
       processMap.put("remove", new remove());
       processMap.put("remove_counter", new remove_counter());
       processMap.put("batch_mutate", new batch_mutate());
@@ -3617,6 +3706,35 @@ public class Cassandra {
       }
     }
 
+    public static class cas<I extends Iface> extends org.apache.thrift.ProcessFunction<I, cas_args> {
+      public cas() {
+        super("cas");
+      }
+
+      public cas_args getEmptyArgsInstance() {
+        return new cas_args();
+      }
+
+      protected boolean isOneway() {
+        return false;
+      }
+
+      public cas_result getResult(I iface, cas_args args) throws org.apache.thrift.TException {
+        cas_result result = new cas_result();
+        try {
+          result.success = iface.cas(args.key, args.column_family, args.expected, args.updates);
+          result.setSuccessIsSet(true);
+        } catch (InvalidRequestException ire) {
+          result.ire = ire;
+        } catch (UnavailableException ue) {
+          result.ue = ue;
+        } catch (TimedOutException te) {
+          result.te = te;
+        }
+        return result;
+      }
+    }
+
     public static class remove<I extends Iface> extends org.apache.thrift.ProcessFunction<I, remove_args> {
       public remove() {
         super("remove");
@@ -6341,7 +6459,1466 @@ public class Cassandra {
 
     @Override
     public String toString() {
-      StringBuilder sb = new StringBuilder("get_args(");
+      StringBuilder sb = new StringBuilder("get_args(");
+      boolean first = true;
+
+      sb.append("key:");
+      if (this.key == null) {
+        sb.append("null");
+      } else {
+        org.apache.thrift.TBaseHelper.toString(this.key, sb);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("column_path:");
+      if (this.column_path == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.column_path);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("consistency_level:");
+      if (this.consistency_level == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.consistency_level);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      if (key == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
+      }
+      if (column_path == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_path' was not present! Struct: " + toString());
+      }
+      if (consistency_level == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
+      }
+      // check for sub-struct validity
+      if (column_path != null) {
+        column_path.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class get_argsStandardSchemeFactory implements SchemeFactory {
+      public get_argsStandardScheme getScheme() {
+        return new get_argsStandardScheme();
+      }
+    }
+
+    private static class get_argsStandardScheme extends StandardScheme<get_args> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, get_args struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 1: // KEY
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRING) {
+                struct.key = iprot.readBinary();
+                struct.setKeyIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // COLUMN_PATH
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.column_path = new ColumnPath();
+                struct.column_path.read(iprot);
+                struct.setColumn_pathIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // CONSISTENCY_LEVEL
+              if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
+                struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
+                struct.setConsistency_levelIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, get_args struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.key != null) {
+          oprot.writeFieldBegin(KEY_FIELD_DESC);
+          oprot.writeBinary(struct.key);
+          oprot.writeFieldEnd();
+        }
+        if (struct.column_path != null) {
+          oprot.writeFieldBegin(COLUMN_PATH_FIELD_DESC);
+          struct.column_path.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.consistency_level != null) {
+          oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC);
+          oprot.writeI32(struct.consistency_level.getValue());
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class get_argsTupleSchemeFactory implements SchemeFactory {
+      public get_argsTupleScheme getScheme() {
+        return new get_argsTupleScheme();
+      }
+    }
+
+    private static class get_argsTupleScheme extends TupleScheme<get_args> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        oprot.writeBinary(struct.key);
+        struct.column_path.write(oprot);
+        oprot.writeI32(struct.consistency_level.getValue());
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        struct.key = iprot.readBinary();
+        struct.setKeyIsSet(true);
+        struct.column_path = new ColumnPath();
+        struct.column_path.read(iprot);
+        struct.setColumn_pathIsSet(true);
+        struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
+        struct.setConsistency_levelIsSet(true);
+      }
+    }
+
+  }
+
+  public static class get_result implements org.apache.thrift.TBase<get_result, get_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_result");
+
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
+    private static final org.apache.thrift.protocol.TField NFE_FIELD_DESC = new org.apache.thrift.protocol.TField("nfe", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new get_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new get_resultTupleSchemeFactory());
+    }
+
+    public ColumnOrSuperColumn success; // required
+    public InvalidRequestException ire; // required
+    public NotFoundException nfe; // required
+    public UnavailableException ue; // required
+    public TimedOutException te; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      SUCCESS((short)0, "success"),
+      IRE((short)1, "ire"),
+      NFE((short)2, "nfe"),
+      UE((short)3, "ue"),
+      TE((short)4, "te");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 0: // SUCCESS
+            return SUCCESS;
+          case 1: // IRE
+            return IRE;
+          case 2: // NFE
+            return NFE;
+          case 3: // UE
+            return UE;
+          case 4: // TE
+            return TE;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnOrSuperColumn.class)));
+      tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.NFE, new org.apache.thrift.meta_data.FieldMetaData("nfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_result.class, metaDataMap);
+    }
+
+    public get_result() {
+    }
+
+    public get_result(
+      ColumnOrSuperColumn success,
+      InvalidRequestException ire,
+      NotFoundException nfe,
+      UnavailableException ue,
+      TimedOutException te)
+    {
+      this();
+      this.success = success;
+      this.ire = ire;
+      this.nfe = nfe;
+      this.ue = ue;
+      this.te = te;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public get_result(get_result other) {
+      if (other.isSetSuccess()) {
+        this.success = new ColumnOrSuperColumn(other.success);
+      }
+      if (other.isSetIre()) {
+        this.ire = new InvalidRequestException(other.ire);
+      }
+      if (other.isSetNfe()) {
+        this.nfe = new NotFoundException(other.nfe);
+      }
+      if (other.isSetUe()) {
+        this.ue = new UnavailableException(other.ue);
+      }
+      if (other.isSetTe()) {
+        this.te = new TimedOutException(other.te);
+      }
+    }
+
+    public get_result deepCopy() {
+      return new get_result(this);
+    }
+
+    @Override
+    public void clear() {
+      this.success = null;
+      this.ire = null;
+      this.nfe = null;
+      this.ue = null;
+      this.te = null;
+    }
+
+    public ColumnOrSuperColumn getSuccess() {
+      return this.success;
+    }
+
+    public get_result setSuccess(ColumnOrSuperColumn success) {
+      this.success = success;
+      return this;
+    }
+
+    public void unsetSuccess() {
+      this.success = null;
+    }
+
+    /** Returns true if field success is set (has been assigned a value) and false otherwise */
+    public boolean isSetSuccess() {
+      return this.success != null;
+    }
+
+    public void setSuccessIsSet(boolean value) {
+      if (!value) {
+        this.success = null;
+      }
+    }
+
+    public InvalidRequestException getIre() {
+      return this.ire;
+    }
+
+    public get_result setIre(InvalidRequestException ire) {
+      this.ire = ire;
+      return this;
+    }
+
+    public void unsetIre() {
+      this.ire = null;
+    }
+
+    /** Returns true if field ire is set (has been assigned a value) and false otherwise */
+    public boolean isSetIre() {
+      return this.ire != null;
+    }
+
+    public void setIreIsSet(boolean value) {
+      if (!value) {
+        this.ire = null;
+      }
+    }
+
+    public NotFoundException getNfe() {
+      return this.nfe;
+    }
+
+    public get_result setNfe(NotFoundException nfe) {
+      this.nfe = nfe;
+      return this;
+    }
+
+    public void unsetNfe() {
+      this.nfe = null;
+    }
+
+    /** Returns true if field nfe is set (has been assigned a value) and false otherwise */
+    public boolean isSetNfe() {
+      return this.nfe != null;
+    }
+
+    public void setNfeIsSet(boolean value) {
+      if (!value) {
+        this.nfe = null;
+      }
+    }
+
+    public UnavailableException getUe() {
+      return this.ue;
+    }
+
+    public get_result setUe(UnavailableException ue) {
+      this.ue = ue;
+      return this;
+    }
+
+    public void unsetUe() {
+      this.ue = null;
+    }
+
+    /** Returns true if field ue is set (has been assigned a value) and false otherwise */
+    public boolean isSetUe() {
+      return this.ue != null;
+    }
+
+    public void setUeIsSet(boolean value) {
+      if (!value) {
+        this.ue = null;
+      }
+    }
+
+    public TimedOutException getTe() {
+      return this.te;
+    }
+
+    public get_result setTe(TimedOutException te) {
+      this.te = te;
+      return this;
+    }
+
+    public void unsetTe() {
+      this.te = null;
+    }
+
+    /** Returns true if field te is set (has been assigned a value) and false otherwise */
+    public boolean isSetTe() {
+      return this.te != null;
+    }
+
+    public void setTeIsSet(boolean value) {
+      if (!value) {
+        this.te = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case SUCCESS:
+        if (value == null) {
+          unsetSuccess();
+        } else {
+          setSuccess((ColumnOrSuperColumn)value);
+        }
+        break;
+
+      case IRE:
+        if (value == null) {
+          unsetIre();
+        } else {
+          setIre((InvalidRequestException)value);
+        }
+        break;
+
+      case NFE:
+        if (value == null) {
+          unsetNfe();
+        } else {
+          setNfe((NotFoundException)value);
+        }
+        break;
+
+      case UE:
+        if (value == null) {
+          unsetUe();
+        } else {
+          setUe((UnavailableException)value);
+        }
+        break;
+
+      case TE:
+        if (value == null) {
+          unsetTe();
+        } else {
+          setTe((TimedOutException)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case SUCCESS:
+        return getSuccess();
+
+      case IRE:
+        return getIre();
+
+      case NFE:
+        return getNfe();
+
+      case UE:
+        return getUe();
+
+      case TE:
+        return getTe();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case SUCCESS:
+        return isSetSuccess();
+      case IRE:
+        return isSetIre();
+      case NFE:
+        return isSetNfe();
+      case UE:
+        return isSetUe();
+      case TE:
+        return isSetTe();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof get_result)
+        return this.equals((get_result)that);
+      return false;
+    }
+
+    public boolean equals(get_result that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_success = true && this.isSetSuccess();
+      boolean that_present_success = true && that.isSetSuccess();
+      if (this_present_success || that_present_success) {
+        if (!(this_present_success && that_present_success))
+          return false;
+        if (!this.success.equals(that.success))
+          return false;
+      }
+
+      boolean this_present_ire = true && this.isSetIre();
+      boolean that_present_ire = true && that.isSetIre();
+      if (this_present_ire || that_present_ire) {
+        if (!(this_present_ire && that_present_ire))
+          return false;
+        if (!this.ire.equals(that.ire))
+          return false;
+      }
+
+      boolean this_present_nfe = true && this.isSetNfe();
+      boolean that_present_nfe = true && that.isSetNfe();
+      if (this_present_nfe || that_present_nfe) {
+        if (!(this_present_nfe && that_present_nfe))
+          return false;
+        if (!this.nfe.equals(that.nfe))
+          return false;
+      }
+
+      boolean this_present_ue = true && this.isSetUe();
+      boolean that_present_ue = true && that.isSetUe();
+      if (this_present_ue || that_present_ue) {
+        if (!(this_present_ue && that_present_ue))
+          return false;
+        if (!this.ue.equals(that.ue))
+          return false;
+      }
+
+      boolean this_present_te = true && this.isSetTe();
+      boolean that_present_te = true && that.isSetTe();
+      if (this_present_te || that_present_te) {
+        if (!(this_present_te && that_present_te))
+          return false;
+        if (!this.te.equals(that.te))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      HashCodeBuilder builder = new HashCodeBuilder();
+
+      boolean present_success = true && (isSetSuccess());
+      builder.append(present_success);
+      if (present_success)
+        builder.append(success);
+
+      boolean present_ire = true && (isSetIre());
+      builder.append(present_ire);
+      if (present_ire)
+        builder.append(ire);
+
+      boolean present_nfe = true && (isSetNfe());
+      builder.append(present_nfe);
+      if (present_nfe)
+        builder.append(nfe);
+
+      boolean present_ue = true && (isSetUe());
+      builder.append(present_ue);
+      if (present_ue)
+        builder.append(ue);
+
+      boolean present_te = true && (isSetTe());
+      builder.append(present_te);
+      if (present_te)
+        builder.append(te);
+
+      return builder.toHashCode();
+    }
+
+    public int compareTo(get_result other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      get_result typedOther = (get_result)other;
+
+      lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetSuccess()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.success, typedOther.success);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetIre()).compareTo(typedOther.isSetIre());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetIre()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ire, typedOther.ire);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetNfe()).compareTo(typedOther.isSetNfe());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetNfe()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nfe, typedOther.nfe);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetUe()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.ue, typedOther.ue);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetTe()).compareTo(typedOther.isSetTe());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetTe()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.te, typedOther.te);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+      }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("get_result(");
+      boolean first = true;
+
+      sb.append("success:");
+      if (this.success == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.success);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ire:");
+      if (this.ire == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ire);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("nfe:");
+      if (this.nfe == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.nfe);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("ue:");
+      if (this.ue == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.ue);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("te:");
+      if (this.te == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.te);
+      }
+      first = false;
+      sb.append(")");
+      return sb.toString();
+    }
+
+    public void validate() throws org.apache.thrift.TException {
+      // check for required fields
+      // check for sub-struct validity
+      if (success != null) {
+        success.validate();
+      }
+    }
+
+    private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
+      try {
+        write(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(out)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private void readObject(java.io.ObjectInputStream in) throws java.io.IOException, ClassNotFoundException {
+      try {
+        read(new org.apache.thrift.protocol.TCompactProtocol(new org.apache.thrift.transport.TIOStreamTransport(in)));
+      } catch (org.apache.thrift.TException te) {
+        throw new java.io.IOException(te);
+      }
+    }
+
+    private static class get_resultStandardSchemeFactory implements SchemeFactory {
+      public get_resultStandardScheme getScheme() {
+        return new get_resultStandardScheme();
+      }
+    }
+
+    private static class get_resultStandardScheme extends StandardScheme<get_result> {
+
+      public void read(org.apache.thrift.protocol.TProtocol iprot, get_result struct) throws org.apache.thrift.TException {
+        org.apache.thrift.protocol.TField schemeField;
+        iprot.readStructBegin();
+        while (true)
+        {
+          schemeField = iprot.readFieldBegin();
+          if (schemeField.type == org.apache.thrift.protocol.TType.STOP) { 
+            break;
+          }
+          switch (schemeField.id) {
+            case 0: // SUCCESS
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.success = new ColumnOrSuperColumn();
+                struct.success.read(iprot);
+                struct.setSuccessIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 1: // IRE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ire = new InvalidRequestException();
+                struct.ire.read(iprot);
+                struct.setIreIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 2: // NFE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.nfe = new NotFoundException();
+                struct.nfe.read(iprot);
+                struct.setNfeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 3: // UE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.ue = new UnavailableException();
+                struct.ue.read(iprot);
+                struct.setUeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // TE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.te = new TimedOutException();
+                struct.te.read(iprot);
+                struct.setTeIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            default:
+              org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+          }
+          iprot.readFieldEnd();
+        }
+        iprot.readStructEnd();
+
+        // check for required fields of primitive type, which can't be checked in the validate method
+        struct.validate();
+      }
+
+      public void write(org.apache.thrift.protocol.TProtocol oprot, get_result struct) throws org.apache.thrift.TException {
+        struct.validate();
+
+        oprot.writeStructBegin(STRUCT_DESC);
+        if (struct.success != null) {
+          oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
+          struct.success.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ire != null) {
+          oprot.writeFieldBegin(IRE_FIELD_DESC);
+          struct.ire.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.nfe != null) {
+          oprot.writeFieldBegin(NFE_FIELD_DESC);
+          struct.nfe.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.ue != null) {
+          oprot.writeFieldBegin(UE_FIELD_DESC);
+          struct.ue.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.te != null) {
+          oprot.writeFieldBegin(TE_FIELD_DESC);
+          struct.te.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        oprot.writeFieldStop();
+        oprot.writeStructEnd();
+      }
+
+    }
+
+    private static class get_resultTupleSchemeFactory implements SchemeFactory {
+      public get_resultTupleScheme getScheme() {
+        return new get_resultTupleScheme();
+      }
+    }
+
+    private static class get_resultTupleScheme extends TupleScheme<get_result> {
+
+      @Override
+      public void write(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol oprot = (TTupleProtocol) prot;
+        BitSet optionals = new BitSet();
+        if (struct.isSetSuccess()) {
+          optionals.set(0);
+        }
+        if (struct.isSetIre()) {
+          optionals.set(1);
+        }
+        if (struct.isSetNfe()) {
+          optionals.set(2);
+        }
+        if (struct.isSetUe()) {
+          optionals.set(3);
+        }
+        if (struct.isSetTe()) {
+          optionals.set(4);
+        }
+        oprot.writeBitSet(optionals, 5);
+        if (struct.isSetSuccess()) {
+          struct.success.write(oprot);
+        }
+        if (struct.isSetIre()) {
+          struct.ire.write(oprot);
+        }
+        if (struct.isSetNfe()) {
+          struct.nfe.write(oprot);
+        }
+        if (struct.isSetUe()) {
+          struct.ue.write(oprot);
+        }
+        if (struct.isSetTe()) {
+          struct.te.write(oprot);
+        }
+      }
+
+      @Override
+      public void read(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
+        TTupleProtocol iprot = (TTupleProtocol) prot;
+        BitSet incoming = iprot.readBitSet(5);
+        if (incoming.get(0)) {
+          struct.success = new ColumnOrSuperColumn();
+          struct.success.read(iprot);
+          struct.setSuccessIsSet(true);
+        }
+        if (incoming.get(1)) {
+          struct.ire = new InvalidRequestException();
+          struct.ire.read(iprot);
+          struct.setIreIsSet(true);
+        }
+        if (incoming.get(2)) {
+          struct.nfe = new NotFoundException();
+          struct.nfe.read(iprot);
+          struct.setNfeIsSet(true);
+        }
+        if (incoming.get(3)) {
+          struct.ue = new UnavailableException();
+          struct.ue.read(iprot);
+          struct.setUeIsSet(true);
+        }
+        if (incoming.get(4)) {
+          struct.te = new TimedOutException();
+          struct.te.read(iprot);
+          struct.setTeIsSet(true);
+        }
+      }
+    }
+
+  }
+
+  public static class get_slice_args implements org.apache.thrift.TBase<get_slice_args, get_slice_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_slice_args");
+
+    private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
+    private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField PREDICATE_FIELD_DESC = new org.apache.thrift.protocol.TField("predicate", org.apache.thrift.protocol.TType.STRUCT, (short)3);
+    private static final org.apache.thrift.protocol.TField CONSISTENCY_LEVEL_FIELD_DESC = new org.apache.thrift.protocol.TField("consistency_level", org.apache.thrift.protocol.TType.I32, (short)4);
+
+    private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
+    static {
+      schemes.put(StandardScheme.class, new get_slice_argsStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new get_slice_argsTupleSchemeFactory());
+    }
+
+    public ByteBuffer key; // required
+    public ColumnParent column_parent; // required
+    public SlicePredicate predicate; // required
+    /**
+     * 
+     * @see ConsistencyLevel
+     */
+    public ConsistencyLevel consistency_level; // required
+
+    /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
+    public enum _Fields implements org.apache.thrift.TFieldIdEnum {
+      KEY((short)1, "key"),
+      COLUMN_PARENT((short)2, "column_parent"),
+      PREDICATE((short)3, "predicate"),
+      /**
+       * 
+       * @see ConsistencyLevel
+       */
+      CONSISTENCY_LEVEL((short)4, "consistency_level");
+
+      private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
+
+      static {
+        for (_Fields field : EnumSet.allOf(_Fields.class)) {
+          byName.put(field.getFieldName(), field);
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, or null if its not found.
+       */
+      public static _Fields findByThriftId(int fieldId) {
+        switch(fieldId) {
+          case 1: // KEY
+            return KEY;
+          case 2: // COLUMN_PARENT
+            return COLUMN_PARENT;
+          case 3: // PREDICATE
+            return PREDICATE;
+          case 4: // CONSISTENCY_LEVEL
+            return CONSISTENCY_LEVEL;
+          default:
+            return null;
+        }
+      }
+
+      /**
+       * Find the _Fields constant that matches fieldId, throwing an exception
+       * if it is not found.
+       */
+      public static _Fields findByThriftIdOrThrow(int fieldId) {
+        _Fields fields = findByThriftId(fieldId);
+        if (fields == null) throw new IllegalArgumentException("Field " + fieldId + " doesn't exist!");
+        return fields;
+      }
+
+      /**
+       * Find the _Fields constant that matches name, or null if its not found.
+       */
+      public static _Fields findByName(String name) {
+        return byName.get(name);
+      }
+
+      private final short _thriftId;
+      private final String _fieldName;
+
+      _Fields(short thriftId, String fieldName) {
+        _thriftId = thriftId;
+        _fieldName = fieldName;
+      }
+
+      public short getThriftFieldId() {
+        return _thriftId;
+      }
+
+      public String getFieldName() {
+        return _fieldName;
+      }
+    }
+
+    // isset id assignments
+    public static final Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> metaDataMap;
+    static {
+      Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
+      tmpMap.put(_Fields.KEY, new org.apache.thrift.meta_data.FieldMetaData("key", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRING          , true)));
+      tmpMap.put(_Fields.COLUMN_PARENT, new org.apache.thrift.meta_data.FieldMetaData("column_parent", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnParent.class)));
+      tmpMap.put(_Fields.PREDICATE, new org.apache.thrift.meta_data.FieldMetaData("predicate", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, SlicePredicate.class)));
+      tmpMap.put(_Fields.CONSISTENCY_LEVEL, new org.apache.thrift.meta_data.FieldMetaData("consistency_level", org.apache.thrift.TFieldRequirementType.REQUIRED, 
+          new org.apache.thrift.meta_data.EnumMetaData(org.apache.thrift.protocol.TType.ENUM, ConsistencyLevel.class)));
+      metaDataMap = Collections.unmodifiableMap(tmpMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_slice_args.class, metaDataMap);
+    }
+
+    public get_slice_args() {
+      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;
+
+    }
+
+    public get_slice_args(
+      ByteBuffer key,
+      ColumnParent column_parent,
+      SlicePredicate predicate,
+      ConsistencyLevel consistency_level)
+    {
+      this();
+      this.key = key;
+      this.column_parent = column_parent;
+      this.predicate = predicate;
+      this.consistency_level = consistency_level;
+    }
+
+    /**
+     * Performs a deep copy on <i>other</i>.
+     */
+    public get_slice_args(get_slice_args other) {
+      if (other.isSetKey()) {
+        this.key = org.apache.thrift.TBaseHelper.copyBinary(other.key);
+;
+      }
+      if (other.isSetColumn_parent()) {
+        this.column_parent = new ColumnParent(other.column_parent);
+      }
+      if (other.isSetPredicate()) {
+        this.predicate = new SlicePredicate(other.predicate);
+      }
+      if (other.isSetConsistency_level()) {
+        this.consistency_level = other.consistency_level;
+      }
+    }
+
+    public get_slice_args deepCopy() {
+      return new get_slice_args(this);
+    }
+
+    @Override
+    public void clear() {
+      this.key = null;
+      this.column_parent = null;
+      this.predicate = null;
+      this.consistency_level = org.apache.cassandra.thrift.ConsistencyLevel.ONE;
+
+    }
+
+    public byte[] getKey() {
+      setKey(org.apache.thrift.TBaseHelper.rightSize(key));
+      return key == null ? null : key.array();
+    }
+
+    public ByteBuffer bufferForKey() {
+      return key;
+    }
+
+    public get_slice_args setKey(byte[] key) {
+      setKey(key == null ? (ByteBuffer)null : ByteBuffer.wrap(key));
+      return this;
+    }
+
+    public get_slice_args setKey(ByteBuffer key) {
+      this.key = key;
+      return this;
+    }
+
+    public void unsetKey() {
+      this.key = null;
+    }
+
+    /** Returns true if field key is set (has been assigned a value) and false otherwise */
+    public boolean isSetKey() {
+      return this.key != null;
+    }
+
+    public void setKeyIsSet(boolean value) {
+      if (!value) {
+        this.key = null;
+      }
+    }
+
+    public ColumnParent getColumn_parent() {
+      return this.column_parent;
+    }
+
+    public get_slice_args setColumn_parent(ColumnParent column_parent) {
+      this.column_parent = column_parent;
+      return this;
+    }
+
+    public void unsetColumn_parent() {
+      this.column_parent = null;
+    }
+
+    /** Returns true if field column_parent is set (has been assigned a value) and false otherwise */
+    public boolean isSetColumn_parent() {
+      return this.column_parent != null;
+    }
+
+    public void setColumn_parentIsSet(boolean value) {
+      if (!value) {
+        this.column_parent = null;
+      }
+    }
+
+    public SlicePredicate getPredicate() {
+      return this.predicate;
+    }
+
+    public get_slice_args setPredicate(SlicePredicate predicate) {
+      this.predicate = predicate;
+      return this;
+    }
+
+    public void unsetPredicate() {
+      this.predicate = null;
+    }
+
+    /** Returns true if field predicate is set (has been assigned a value) and false otherwise */
+    public boolean isSetPredicate() {
+      return this.predicate != null;
+    }
+
+    public void setPredicateIsSet(boolean value) {
+      if (!value) {
+        this.predicate = null;
+      }
+    }
+
+    /**
+     * 
+     * @see ConsistencyLevel
+     */
+    public ConsistencyLevel getConsistency_level() {
+      return this.consistency_level;
+    }
+
+    /**
+     * 
+     * @see ConsistencyLevel
+     */
+    public get_slice_args setConsistency_level(ConsistencyLevel consistency_level) {
+      this.consistency_level = consistency_level;
+      return this;
+    }
+
+    public void unsetConsistency_level() {
+      this.consistency_level = null;
+    }
+
+    /** Returns true if field consistency_level is set (has been assigned a value) and false otherwise */
+    public boolean isSetConsistency_level() {
+      return this.consistency_level != null;
+    }
+
+    public void setConsistency_levelIsSet(boolean value) {
+      if (!value) {
+        this.consistency_level = null;
+      }
+    }
+
+    public void setFieldValue(_Fields field, Object value) {
+      switch (field) {
+      case KEY:
+        if (value == null) {
+          unsetKey();
+        } else {
+          setKey((ByteBuffer)value);
+        }
+        break;
+
+      case COLUMN_PARENT:
+        if (value == null) {
+          unsetColumn_parent();
+        } else {
+          setColumn_parent((ColumnParent)value);
+        }
+        break;
+
+      case PREDICATE:
+        if (value == null) {
+          unsetPredicate();
+        } else {
+          setPredicate((SlicePredicate)value);
+        }
+        break;
+
+      case CONSISTENCY_LEVEL:
+        if (value == null) {
+          unsetConsistency_level();
+        } else {
+          setConsistency_level((ConsistencyLevel)value);
+        }
+        break;
+
+      }
+    }
+
+    public Object getFieldValue(_Fields field) {
+      switch (field) {
+      case KEY:
+        return getKey();
+
+      case COLUMN_PARENT:
+        return getColumn_parent();
+
+      case PREDICATE:
+        return getPredicate();
+
+      case CONSISTENCY_LEVEL:
+        return getConsistency_level();
+
+      }
+      throw new IllegalStateException();
+    }
+
+    /** Returns true if field corresponding to fieldID is set (has been assigned a value) and false otherwise */
+    public boolean isSet(_Fields field) {
+      if (field == null) {
+        throw new IllegalArgumentException();
+      }
+
+      switch (field) {
+      case KEY:
+        return isSetKey();
+      case COLUMN_PARENT:
+        return isSetColumn_parent();
+      case PREDICATE:
+        return isSetPredicate();
+      case CONSISTENCY_LEVEL:
+        return isSetConsistency_level();
+      }
+      throw new IllegalStateException();
+    }
+
+    @Override
+    public boolean equals(Object that) {
+      if (that == null)
+        return false;
+      if (that instanceof get_slice_args)
+        return this.equals((get_slice_args)that);
+      return false;
+    }
+
+    public boolean equals(get_slice_args that) {
+      if (that == null)
+        return false;
+
+      boolean this_present_key = true && this.isSetKey();
+      boolean that_present_key = true && that.isSetKey();
+      if (this_present_key || that_present_key) {
+        if (!(this_present_key && that_present_key))
+          return false;
+        if (!this.key.equals(that.key))
+          return false;
+      }
+
+      boolean this_present_column_parent = true && this.isSetColumn_parent();
+      boolean that_present_column_parent = true && that.isSetColumn_parent();
+      if (this_present_column_parent || that_present_column_parent) {
+        if (!(this_present_column_parent && that_present_column_parent))
+          return false;
+        if (!this.column_parent.equals(that.column_parent))
+          return false;
+      }
+
+      boolean this_present_predicate = true && this.isSetPredicate();
+      boolean that_present_predicate = true && that.isSetPredicate();
+      if (this_present_predicate || that_present_predicate) {
+        if (!(this_present_predicate && that_present_predicate))
+          return false;
+        if (!this.predicate.equals(that.predicate))
+          return false;
+      }
+
+      boolean this_present_consistency_level = true && this.isSetConsistency_level();
+      boolean that_present_consistency_level = true && that.isSetConsistency_level();
+      if (this_present_consistency_level || that_present_consistency_level) {
+        if (!(this_present_consistency_level && that_present_consistency_level))
+          return false;
+        if (!this.consistency_level.equals(that.consistency_level))
+          return false;
+      }
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      HashCodeBuilder builder = new HashCodeBuilder();
+
+      boolean present_key = true && (isSetKey());
+      builder.append(present_key);
+      if (present_key)
+        builder.append(key);
+
+      boolean present_column_parent = true && (isSetColumn_parent());
+      builder.append(present_column_parent);
+      if (present_column_parent)
+        builder.append(column_parent);
+
+      boolean present_predicate = true && (isSetPredicate());
+      builder.append(present_predicate);
+      if (present_predicate)
+        builder.append(predicate);
+
+      boolean present_consistency_level = true && (isSetConsistency_level());
+      builder.append(present_consistency_level);
+      if (present_consistency_level)
+        builder.append(consistency_level.getValue());
+
+      return builder.toHashCode();
+    }
+
+    public int compareTo(get_slice_args other) {
+      if (!getClass().equals(other.getClass())) {
+        return getClass().getName().compareTo(other.getClass().getName());
+      }
+
+      int lastComparison = 0;
+      get_slice_args typedOther = (get_slice_args)other;
+
+      lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetKey()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.key, typedOther.key);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(typedOther.isSetColumn_parent());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetColumn_parent()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.column_parent, typedOther.column_parent);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(typedOther.isSetPredicate());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetPredicate()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.predicate, typedOther.predicate);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(typedOther.isSetConsistency_level());
+      if (lastComparison != 0) {
+        return lastComparison;
+      }
+      if (isSetConsistency_level()) {
+        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.consistency_level, typedOther.consistency_level);
+        if (lastComparison != 0) {
+          return lastComparison;
+        }
+      }
+      return 0;
+    }
+
+    public _Fields fieldForId(int fieldId) {
+      return _Fields.findByThriftId(fieldId);
+    }
+
+    public void read(org.apache.thrift.protocol.TProtocol iprot) throws org.apache.thrift.TException {
+      schemes.get(iprot.getScheme()).getScheme().read(iprot, this);
+    }
+
+    public void write(org.apache.thrift.protocol.TProtocol oprot) throws org.apache.thrift.TException {
+      schemes.get(oprot.getScheme()).getScheme().write(oprot, this);
+    }
+
+    @Override
+    public String toString() {
+      StringBuilder sb = new StringBuilder("get_slice_args(");
       boolean first = true;
 
       sb.append("key:");
@@ -6352,11 +7929,19 @@ public class Cassandra {
       }
       first = false;
       if (!first) sb.append(", ");
-      sb.append("column_path:");
-      if (this.column_path == null) {
+      sb.append("column_parent:");
+      if (this.column_parent == null) {
         sb.append("null");
       } else {
-        sb.append(this.column_path);
+        sb.append(this.column_parent);
+      }
+      first = false;
+      if (!first) sb.append(", ");
+      sb.append("predicate:");
+      if (this.predicate == null) {
+        sb.append("null");
+      } else {
+        sb.append(this.predicate);
       }
       first = false;
       if (!first) sb.append(", ");
@@ -6376,15 +7961,21 @@ public class Cassandra {
       if (key == null) {
         throw new org.apache.thrift.protocol.TProtocolException("Required field 'key' was not present! Struct: " + toString());
       }
-      if (column_path == null) {
-        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_path' was not present! Struct: " + toString());
+      if (column_parent == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'column_parent' was not present! Struct: " + toString());
+      }
+      if (predicate == null) {
+        throw new org.apache.thrift.protocol.TProtocolException("Required field 'predicate' was not present! Struct: " + toString());
       }
       if (consistency_level == null) {
         throw new org.apache.thrift.protocol.TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString());
       }
       // check for sub-struct validity
-      if (column_path != null) {
-        column_path.validate();
+      if (column_parent != null) {
+        column_parent.validate();
+      }
+      if (predicate != null) {
+        predicate.validate();
       }
     }
 
@@ -6404,15 +7995,15 @@ public class Cassandra {
       }
     }
 
-    private static class get_argsStandardSchemeFactory implements SchemeFactory {
-      public get_argsStandardScheme getScheme() {
-        return new get_argsStandardScheme();
+    private static class get_slice_argsStandardSchemeFactory implements SchemeFactory {
+      public get_slice_argsStandardScheme getScheme() {
+        return new get_slice_argsStandardScheme();
       }
     }
 
-    private static class get_argsStandardScheme extends StandardScheme<get_args> {
+    private static class get_slice_argsStandardScheme extends StandardScheme<get_slice_args> {
 
-      public void read(org.apache.thrift.protocol.TProtocol iprot, get_args struct) throws org.apache.thrift.TException {
+      public void read(org.apache.thrift.protocol.TProtocol iprot, get_slice_args struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
         iprot.readStructBegin();
         while (true)
@@ -6430,16 +8021,25 @@ public class Cassandra {
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
               }
               break;
-            case 2: // COLUMN_PATH
+            case 2: // COLUMN_PARENT
               if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
-                struct.column_path = new ColumnPath();
-                struct.column_path.read(iprot);
-                struct.setColumn_pathIsSet(true);
+                struct.column_parent = new ColumnParent();
+                struct.column_parent.read(iprot);
+                struct.setColumn_parentIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
               }
               break;
-            case 3: // CONSISTENCY_LEVEL
+            case 3: // PREDICATE
+              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
+                struct.predicate = new SlicePredicate();
+                struct.predicate.read(iprot);
+                struct.setPredicateIsSet(true);
+              } else { 
+                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
+              }
+              break;
+            case 4: // CONSISTENCY_LEVEL
               if (schemeField.type == org.apache.thrift.protocol.TType.I32) {
                 struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
                 struct.setConsistency_levelIsSet(true);
@@ -6458,7 +8058,7 @@ public class Cassandra {
         struct.validate();
       }
 
-      public void write(org.apache.thrift.protocol.TProtocol oprot, get_args struct) throws org.apache.thrift.TException {
+      public void write(org.apache.thrift.protocol.TProtocol oprot, get_slice_args struct) throws org.apache.thrift.TException {
         struct.validate();
 
         oprot.writeStructBegin(STRUCT_DESC);
@@ -6467,9 +8067,14 @@ public class Cassandra {
           oprot.writeBinary(struct.key);
           oprot.writeFieldEnd();
         }
-        if (struct.column_path != null) {
-          oprot.writeFieldBegin(COLUMN_PATH_FIELD_DESC);
-          struct.column_path.write(oprot);
+        if (struct.column_parent != null) {
+          oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC);
+          struct.column_parent.write(oprot);
+          oprot.writeFieldEnd();
+        }
+        if (struct.predicate != null) {
+          oprot.writeFieldBegin(PREDICATE_FIELD_DESC);
+          struct.predicate.write(oprot);
           oprot.writeFieldEnd();
         }
         if (struct.consistency_level != null) {
@@ -6483,30 +8088,34 @@ public class Cassandra {
 
     }
 
-    private static class get_argsTupleSchemeFactory implements SchemeFactory {
-      public get_argsTupleScheme getScheme() {
-        return new get_argsTupleScheme();
+    private static class get_slice_argsTupleSchemeFactory implements SchemeFactory {
+      public get_slice_argsTupleScheme getScheme() {
+        return new get_slice_argsTupleScheme();
       }
     }
 
-    private static class get_argsTupleScheme extends TupleScheme<get_args> {
+    private static class get_slice_argsTupleScheme extends TupleScheme<get_slice_args> {
 
       @Override
-      public void write(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
+      public void write(org.apache.thrift.protocol.TProtocol prot, get_slice_args struct) throws org.apache.thrift.TException {
         TTupleProtocol oprot = (TTupleProtocol) prot;
         oprot.writeBinary(struct.key);
-        struct.column_path.write(oprot);
+        struct.column_parent.write(oprot);
+        struct.predicate.write(oprot);
         oprot.writeI32(struct.consistency_level.getValue());
       }
 
       @Override
-      public void read(org.apache.thrift.protocol.TProtocol prot, get_args struct) throws org.apache.thrift.TException {
+      public void read(org.apache.thrift.protocol.TProtocol prot, get_slice_args struct) throws org.apache.thrift.TException {
         TTupleProtocol iprot = (TTupleProtocol) prot;
         struct.key = iprot.readBinary();
         struct.setKeyIsSet(true);
-        struct.column_path = new ColumnPath();
-        struct.column_path.read(iprot);
-        struct.setColumn_pathIsSet(true);
+        struct.column_parent = new ColumnParent();
+        struct.column_parent.read(iprot);
+        struct.setColumn_parentIsSet(true);
+        struct.predicate = new SlicePredicate();
+        struct.predicate.read(iprot);
+        struct.setPredicateIsSet(true);
         struct.consistency_level = ConsistencyLevel.findByValue(iprot.readI32());
         struct.setConsistency_levelIsSet(true);
       }
@@ -6514,24 +8123,22 @@ public class Cassandra {
 
   }
 
-  public static class get_result implements org.apache.thrift.TBase<get_result, get_result._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_result");
+  public static class get_slice_result implements org.apache.thrift.TBase<get_slice_result, get_slice_result._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_slice_result");
 
-    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.STRUCT, (short)0);
+    private static final org.apache.thrift.protocol.TField SUCCESS_FIELD_DESC = new org.apache.thrift.protocol.TField("success", org.apache.thrift.protocol.TType.LIST, (short)0);
     private static final org.apache.thrift.protocol.TField IRE_FIELD_DESC = new org.apache.thrift.protocol.TField("ire", org.apache.thrift.protocol.TType.STRUCT, (short)1);
-    private static final org.apache.thrift.protocol.TField NFE_FIELD_DESC = new org.apache.thrift.protocol.TField("nfe", org.apache.thrift.protocol.TType.STRUCT, (short)2);
-    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)3);
-    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)4);
+    private static final org.apache.thrift.protocol.TField UE_FIELD_DESC = new org.apache.thrift.protocol.TField("ue", org.apache.thrift.protocol.TType.STRUCT, (short)2);
+    private static final org.apache.thrift.protocol.TField TE_FIELD_DESC = new org.apache.thrift.protocol.TField("te", org.apache.thrift.protocol.TType.STRUCT, (short)3);
 
     private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
     static {
-      schemes.put(StandardScheme.class, new get_resultStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new get_resultTupleSchemeFactory());
+      schemes.put(StandardScheme.class, new get_slice_resultStandardSchemeFactory());
+      schemes.put(TupleScheme.class, new get_slice_resultTupleSchemeFactory());
     }
 
-    public ColumnOrSuperColumn success; // required
+    public List<ColumnOrSuperColumn> success; // required
     public InvalidRequestException ire; // required
-    public NotFoundException nfe; // required
     public UnavailableException ue; // required
     public TimedOutException te; // required
 
@@ -6539,9 +8146,8 @@ public class Cassandra {
     public enum _Fields implements org.apache.thrift.TFieldIdEnum {
       SUCCESS((short)0, "success"),
       IRE((short)1, "ire"),
-      NFE((short)2, "nfe"),
-      UE((short)3, "ue"),
-      TE((short)4, "te");
+      UE((short)2, "ue"),
+      TE((short)3, "te");
 
       private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
 
@@ -6560,11 +8166,9 @@ public class Cassandra {
             return SUCCESS;
           case 1: // IRE
             return IRE;
-          case 2: // NFE
-            return NFE;
-          case 3: // UE
+          case 2: // UE
             return UE;
-          case 4: // TE
+          case 3: // TE
             return TE;
           default:
             return null;
@@ -6610,33 +8214,30 @@ public class Cassandra {
     static {
       Map<_Fields, org.apache.thrift.meta_data.FieldMetaData> tmpMap = new EnumMap<_Fields, org.apache.thrift.meta_data.FieldMetaData>(_Fields.class);
       tmpMap.put(_Fields.SUCCESS, new org.apache.thrift.meta_data.FieldMetaData("success", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnOrSuperColumn.class)));
+          new org.apache.thrift.meta_data.ListMetaData(org.apache.thrift.protocol.TType.LIST, 
+              new org.apache.thrift.meta_data.StructMetaData(org.apache.thrift.protocol.TType.STRUCT, ColumnOrSuperColumn.class))));
       tmpMap.put(_Fields.IRE, new org.apache.thrift.meta_data.FieldMetaData("ire", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
-      tmpMap.put(_Fields.NFE, new org.apache.thrift.meta_data.FieldMetaData("nfe", org.apache.thrift.TFieldRequirementType.DEFAULT, 
-          new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
       tmpMap.put(_Fields.UE, new org.apache.thrift.meta_data.FieldMetaData("ue", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
       tmpMap.put(_Fields.TE, new org.apache.thrift.meta_data.FieldMetaData("te", org.apache.thrift.TFieldRequirementType.DEFAULT, 
           new org.apache.thrift.meta_data.FieldValueMetaData(org.apache.thrift.protocol.TType.STRUCT)));
       metaDataMap = Collections.unmodifiableMap(tmpMap);
-      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_result.class, metaDataMap);
+      org.apache.thrift.meta_data.FieldMetaData.addStructMetaDataMap(get_slice_result.class, metaDataMap);
     }
 
-    public get_result() {
+    public get_slice_result() {
     }
 
-    public get_result(
-      ColumnOrSuperColumn success,
+    public get_slice_result(
+      List<ColumnOrSuperColumn> success,
       InvalidRequestException ire,
-      NotFoundException nfe,
       UnavailableException ue,
       TimedOutException te)
     {
       this();
       this.success = success;
       this.ire = ire;
-      this.nfe = nfe;
       this.ue = ue;
       this.te = te;
     }
@@ -6644,16 +8245,17 @@ public class Cassandra {
     /**
      * Performs a deep copy on <i>other</i>.
      */
-    public get_result(get_result other) {
+    public get_slice_result(get_slice_result other) {
       if (other.isSetSuccess()) {
-        this.success = new ColumnOrSuperColumn(other.success);
+        List<ColumnOrSuperColumn> __this__success = new ArrayList<ColumnOrSuperColumn>();
+        for (ColumnOrSuperColumn other_element : other.success) {
+          __this__success.add(new ColumnOrSuperColumn(other_element));
+        }
+        this.success = __this__success;
       }
       if (other.isSetIre()) {
         this.ire = new InvalidRequestException(other.ire);
       }
-      if (other.isSetNfe()) {
-        this.nfe = new NotFoundException(other.nfe);
-      }
       if (other.isSetUe()) {
         this.ue = new UnavailableException(other.ue);
       }
@@ -6662,24 +8264,38 @@ public class Cassandra {
       }
     }
 
-    public get_result deepCopy() {
-      return new get_result(this);
+    public get_slice_result deepCopy() {
+      return new get_slice_result(this);
     }
 
     @Override
     public void clear() {
       this.success = null;
       this.ire = null;
-      this.nfe = null;
       this.ue = null;
       this.te = null;
     }
 
-    public ColumnOrSuperColumn getSuccess() {
+    public int getSuccessSize() {
+      return (this.success == null) ? 0 : this.success.size();
+    }
+
+    public java.util.Iterator<ColumnOrSuperColumn> getSuccessIterator() {
+      return (this.success == null) ? null : this.success.iterator();
+    }
+
+    public void addToSuccess(ColumnOrSuperColumn elem) {
+      if (this.success == null) {
+        this.success = new ArrayList<ColumnOrSuperColumn>();
+      }
+      this.success.add(elem);
+    }
+
+    public List<ColumnOrSuperColumn> getSuccess() {
       return this.success;
     }
 
-    public get_result setSuccess(ColumnOrSuperColumn success) {
+    public get_slice_result setSuccess(List<ColumnOrSuperColumn> success) {
       this.success = success;
       return this;
     }
@@ -6703,7 +8319,7 @@ public class Cassandra {
       return this.ire;
     }
 
-    public get_result setIre(InvalidRequestException ire) {
+    public get_slice_result setIre(InvalidRequestException ire) {
       this.ire = ire;
       return this;
     }
@@ -6723,35 +8339,11 @@ public class Cassandra {
       }
     }
 
-    public NotFoundException getNfe() {
-      return this.nfe;
-    }
-
-    public get_result setNfe(NotFoundException nfe) {
-      this.nfe = nfe;
-      return this;
-    }
-
-    public void unsetNfe() {
-      this.nfe = null;
-    }
-
-    /** Returns true if field nfe is set (has been assigned a value) and false otherwise */
-    public boolean isSetNfe() {
-      return this.nfe != null;
-    }
-
-    public void setNfeIsSet(boolean value) {
-      if (!value) {
-        this.nfe = null;
-      }
-    }
-
     public UnavailableException getUe() {
       return this.ue;
     }
 
-    public get_result setUe(UnavailableException ue) {
+    public get_slice_result setUe(UnavailableException ue) {
       this.ue = ue;
       return this;
     }
@@ -6775,7 +8367,7 @@ public class Cassandra {
       return this.te;
     }
 
-    public get_result setTe(TimedOutException te) {
+    public get_slice_result setTe(TimedOutException te) {
       this.te = te;
       return this;
     }
@@ -6801,7 +8393,7 @@ public class Cassandra {
         if (value == null) {
           unsetSuccess();
         } else {
-          setSuccess((ColumnOrSuperColumn)value);
+          setSuccess((List<ColumnOrSuperColumn>)value);
         }
         break;
 
@@ -6813,14 +8405,6 @@ public class Cassandra {
         }
         break;
 
-      case NFE:
-        if (value == null) {
-          unsetNfe();
-        } else {
-          setNfe((NotFoundException)value);
-        }
-        break;
-
       case UE:
         if (value == null) {
           unsetUe();
@@ -6848,9 +8432,6 @@ public class Cassandra {
       case IRE:
         return getIre();
 
-      case NFE:
-        return getNfe();
-
       case UE:
         return getUe();
 
@@ -6872,8 +8453,6 @@ public class Cassandra {
         return isSetSuccess();
       case IRE:
         return isSetIre();
-      case NFE:
-        return isSetNfe();
       case UE:
         return isSetUe();
       case TE:
@@ -6886,12 +8465,12 @@ public class Cassandra {
     public boolean equals(Object that) {
       if (that == null)
         return false;
-      if (that instanceof get_result)
-        return this.equals((get_result)that);
+      if (that instanceof get_slice_result)
+        return this.equals((get_slice_result)that);
       return false;
     }
 
-    public boolean equals(get_result that) {
+    public boolean equals(get_slice_result that) {
       if (that == null)
         return false;
 
@@ -6913,15 +8492,6 @@ public class Cassandra {
           return false;
       }
 
-      boolean this_present_nfe = true && this.isSetNfe();
-      boolean that_present_nfe = true && that.isSetNfe();
-      if (this_present_nfe || that_present_nfe) {
-        if (!(this_present_nfe && that_present_nfe))
-          return false;
-        if (!this.nfe.equals(that.nfe))
-          return false;
-      }
-
       boolean this_present_ue = true && this.isSetUe();
       boolean that_present_ue = true && that.isSetUe();
       if (this_present_ue || that_present_ue) {
@@ -6957,11 +8527,6 @@ public class Cassandra {
       if (present_ire)
         builder.append(ire);
 
-      boolean present_nfe = true && (isSetNfe());
-      builder.append(present_nfe);
-      if (present_nfe)
-        builder.append(nfe);
-
       boolean present_ue = true && (isSetUe());
       builder.append(present_ue);
       if (present_ue)
@@ -6975,13 +8540,13 @@ public class Cassandra {
       return builder.toHashCode();
     }
 
-    public int compareTo(get_result other) {
+    public int compareTo(get_slice_result other) {
       if (!getClass().equals(other.getClass())) {
         return getClass().getName().compareTo(other.getClass().getName());
       }
 
       int lastComparison = 0;
-      get_result typedOther = (get_result)other;
+      get_slice_result typedOther = (get_slice_result)other;
 
       lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess());
       if (lastComparison != 0) {
@@ -7003,16 +8568,6 @@ public class Cassandra {
           return lastComparison;
         }
       }
-      lastComparison = Boolean.valueOf(isSetNfe()).compareTo(typedOther.isSetNfe());
-      if (lastComparison != 0) {
-        return lastComparison;
-      }
-      if (isSetNfe()) {
-        lastComparison = org.apache.thrift.TBaseHelper.compareTo(this.nfe, typedOther.nfe);
-        if (lastComparison != 0) {
-          return lastComparison;
-        }
-      }
       lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe());
       if (lastComparison != 0) {
         return lastComparison;
@@ -7050,7 +8605,7 @@ public class Cassandra {
 
     @Override
     public String toString() {
-      StringBuilder sb = new StringBuilder("get_result(");
+      StringBuilder sb = new StringBuilder("get_slice_result(");
       boolean first = true;
 
       sb.append("success:");
@@ -7069,14 +8624,6 @@ public class Cassandra {
       }
       first = false;
       if (!first) sb.append(", ");
-      sb.append("nfe:");
-      if (this.nfe == null) {
-        sb.append("null");
-      } else {
-        sb.append(this.nfe);
-      }
-      first = false;
-      if (!first) sb.append(", ");
       sb.append("ue:");
       if (this.ue == null) {
         sb.append("null");
@@ -7099,9 +8646,6 @@ public class Cassandra {
     public void validate() throws org.apache.thrift.TException {
       // check for required fields
       // check for sub-struct validity
-      if (success != null) {
-        success.validate();
-      }
     }
 
     private void writeObject(java.io.ObjectOutputStream out) throws java.io.IOException {
@@ -7120,15 +8664,15 @@ public class Cassandra {
       }
     }
 
-    private static class get_resultStandardSchemeFactory implements SchemeFactory {
-      public get_resultStandardScheme getScheme() {
-        return new get_resultStandardScheme();
+    private static class get_slice_resultStandardSchemeFactory implements SchemeFactory {
+      public get_slice_resultStandardScheme getScheme() {
+        return new get_slice_resultStandardScheme();
       }
     }
 
-    private static class get_resultStandardScheme extends StandardScheme<get_result> {
+    private static class get_slice_resultStandardScheme extends StandardScheme<get_slice_result> {
 
-      public void read(org.apache.thrift.protocol.TProtocol iprot, get_result struct) throws org.apache.thrift.TException {
+      public void read(org.apache.thrift.protocol.TProtocol iprot, get_slice_result struct) throws org.apache.thrift.TException {
         org.apache.thrift.protocol.TField schemeField;
         iprot.readStructBegin();
         while (true)
@@ -7139,9 +8683,19 @@ public class Cassandra {
           }
           switch (schemeField.id) {
             case 0: // SUCCESS
-              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
-                struct.success = new ColumnOrSuperColumn();
-                struct.success.read(iprot);
+              if (schemeField.type == org.apache.thrift.protocol.TType.LIST) {
+                {
+                  org.apache.thrift.protocol.TList _list190 = iprot.readListBegin();
+                  struct.success = new ArrayList<ColumnOrSuperColumn>(_list190.size);
+                  for (int _i191 = 0; _i191 < _list190.size; ++_i191)
+                  {
+                    ColumnOrSuperColumn _elem192; // required
+                    _elem192 = new ColumnOrSuperColumn();
+                    _elem192.read(iprot);
+                    struct.success.add(_elem192);
+                  }
+                  iprot.readListEnd();
+                }
                 struct.setSuccessIsSet(true);
               } else { 
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
@@ -7156,16 +8710,7 @@ public class Cassandra {
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
               }
               break;
-            case 2: // NFE
-              if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
-                struct.nfe = new NotFoundException();
-                struct.nfe.read(iprot);
-                struct.setNfeIsSet(true);
-              } else { 
-                org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
-              }
-              break;
-            case 3: // UE
+            case 2: // UE
               if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                 struct.ue = new UnavailableException();
                 struct.ue.read(iprot);
@@ -7174,7 +8719,7 @@ public class Cassandra {
                 org.apache.thrift.protocol.TProtocolUtil.skip(iprot, schemeField.type);
               }
               break;
-            case 4: // TE
+            case 3: // TE
               if (schemeField.type == org.apache.thrift.protocol.TType.STRUCT) {
                 struct.te = new TimedOutException();
                 struct.te.read(iprot);
@@ -7194,13 +8739,20 @@ public class Cassandra {
         struct.validate();
       }
 
-      public void write(org.apache.thrift.protocol.TProtocol oprot, get_result struct) throws org.apache.thrift.TException {
+      public void write(org.apache.thrift.protocol.TProtocol oprot, get_slice_result struct) throws org.apache.thrift.TException {
         struct.validate();
 
         oprot.writeStructBegin(STRUCT_DESC);
         if (struct.success != null) {
           oprot.writeFieldBegin(SUCCESS_FIELD_DESC);
-          struct.success.write(oprot);
+          {
+            oprot.writeListBegin(new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, struct.success.size()));
+            for (ColumnOrSuperColumn _iter193 : struct.success)
+            {
+              _iter193.write(oprot);
+            }
+            oprot.writeListEnd();
+          }
           oprot.writeFieldEnd();
         }
         if (struct.ire != null) {
@@ -7208,11 +8760,6 @@ public class Cassandra {
           struct.ire.write(oprot);
           oprot.writeFieldEnd();
         }
-        if (struct.nfe != null) {
-          oprot.writeFieldBegin(NFE_FIELD_DESC);
-          struct.nfe.write(oprot);
-          oprot.writeFieldEnd();
-        }
         if (struct.ue != null) {
           oprot.writeFieldBegin(UE_FIELD_DESC);
           struct.ue.write(oprot);
@@ -7229,16 +8776,16 @@ public class Cassandra {
 
     }
 
-    private static class get_resultTupleSchemeFactory implements SchemeFactory {
-      public get_resultTupleScheme getScheme() {
-        return new get_resultTupleScheme();
+    private static class get_slice_resultTupleSchemeFactory implements SchemeFactory {
+      public get_slice_resultTupleScheme getScheme() {
+        return new get_slice_resultTupleScheme();
       }
     }
 
-    private static class get_resultTupleScheme extends TupleScheme<get_result> {
+    private static class get_slice_resultTupleScheme extends TupleScheme<get_slice_result> {
 
       @Override
-      public void write(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
+      public void write(org.apache.thrift.protocol.TProtocol prot, get_slice_result struct) throws org.apache.thrift.TException {
         TTupleProtocol oprot = (TTupleProtocol) prot;
         BitSet optionals = new BitSet();
         if (struct.isSetSuccess()) {
@@ -7247,25 +8794,25 @@ public class Cassandra {
         if (struct.isSetIre()) {
           optionals.set(1);
         }
-        if (struct.isSetNfe()) {
-          optionals.set(2);
-        }
         if (struct.isSetUe()) {
-          optionals.set(3);
+          optionals.set(2);
         }
         if (struct.isSetTe()) {
-          optionals.set(4);
+          optionals.set(3);
         }
-        oprot.writeBitSet(optionals, 5);
+        oprot.writeBitSet(optionals, 4);
         if (struct.isSetSuccess()) {
-          struct.success.write(oprot);
+          {
+            oprot.writeI32(struct.success.size());
+            for (ColumnOrSuperColumn _iter194 : struct.success)
+            {
+              _iter194.write(oprot);
+            }
+          }
         }
         if (struct.isSetIre()) {
           struct.ire.write(oprot);
         }
-        if (struct.isSetNfe()) {
-          struct.nfe.write(oprot);
-        }
         if (struct.isSetUe()) {
           struct.ue.write(oprot);
         }
@@ -7275,12 +8822,21 @@ public class Cassandra {
       }
 
       @Override
-      public void read(org.apache.thrift.protocol.TProtocol prot, get_result struct) throws org.apache.thrift.TException {
+      public void read(org.apache.thrift.protocol.TProtocol prot, get_slice_result struct) throws org.apache.thrift.TException {
         TTupleProtocol iprot = (TTupleProtocol) prot;
-        BitSet incoming = iprot.readBitSet(5);
+        BitSet incoming = iprot.readBitSet(4);
         if (incoming.get(0)) {
-          struct.success = new ColumnOrSuperColumn();
-          struct.success.read(iprot);
+          {
+            org.apache.thrift.protocol.TList _list195 = new org.apache.thrift.protocol.TList(org.apache.thrift.protocol.TType.STRUCT, iprot.readI32());
+            struct.success = new ArrayList<ColumnOrSuperColumn>(_list195.size);
+            for (int _i196 = 0; _i196 < _list195.size; ++_i196)
+            {
+              ColumnOrSuperColumn _elem197; // required
+              _elem197 = new ColumnOrSuperColumn();
+              _elem197.read(iprot);
+              struct.success.add(_elem197);
+            }
+          }
           struct.setSuccessIsSet(true);
         }
         if (incoming.get(1)) {
@@ -7289,16 +8845,11 @@ public class Cassandra {
           struct.setIreIsSet(true);
         }
         if (incoming.get(2)) {
-          struct.nfe = new NotFoundException();
-          struct.nfe.read(iprot);
-          struct.setNfeIsSet(true);
-        }
-        if (incoming.get(3)) {
           struct.ue = new UnavailableException();
           struct.ue.read(iprot);
           struct.setUeIsSet(true);
         }
-        if (incoming.get(4)) {
+        if (incoming.get(3)) {
           struct.te = new TimedOutException();
           struct.te.read(iprot);
           struct.setTeIsSet(true);
@@ -7308,8 +8859,8 @@ public class Cassandra {
 
   }
 
-  public static class get_slice_args implements org.apache.thrift.TBase<get_slice_args, get_slice_args._Fields>, java.io.Serializable, Cloneable   {
-    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_slice_args");
+  public static class get_count_args implements org.apache.thrift.TBase<get_count_args, get_count_args._Fields>, java.io.Serializable, Cloneable   {
+    private static final org.apache.thrift.protocol.TStruct STRUCT_DESC = new org.apache.thrift.protocol.TStruct("get_count_args");
 
     private static final org.apache.thrift.protocol.TField KEY_FIELD_DESC = new org.apache.thrift.protocol.TField("key", org.apache.thrift.protocol.TType.STRING, (short)1);
     private static final org.apache.thrift.protocol.TField COLUMN_PARENT_FIELD_DESC = new org.apache.thrift.protocol.TField("column_parent", org.apache.thrift.protocol.TType.STRUCT, (short)2);
@@ -7318,8 +8869,8 @@ public class Cassandra {
 
     private static final Map<Class<? extends IScheme>, SchemeFactory> schemes = new HashMap<Class<? extends IScheme>, SchemeFactory>();
     static {
-      schemes.put(StandardScheme.class, new get_slice_argsStandardSchemeFactory());
-      schemes.put(TupleScheme.class, new get_slice_argsTupleSchemeFactory());
+      schemes.put(StandardScheme.class, new get_count_argsStandardSchemeFactory(

<TRUNCATED>