From 2c4ac98c9ffa8ea52da801830c7cdb745ddc28f0 Mon Sep 17 00:00:00 2001 From: Johan Oskarsson Date: Tue, 21 Dec 2010 22:17:09 +0000 Subject: [PATCH] Adds support for columns that act as incr/decr counters. Patch primarily by Kelvin Kakugawa with select parts from Chris Goffinet, Sylvain Lebresne, Rob Coli, Johan Oskarsson, Adam Samet, Jaakko Laine and more. Review by Jonathan Ellis and Sylvain Lebresne. CASSANDRA-1072. git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@1051679 13f79535-47bb-0310-9956-ffa450edef68 --- CHANGES.txt | 1 + conf/cassandra.yaml | 7 + interface/cassandra.genavro | 1 + interface/cassandra.thrift | 84 + .../thrift/AuthenticationRequest.java | 22 +- .../apache/cassandra/thrift/Cassandra.java | 7872 ++++++++++++++++- .../org/apache/cassandra/thrift/CfDef.java | 114 +- .../org/apache/cassandra/thrift/Counter.java | 433 + .../cassandra/thrift/CounterColumn.java | 448 + .../cassandra/thrift/CounterDeletion.java | 443 + .../cassandra/thrift/CounterMutation.java | 438 + .../cassandra/thrift/CounterSuperColumn.java | 487 + .../apache/cassandra/thrift/IndexClause.java | 18 +- .../org/apache/cassandra/thrift/KeySlice.java | 18 +- .../org/apache/cassandra/thrift/KsDef.java | 40 +- .../cassandra/thrift/SlicePredicate.java | 16 +- .../apache/cassandra/thrift/TokenRange.java | 16 +- .../cassandra/avro/CassandraServer.java | 2 +- .../apache/cassandra/concurrent/Stage.java | 4 +- .../cassandra/concurrent/StageManager.java | 2 + .../apache/cassandra/config/CFMetaData.java | 24 + .../org/apache/cassandra/config/Config.java | 1 + .../cassandra/config/DatabaseDescriptor.java | 11 + .../cassandra/config/RawColumnFamily.java | 1 + .../org/apache/cassandra/db/ColumnFamily.java | 18 +- .../cassandra/db/ColumnFamilyStore.java | 147 +- .../apache/cassandra/db/ColumnSerializer.java | 36 +- .../cassandra/db/CompactionManager.java | 7 +- .../apache/cassandra/db/CounterColumn.java | 287 + .../apache/cassandra/db/DeletedColumn.java | 8 + .../apache/cassandra/db/IColumnContainer.java | 5 + .../org/apache/cassandra/db/Memtable.java | 14 +- .../cassandra/db/ReplicateOnWriteTask.java | 129 + .../db/ReplicateOnWriteVerbHandler.java | 51 + .../org/apache/cassandra/db/RowMutation.java | 22 +- .../cassandra/db/RowMutationVerbHandler.java | 6 + .../org/apache/cassandra/db/SuperColumn.java | 5 + .../cassandra/db/context/CounterContext.java | 553 ++ .../apache/cassandra/db/context/IContext.java | 79 + .../db/marshal/AbstractCommutativeType.java | 50 + .../cassandra/db/marshal/AbstractType.java | 5 + .../db/marshal/CounterColumnType.java | 133 + .../apache/cassandra/dht/BootStrapper.java | 5 +- .../cassandra/io/sstable/SSTableWriter.java | 218 +- .../cassandra/service/AntiEntropyService.java | 5 +- .../service/ReadResponseResolver.java | 51 +- .../cassandra/service/StorageProxy.java | 47 + .../cassandra/service/StorageService.java | 10 +- .../cassandra/streaming/OperationType.java | 31 + .../cassandra/streaming/PendingFile.java | 11 +- .../apache/cassandra/streaming/StreamIn.java | 8 +- .../cassandra/streaming/StreamInSession.java | 2 +- .../apache/cassandra/streaming/StreamOut.java | 16 +- .../streaming/StreamRequestMessage.java | 10 +- .../streaming/StreamRequestVerbHandler.java | 2 +- .../cassandra/thrift/CassandraServer.java | 235 +- .../cassandra/thrift/ThriftValidation.java | 25 + .../apache/cassandra/utils/FBUtilities.java | 201 +- test/conf/cassandra.yaml | 12 + test/system/__init__.py | 2 + test/system/test_thrift_server.py | 249 + test/unit/org/apache/cassandra/Util.java | 21 + .../cassandra/db/CounterColumnTest.java | 346 + .../org/apache/cassandra/db/DefsTest.java | 2 + .../apache/cassandra/db/SuperColumnTest.java | 71 +- .../db/context/CounterContextTest.java | 536 ++ .../cassandra/io/sstable/SSTableUtils.java | 14 +- .../SSTableWriterAESCommutativeTest.java | 186 + .../io/sstable/SSTableWriterTest.java | 3 +- .../AntiEntropyServiceCounterTest.java | 10 + .../AntiEntropyServiceStandardTest.java | 10 + .../AntiEntropyServiceTestAbstract.java | 273 + .../cassandra/streaming/BootstrapTest.java | 2 +- .../streaming/StreamingTransferTest.java | 4 +- .../thrift/ThriftValidationTest.java | 20 + .../cassandra/utils/FBUtilitiesTest.java | 73 + 76 files changed, 14382 insertions(+), 387 deletions(-) create mode 100644 interface/thrift/gen-java/org/apache/cassandra/thrift/Counter.java create mode 100644 interface/thrift/gen-java/org/apache/cassandra/thrift/CounterColumn.java create mode 100644 interface/thrift/gen-java/org/apache/cassandra/thrift/CounterDeletion.java create mode 100644 interface/thrift/gen-java/org/apache/cassandra/thrift/CounterMutation.java create mode 100644 interface/thrift/gen-java/org/apache/cassandra/thrift/CounterSuperColumn.java create mode 100644 src/java/org/apache/cassandra/db/CounterColumn.java create mode 100644 src/java/org/apache/cassandra/db/ReplicateOnWriteTask.java create mode 100644 src/java/org/apache/cassandra/db/ReplicateOnWriteVerbHandler.java create mode 100644 src/java/org/apache/cassandra/db/context/CounterContext.java create mode 100644 src/java/org/apache/cassandra/db/context/IContext.java create mode 100644 src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java create mode 100644 src/java/org/apache/cassandra/db/marshal/CounterColumnType.java create mode 100644 src/java/org/apache/cassandra/streaming/OperationType.java create mode 100644 test/unit/org/apache/cassandra/db/CounterColumnTest.java create mode 100644 test/unit/org/apache/cassandra/db/context/CounterContextTest.java create mode 100644 test/unit/org/apache/cassandra/io/sstable/SSTableWriterAESCommutativeTest.java create mode 100644 test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java create mode 100644 test/unit/org/apache/cassandra/service/AntiEntropyServiceStandardTest.java create mode 100644 test/unit/org/apache/cassandra/service/AntiEntropyServiceTestAbstract.java create mode 100644 test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java diff --git a/CHANGES.txt b/CHANGES.txt index 52b0b5ece8..3b0827fd12 100644 --- a/CHANGES.txt +++ b/CHANGES.txt @@ -1,5 +1,6 @@ 0.8-dev * avoid double RowMutation serialization on write path (CASSANDRA-1800) + * adds support for columns that act as incr/decr counters (CASSANDRA-1072) 0.7-dev diff --git a/conf/cassandra.yaml b/conf/cassandra.yaml index f63bc5f9ba..40a047f630 100644 --- a/conf/cassandra.yaml +++ b/conf/cassandra.yaml @@ -459,3 +459,10 @@ keyspaces: validator_class: LongType index_name: birthdate_idx index_type: KEYS + + - name: Counter1 + default_validation_class: CounterColumnType + + - name: SuperCounter1 + column_type: Super + default_validation_class: CounterColumnType diff --git a/interface/cassandra.genavro b/interface/cassandra.genavro index 0243ec7384..9620441623 100644 --- a/interface/cassandra.genavro +++ b/interface/cassandra.genavro @@ -146,6 +146,7 @@ protocol Cassandra { union { double, null } row_cache_size; union { double, null } key_cache_size; union { double, null } read_repair_chance; + union { boolean, null } replicate_on_write; union { int, null } gc_grace_seconds; union { null, string } default_validation_class = null; union { null, int } min_compaction_threshold = null; diff --git a/interface/cassandra.thrift b/interface/cassandra.thrift index efeb0da4b8..3197c5cb4d 100644 --- a/interface/cassandra.thrift +++ b/interface/cassandra.thrift @@ -189,6 +189,21 @@ struct ColumnPath { 5: optional binary column, } +struct CounterColumn { + 1: required binary name, + 2: required i64 value +} + +struct CounterSuperColumn { + 1: required binary name, + 2: required list columns +} + +struct Counter { + 1: optional CounterColumn column, + 2: optional CounterSuperColumn super_column +} + /** A slice range is a structure that stores basic range, ordering and limit information for a query that will return multiple columns. It could be thought of as Cassandra's version of LIMIT and ORDER BY @@ -298,6 +313,21 @@ struct Mutation { 2: optional Deletion deletion, } +struct CounterDeletion { + 1: optional binary super_column, + 2: optional SlicePredicate predicate, +} + +/** + A CounterMutation is either an insert, represented by filling counter, or a deletion, represented by filling the deletion attribute. + @param counter. An insert to a counter column or supercolumn + @param deletion. A deletion of a counter column or supercolumn +*/ +struct CounterMutation { + 1: optional Counter counter, + 2: optional CounterDeletion deletion, +} + struct TokenRange { 1: required string start_token, 2: required string end_token, @@ -346,6 +376,7 @@ struct CfDef { 21: optional i32 memtable_flush_after_mins, 22: optional i32 memtable_throughput_in_mb, 23: optional double memtable_operations_in_millions, + 24: optional bool replicate_on_write=0, } /* describes a keyspace. */ @@ -470,6 +501,59 @@ service Cassandra { */ void truncate(1:required string cfname) throws (1: InvalidRequestException ire, 2: UnavailableException ue), + + + # counter methods + + /** + * Increment or decrement a counter. + */ + void add(1:required binary key, + 2:required ColumnParent column_parent, + 3:required CounterColumn column, + 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), + /** + * Batch increment or decrement a counter. + */ + void batch_add(1:required map>> update_map, + 2:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), + + /** + * Return the counter at the specified column path. + */ + Counter get_counter(1:required binary key, + 2:required ColumnPath path, + 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:NotFoundException nfe, 3:UnavailableException ue, 4:TimedOutException te), + + /** + * Get a list of counters from the specified columns. + */ + list get_counter_slice(1:required binary key, + 2:required ColumnParent column_parent, + 3:required SlicePredicate predicate, + 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), + + /** + * Get counter slices from multiple keys. + */ + map> multiget_counter_slice(1:required list keys, + 2:required ColumnParent column_parent, + 3:required SlicePredicate predicate, + 4:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), + + /** + * Remove a counter at the specified location. + */ + void remove_counter(1:required binary key, + 2:required ColumnPath path, + 3:required ConsistencyLevel consistency_level=ConsistencyLevel.ONE) + throws (1:InvalidRequestException ire, 2:UnavailableException ue, 3:TimedOutException te), + // Meta-APIs -- APIs to get information about the node or cluster, // rather than user data. The nodeprobe program provides usage examples. diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/AuthenticationRequest.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/AuthenticationRequest.java index cba008ae35..43d20e57db 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/AuthenticationRequest.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/AuthenticationRequest.java @@ -314,15 +314,15 @@ public class AuthenticationRequest implements TBase(2*_map20.size); - for (int _i21 = 0; _i21 < _map20.size; ++_i21) + TMap _map24 = iprot.readMapBegin(); + this.credentials = new HashMap(2*_map24.size); + for (int _i25 = 0; _i25 < _map24.size; ++_i25) { - String _key22; - String _val23; - _key22 = iprot.readString(); - _val23 = iprot.readString(); - this.credentials.put(_key22, _val23); + String _key26; + String _val27; + _key26 = iprot.readString(); + _val27 = iprot.readString(); + this.credentials.put(_key26, _val27); } iprot.readMapEnd(); } @@ -349,10 +349,10 @@ public class AuthenticationRequest implements TBase _iter24 : this.credentials.entrySet()) + for (Map.Entry _iter28 : this.credentials.entrySet()) { - oprot.writeString(_iter24.getKey()); - oprot.writeString(_iter24.getValue()); + oprot.writeString(_iter28.getKey()); + oprot.writeString(_iter28.getValue()); } oprot.writeMapEnd(); } 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 bf41606abc..c296696218 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/Cassandra.java @@ -173,6 +173,62 @@ public class Cassandra { */ public void truncate(String cfname) throws InvalidRequestException, UnavailableException, TException; + /** + * Increment or decrement a counter. + * + * @param key + * @param column_parent + * @param column + * @param consistency_level + */ + public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; + + /** + * Batch increment or decrement a counter. + * + * @param update_map + * @param consistency_level + */ + public void batch_add(Map>> update_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; + + /** + * Return the counter at the specified column path. + * + * @param key + * @param path + * @param consistency_level + */ + public Counter get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException; + + /** + * Get a list of counters from the specified columns. + * + * @param key + * @param column_parent + * @param predicate + * @param consistency_level + */ + public List get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; + + /** + * Get counter slices from multiple keys. + * + * @param keys + * @param column_parent + * @param predicate + * @param consistency_level + */ + public Map> multiget_counter_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; + + /** + * Remove a counter at the specified location. + * + * @param key + * @param path + * @param consistency_level + */ + public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException; + /** * for each schema version present in the cluster, returns a list of nodes at that version. * hosts that do not respond will be under the key DatabaseDescriptor.INITIAL_VERSION. @@ -312,6 +368,18 @@ public class Cassandra { public void truncate(String cfname, AsyncMethodCallback resultHandler) throws TException; + public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + + public void batch_add(Map>> update_map, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + + public void get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + + public void get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + + public void multiget_counter_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + + public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException; + public void describe_schema_versions(AsyncMethodCallback resultHandler) throws TException; public void describe_keyspaces(AsyncMethodCallback resultHandler) throws TException; @@ -966,6 +1034,284 @@ public class Cassandra { return; } + public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + send_add(key, column_parent, column, consistency_level); + recv_add(); + } + + public void send_add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("add", TMessageType.CALL, ++seqid_)); + add_args args = new add_args(); + args.setKey(key); + args.setColumn_parent(column_parent); + args.setColumn(column); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public void recv_add() throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "add failed: out of sequence response"); + } + add_result result = new add_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + if (result.ire != null) { + throw result.ire; + } + if (result.ue != null) { + throw result.ue; + } + if (result.te != null) { + throw result.te; + } + return; + } + + public void batch_add(Map>> update_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + send_batch_add(update_map, consistency_level); + recv_batch_add(); + } + + public void send_batch_add(Map>> update_map, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("batch_add", TMessageType.CALL, ++seqid_)); + batch_add_args args = new batch_add_args(); + args.setUpdate_map(update_map); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public void recv_batch_add() throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "batch_add failed: out of sequence response"); + } + batch_add_result result = new batch_add_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + if (result.ire != null) { + throw result.ire; + } + if (result.ue != null) { + throw result.ue; + } + if (result.te != null) { + throw result.te; + } + return; + } + + public Counter get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException + { + send_get_counter(key, path, consistency_level); + return recv_get_counter(); + } + + public void send_get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("get_counter", TMessageType.CALL, ++seqid_)); + get_counter_args args = new get_counter_args(); + args.setKey(key); + args.setPath(path); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public Counter recv_get_counter() throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "get_counter failed: out of sequence response"); + } + get_counter_result result = new get_counter_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + if (result.isSetSuccess()) { + return result.success; + } + if (result.ire != null) { + throw result.ire; + } + if (result.nfe != null) { + throw result.nfe; + } + if (result.ue != null) { + throw result.ue; + } + if (result.te != null) { + throw result.te; + } + throw new TApplicationException(TApplicationException.MISSING_RESULT, "get_counter failed: unknown result"); + } + + public List get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + send_get_counter_slice(key, column_parent, predicate, consistency_level); + return recv_get_counter_slice(); + } + + public void send_get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("get_counter_slice", TMessageType.CALL, ++seqid_)); + get_counter_slice_args args = new get_counter_slice_args(); + args.setKey(key); + args.setColumn_parent(column_parent); + args.setPredicate(predicate); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public List recv_get_counter_slice() throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "get_counter_slice failed: out of sequence response"); + } + get_counter_slice_result result = new get_counter_slice_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + 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 TApplicationException(TApplicationException.MISSING_RESULT, "get_counter_slice failed: unknown result"); + } + + public Map> multiget_counter_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + send_multiget_counter_slice(keys, column_parent, predicate, consistency_level); + return recv_multiget_counter_slice(); + } + + public void send_multiget_counter_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("multiget_counter_slice", TMessageType.CALL, ++seqid_)); + multiget_counter_slice_args args = new multiget_counter_slice_args(); + args.setKeys(keys); + args.setColumn_parent(column_parent); + args.setPredicate(predicate); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public Map> recv_multiget_counter_slice() throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "multiget_counter_slice failed: out of sequence response"); + } + multiget_counter_slice_result result = new multiget_counter_slice_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + 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 TApplicationException(TApplicationException.MISSING_RESULT, "multiget_counter_slice failed: unknown result"); + } + + public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + send_remove_counter(key, path, consistency_level); + recv_remove_counter(); + } + + public void send_remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) throws TException + { + oprot_.writeMessageBegin(new TMessage("remove_counter", TMessageType.CALL, ++seqid_)); + remove_counter_args args = new remove_counter_args(); + args.setKey(key); + args.setPath(path); + args.setConsistency_level(consistency_level); + args.write(oprot_); + oprot_.writeMessageEnd(); + oprot_.getTransport().flush(); + } + + public void recv_remove_counter() throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + TMessage msg = iprot_.readMessageBegin(); + if (msg.type == TMessageType.EXCEPTION) { + TApplicationException x = TApplicationException.read(iprot_); + iprot_.readMessageEnd(); + throw x; + } + if (msg.seqid != seqid_) { + throw new TApplicationException(TApplicationException.BAD_SEQUENCE_ID, "remove_counter failed: out of sequence response"); + } + remove_counter_result result = new remove_counter_result(); + result.read(iprot_); + iprot_.readMessageEnd(); + if (result.ire != null) { + throw result.ire; + } + if (result.ue != null) { + throw result.ue; + } + if (result.te != null) { + throw result.te; + } + return; + } + public Map> describe_schema_versions() throws InvalidRequestException, TException { send_describe_schema_versions(); @@ -2038,6 +2384,234 @@ public class Cassandra { } } + public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + add_call method_call = new add_call(key, column_parent, column, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class add_call extends TAsyncMethodCall { + private ByteBuffer key; + private ColumnParent column_parent; + private CounterColumn column; + private ConsistencyLevel consistency_level; + public add_call(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.key = key; + this.column_parent = column_parent; + this.column = column; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("add", TMessageType.CALL, 0)); + add_args args = new add_args(); + args.setKey(key); + args.setColumn_parent(column_parent); + args.setColumn(column); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + (new Client(prot)).recv_add(); + } + } + + public void batch_add(Map>> update_map, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + batch_add_call method_call = new batch_add_call(update_map, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class batch_add_call extends TAsyncMethodCall { + private Map>> update_map; + private ConsistencyLevel consistency_level; + public batch_add_call(Map>> update_map, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.update_map = update_map; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("batch_add", TMessageType.CALL, 0)); + batch_add_args args = new batch_add_args(); + args.setUpdate_map(update_map); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + (new Client(prot)).recv_batch_add(); + } + } + + public void get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + get_counter_call method_call = new get_counter_call(key, path, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class get_counter_call extends TAsyncMethodCall { + private ByteBuffer key; + private ColumnPath path; + private ConsistencyLevel consistency_level; + public get_counter_call(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.key = key; + this.path = path; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("get_counter", TMessageType.CALL, 0)); + get_counter_args args = new get_counter_args(); + args.setKey(key); + args.setPath(path); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public Counter getResult() throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + return (new Client(prot)).recv_get_counter(); + } + } + + public void get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + get_counter_slice_call method_call = new get_counter_slice_call(key, column_parent, predicate, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class get_counter_slice_call extends TAsyncMethodCall { + private ByteBuffer key; + private ColumnParent column_parent; + private SlicePredicate predicate; + private ConsistencyLevel consistency_level; + public get_counter_slice_call(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.key = key; + this.column_parent = column_parent; + this.predicate = predicate; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("get_counter_slice", TMessageType.CALL, 0)); + get_counter_slice_args args = new get_counter_slice_args(); + args.setKey(key); + args.setColumn_parent(column_parent); + args.setPredicate(predicate); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public List getResult() throws InvalidRequestException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + return (new Client(prot)).recv_get_counter_slice(); + } + } + + public void multiget_counter_slice(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + multiget_counter_slice_call method_call = new multiget_counter_slice_call(keys, column_parent, predicate, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class multiget_counter_slice_call extends TAsyncMethodCall { + private List keys; + private ColumnParent column_parent; + private SlicePredicate predicate; + private ConsistencyLevel consistency_level; + public multiget_counter_slice_call(List keys, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.keys = keys; + this.column_parent = column_parent; + this.predicate = predicate; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("multiget_counter_slice", TMessageType.CALL, 0)); + multiget_counter_slice_args args = new multiget_counter_slice_args(); + args.setKeys(keys); + args.setColumn_parent(column_parent); + args.setPredicate(predicate); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public Map> getResult() throws InvalidRequestException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + return (new Client(prot)).recv_multiget_counter_slice(); + } + } + + public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler) throws TException { + checkReady(); + remove_counter_call method_call = new remove_counter_call(key, path, consistency_level, resultHandler, this, protocolFactory, transport); + manager.call(method_call); + } + + public static class remove_counter_call extends TAsyncMethodCall { + private ByteBuffer key; + private ColumnPath path; + private ConsistencyLevel consistency_level; + public remove_counter_call(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level, AsyncMethodCallback resultHandler, TAsyncClient client, TProtocolFactory protocolFactory, TNonblockingTransport transport) throws TException { + super(client, protocolFactory, transport, resultHandler, false); + this.key = key; + this.path = path; + this.consistency_level = consistency_level; + } + + public void write_args(TProtocol prot) throws TException { + prot.writeMessageBegin(new TMessage("remove_counter", TMessageType.CALL, 0)); + remove_counter_args args = new remove_counter_args(); + args.setKey(key); + args.setPath(path); + args.setConsistency_level(consistency_level); + args.write(prot); + prot.writeMessageEnd(); + } + + public void getResult() throws InvalidRequestException, UnavailableException, TimedOutException, TException { + if (getState() != State.RESPONSE_READ) { + throw new IllegalStateException("Method call not finished!"); + } + TMemoryInputTransport memoryTransport = new TMemoryInputTransport(getFrameBuffer().array()); + TProtocol prot = client.getProtocolFactory().getProtocol(memoryTransport); + (new Client(prot)).recv_remove_counter(); + } + } + public void describe_schema_versions(AsyncMethodCallback resultHandler) throws TException { checkReady(); describe_schema_versions_call method_call = new describe_schema_versions_call(resultHandler, this, protocolFactory, transport); @@ -2514,6 +3088,12 @@ public class Cassandra { processMap_.put("remove", new remove()); processMap_.put("batch_mutate", new batch_mutate()); processMap_.put("truncate", new truncate()); + processMap_.put("add", new add()); + processMap_.put("batch_add", new batch_add()); + processMap_.put("get_counter", new get_counter()); + processMap_.put("get_counter_slice", new get_counter_slice()); + processMap_.put("multiget_counter_slice", new multiget_counter_slice()); + processMap_.put("remove_counter", new remove_counter()); processMap_.put("describe_schema_versions", new describe_schema_versions()); processMap_.put("describe_keyspaces", new describe_keyspaces()); processMap_.put("describe_cluster_name", new describe_cluster_name()); @@ -3097,6 +3677,260 @@ public class Cassandra { } + private class add implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + add_args args = new add_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("add", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + add_result result = new add_result(); + try { + iface_.add(args.key, args.column_parent, args.column, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing add", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing add"); + oprot.writeMessageBegin(new TMessage("add", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("add", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + + private class batch_add implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + batch_add_args args = new batch_add_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("batch_add", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + batch_add_result result = new batch_add_result(); + try { + iface_.batch_add(args.update_map, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing batch_add", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing batch_add"); + oprot.writeMessageBegin(new TMessage("batch_add", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("batch_add", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + + private class get_counter implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + get_counter_args args = new get_counter_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("get_counter", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + get_counter_result result = new get_counter_result(); + try { + result.success = iface_.get_counter(args.key, args.path, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (NotFoundException nfe) { + result.nfe = nfe; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing get_counter", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing get_counter"); + oprot.writeMessageBegin(new TMessage("get_counter", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("get_counter", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + + private class get_counter_slice implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + get_counter_slice_args args = new get_counter_slice_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("get_counter_slice", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + get_counter_slice_result result = new get_counter_slice_result(); + try { + result.success = iface_.get_counter_slice(args.key, args.column_parent, args.predicate, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing get_counter_slice", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing get_counter_slice"); + oprot.writeMessageBegin(new TMessage("get_counter_slice", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("get_counter_slice", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + + private class multiget_counter_slice implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + multiget_counter_slice_args args = new multiget_counter_slice_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("multiget_counter_slice", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + multiget_counter_slice_result result = new multiget_counter_slice_result(); + try { + result.success = iface_.multiget_counter_slice(args.keys, args.column_parent, args.predicate, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing multiget_counter_slice", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing multiget_counter_slice"); + oprot.writeMessageBegin(new TMessage("multiget_counter_slice", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("multiget_counter_slice", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + + private class remove_counter implements ProcessFunction { + public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException + { + remove_counter_args args = new remove_counter_args(); + try { + args.read(iprot); + } catch (TProtocolException e) { + iprot.readMessageEnd(); + TApplicationException x = new TApplicationException(TApplicationException.PROTOCOL_ERROR, e.getMessage()); + oprot.writeMessageBegin(new TMessage("remove_counter", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + iprot.readMessageEnd(); + remove_counter_result result = new remove_counter_result(); + try { + iface_.remove_counter(args.key, args.path, args.consistency_level); + } catch (InvalidRequestException ire) { + result.ire = ire; + } catch (UnavailableException ue) { + result.ue = ue; + } catch (TimedOutException te) { + result.te = te; + } catch (Throwable th) { + LOGGER.error("Internal error processing remove_counter", th); + TApplicationException x = new TApplicationException(TApplicationException.INTERNAL_ERROR, "Internal error processing remove_counter"); + oprot.writeMessageBegin(new TMessage("remove_counter", TMessageType.EXCEPTION, seqid)); + x.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + return; + } + oprot.writeMessageBegin(new TMessage("remove_counter", TMessageType.REPLY, seqid)); + result.write(oprot); + oprot.writeMessageEnd(); + oprot.getTransport().flush(); + } + + } + private class describe_schema_versions implements ProcessFunction { public void process(int seqid, TProtocol iprot, TProtocol oprot) throws TException { @@ -7138,14 +7972,14 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list38 = iprot.readListBegin(); - this.success = new ArrayList(_list38.size); - for (int _i39 = 0; _i39 < _list38.size; ++_i39) + TList _list42 = iprot.readListBegin(); + this.success = new ArrayList(_list42.size); + for (int _i43 = 0; _i43 < _list42.size; ++_i43) { - ColumnOrSuperColumn _elem40; - _elem40 = new ColumnOrSuperColumn(); - _elem40.read(iprot); - this.success.add(_elem40); + ColumnOrSuperColumn _elem44; + _elem44 = new ColumnOrSuperColumn(); + _elem44.read(iprot); + this.success.add(_elem44); } iprot.readListEnd(); } @@ -7195,9 +8029,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); - for (ColumnOrSuperColumn _iter41 : this.success) + for (ColumnOrSuperColumn _iter45 : this.success) { - _iter41.write(oprot); + _iter45.write(oprot); } oprot.writeListEnd(); } @@ -8949,13 +9783,13 @@ public class Cassandra { case 1: // KEYS if (field.type == TType.LIST) { { - TList _list42 = iprot.readListBegin(); - this.keys = new ArrayList(_list42.size); - for (int _i43 = 0; _i43 < _list42.size; ++_i43) + TList _list46 = iprot.readListBegin(); + this.keys = new ArrayList(_list46.size); + for (int _i47 = 0; _i47 < _list46.size; ++_i47) { - ByteBuffer _elem44; - _elem44 = iprot.readBinary(); - this.keys.add(_elem44); + ByteBuffer _elem48; + _elem48 = iprot.readBinary(); + this.keys.add(_elem48); } iprot.readListEnd(); } @@ -9005,9 +9839,9 @@ public class Cassandra { oprot.writeFieldBegin(KEYS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRING, this.keys.size())); - for (ByteBuffer _iter45 : this.keys) + for (ByteBuffer _iter49 : this.keys) { - oprot.writeBinary(_iter45); + oprot.writeBinary(_iter49); } oprot.writeListEnd(); } @@ -9580,26 +10414,26 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.MAP) { { - TMap _map46 = iprot.readMapBegin(); - this.success = new HashMap>(2*_map46.size); - for (int _i47 = 0; _i47 < _map46.size; ++_i47) + TMap _map50 = iprot.readMapBegin(); + this.success = new HashMap>(2*_map50.size); + for (int _i51 = 0; _i51 < _map50.size; ++_i51) { - ByteBuffer _key48; - List _val49; - _key48 = iprot.readBinary(); + ByteBuffer _key52; + List _val53; + _key52 = iprot.readBinary(); { - TList _list50 = iprot.readListBegin(); - _val49 = new ArrayList(_list50.size); - for (int _i51 = 0; _i51 < _list50.size; ++_i51) + TList _list54 = iprot.readListBegin(); + _val53 = new ArrayList(_list54.size); + for (int _i55 = 0; _i55 < _list54.size; ++_i55) { - ColumnOrSuperColumn _elem52; - _elem52 = new ColumnOrSuperColumn(); - _elem52.read(iprot); - _val49.add(_elem52); + ColumnOrSuperColumn _elem56; + _elem56 = new ColumnOrSuperColumn(); + _elem56.read(iprot); + _val53.add(_elem56); } iprot.readListEnd(); } - this.success.put(_key48, _val49); + this.success.put(_key52, _val53); } iprot.readMapEnd(); } @@ -9649,14 +10483,14 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, this.success.size())); - for (Map.Entry> _iter53 : this.success.entrySet()) + for (Map.Entry> _iter57 : this.success.entrySet()) { - oprot.writeBinary(_iter53.getKey()); + oprot.writeBinary(_iter57.getKey()); { - oprot.writeListBegin(new TList(TType.STRUCT, _iter53.getValue().size())); - for (ColumnOrSuperColumn _iter54 : _iter53.getValue()) + oprot.writeListBegin(new TList(TType.STRUCT, _iter57.getValue().size())); + for (ColumnOrSuperColumn _iter58 : _iter57.getValue()) { - _iter54.write(oprot); + _iter58.write(oprot); } oprot.writeListEnd(); } @@ -10228,13 +11062,13 @@ public class Cassandra { case 1: // KEYS if (field.type == TType.LIST) { { - TList _list55 = iprot.readListBegin(); - this.keys = new ArrayList(_list55.size); - for (int _i56 = 0; _i56 < _list55.size; ++_i56) + TList _list59 = iprot.readListBegin(); + this.keys = new ArrayList(_list59.size); + for (int _i60 = 0; _i60 < _list59.size; ++_i60) { - ByteBuffer _elem57; - _elem57 = iprot.readBinary(); - this.keys.add(_elem57); + ByteBuffer _elem61; + _elem61 = iprot.readBinary(); + this.keys.add(_elem61); } iprot.readListEnd(); } @@ -10284,9 +11118,9 @@ public class Cassandra { oprot.writeFieldBegin(KEYS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRING, this.keys.size())); - for (ByteBuffer _iter58 : this.keys) + for (ByteBuffer _iter62 : this.keys) { - oprot.writeBinary(_iter58); + oprot.writeBinary(_iter62); } oprot.writeListEnd(); } @@ -10855,15 +11689,15 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.MAP) { { - TMap _map59 = iprot.readMapBegin(); - this.success = new HashMap(2*_map59.size); - for (int _i60 = 0; _i60 < _map59.size; ++_i60) + TMap _map63 = iprot.readMapBegin(); + this.success = new HashMap(2*_map63.size); + for (int _i64 = 0; _i64 < _map63.size; ++_i64) { - ByteBuffer _key61; - int _val62; - _key61 = iprot.readBinary(); - _val62 = iprot.readI32(); - this.success.put(_key61, _val62); + ByteBuffer _key65; + int _val66; + _key65 = iprot.readBinary(); + _val66 = iprot.readI32(); + this.success.put(_key65, _val66); } iprot.readMapEnd(); } @@ -10913,10 +11747,10 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeMapBegin(new TMap(TType.STRING, TType.I32, this.success.size())); - for (Map.Entry _iter63 : this.success.entrySet()) + for (Map.Entry _iter67 : this.success.entrySet()) { - oprot.writeBinary(_iter63.getKey()); - oprot.writeI32(_iter63.getValue()); + oprot.writeBinary(_iter67.getKey()); + oprot.writeI32(_iter67.getValue()); } oprot.writeMapEnd(); } @@ -12068,14 +12902,14 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list64 = iprot.readListBegin(); - this.success = new ArrayList(_list64.size); - for (int _i65 = 0; _i65 < _list64.size; ++_i65) + TList _list68 = iprot.readListBegin(); + this.success = new ArrayList(_list68.size); + for (int _i69 = 0; _i69 < _list68.size; ++_i69) { - KeySlice _elem66; - _elem66 = new KeySlice(); - _elem66.read(iprot); - this.success.add(_elem66); + KeySlice _elem70; + _elem70 = new KeySlice(); + _elem70.read(iprot); + this.success.add(_elem70); } iprot.readListEnd(); } @@ -12125,9 +12959,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); - for (KeySlice _iter67 : this.success) + for (KeySlice _iter71 : this.success) { - _iter67.write(oprot); + _iter71.write(oprot); } oprot.writeListEnd(); } @@ -13279,14 +14113,14 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list68 = iprot.readListBegin(); - this.success = new ArrayList(_list68.size); - for (int _i69 = 0; _i69 < _list68.size; ++_i69) + TList _list72 = iprot.readListBegin(); + this.success = new ArrayList(_list72.size); + for (int _i73 = 0; _i73 < _list72.size; ++_i73) { - KeySlice _elem70; - _elem70 = new KeySlice(); - _elem70.read(iprot); - this.success.add(_elem70); + KeySlice _elem74; + _elem74 = new KeySlice(); + _elem74.read(iprot); + this.success.add(_elem74); } iprot.readListEnd(); } @@ -13336,9 +14170,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); - for (KeySlice _iter71 : this.success) + for (KeySlice _iter75 : this.success) { - _iter71.write(oprot); + _iter75.write(oprot); } oprot.writeListEnd(); } @@ -15955,38 +16789,38 @@ public class Cassandra { case 1: // MUTATION_MAP if (field.type == TType.MAP) { { - TMap _map72 = iprot.readMapBegin(); - this.mutation_map = new HashMap>>(2*_map72.size); - for (int _i73 = 0; _i73 < _map72.size; ++_i73) + TMap _map76 = iprot.readMapBegin(); + this.mutation_map = new HashMap>>(2*_map76.size); + for (int _i77 = 0; _i77 < _map76.size; ++_i77) { - ByteBuffer _key74; - Map> _val75; - _key74 = iprot.readBinary(); + ByteBuffer _key78; + Map> _val79; + _key78 = iprot.readBinary(); { - TMap _map76 = iprot.readMapBegin(); - _val75 = new HashMap>(2*_map76.size); - for (int _i77 = 0; _i77 < _map76.size; ++_i77) + TMap _map80 = iprot.readMapBegin(); + _val79 = new HashMap>(2*_map80.size); + for (int _i81 = 0; _i81 < _map80.size; ++_i81) { - String _key78; - List _val79; - _key78 = iprot.readString(); + String _key82; + List _val83; + _key82 = iprot.readString(); { - TList _list80 = iprot.readListBegin(); - _val79 = new ArrayList(_list80.size); - for (int _i81 = 0; _i81 < _list80.size; ++_i81) + TList _list84 = iprot.readListBegin(); + _val83 = new ArrayList(_list84.size); + for (int _i85 = 0; _i85 < _list84.size; ++_i85) { - Mutation _elem82; - _elem82 = new Mutation(); - _elem82.read(iprot); - _val79.add(_elem82); + Mutation _elem86; + _elem86 = new Mutation(); + _elem86.read(iprot); + _val83.add(_elem86); } iprot.readListEnd(); } - _val75.put(_key78, _val79); + _val79.put(_key82, _val83); } iprot.readMapEnd(); } - this.mutation_map.put(_key74, _val75); + this.mutation_map.put(_key78, _val79); } iprot.readMapEnd(); } @@ -16020,19 +16854,19 @@ public class Cassandra { oprot.writeFieldBegin(MUTATION_MAP_FIELD_DESC); { oprot.writeMapBegin(new TMap(TType.STRING, TType.MAP, this.mutation_map.size())); - for (Map.Entry>> _iter83 : this.mutation_map.entrySet()) + for (Map.Entry>> _iter87 : this.mutation_map.entrySet()) { - oprot.writeBinary(_iter83.getKey()); + oprot.writeBinary(_iter87.getKey()); { - oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, _iter83.getValue().size())); - for (Map.Entry> _iter84 : _iter83.getValue().entrySet()) + oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, _iter87.getValue().size())); + for (Map.Entry> _iter88 : _iter87.getValue().entrySet()) { - oprot.writeString(_iter84.getKey()); + oprot.writeString(_iter88.getKey()); { - oprot.writeListBegin(new TList(TType.STRUCT, _iter84.getValue().size())); - for (Mutation _iter85 : _iter84.getValue()) + oprot.writeListBegin(new TList(TType.STRUCT, _iter88.getValue().size())); + for (Mutation _iter89 : _iter88.getValue()) { - _iter85.write(oprot); + _iter89.write(oprot); } oprot.writeListEnd(); } @@ -17238,6 +18072,6752 @@ public class Cassandra { } + public static class add_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("add_args"); + + private static final TField KEY_FIELD_DESC = new TField("key", TType.STRING, (short)1); + private static final TField COLUMN_PARENT_FIELD_DESC = new TField("column_parent", TType.STRUCT, (short)2); + private static final TField COLUMN_FIELD_DESC = new TField("column", TType.STRUCT, (short)3); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)4); + + public ByteBuffer key; + public ColumnParent column_parent; + public CounterColumn column; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + KEY((short)1, "key"), + COLUMN_PARENT((short)2, "column_parent"), + COLUMN((short)3, "column"), + /** + * + * @see ConsistencyLevel + */ + CONSISTENCY_LEVEL((short)4, "consistency_level"); + + private static final Map byName = new HashMap(); + + 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: // COLUMN + return COLUMN; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new FieldMetaData("key", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.COLUMN_PARENT, new FieldMetaData("column_parent", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, ColumnParent.class))); + tmpMap.put(_Fields.COLUMN, new FieldMetaData("column", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, CounterColumn.class))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(add_args.class, metaDataMap); + } + + public add_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public add_args( + ByteBuffer key, + ColumnParent column_parent, + CounterColumn column, + ConsistencyLevel consistency_level) + { + this(); + this.key = key; + this.column_parent = column_parent; + this.column = column; + this.consistency_level = consistency_level; + } + + /** + * Performs a deep copy on other. + */ + public add_args(add_args other) { + if (other.isSetKey()) { + this.key = TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetColumn_parent()) { + this.column_parent = new ColumnParent(other.column_parent); + } + if (other.isSetColumn()) { + this.column = new CounterColumn(other.column); + } + if (other.isSetConsistency_level()) { + this.consistency_level = other.consistency_level; + } + } + + public add_args deepCopy() { + return new add_args(this); + } + + @Override + public void clear() { + this.key = null; + this.column_parent = null; + this.column = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public byte[] getKey() { + setKey(TBaseHelper.rightSize(key)); + return key.array(); + } + + public ByteBuffer BufferForKey() { + return key; + } + + public add_args setKey(byte[] key) { + setKey(ByteBuffer.wrap(key)); + return this; + } + + public add_args setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been asigned 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 add_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 asigned 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 CounterColumn getColumn() { + return this.column; + } + + public add_args setColumn(CounterColumn column) { + this.column = column; + return this; + } + + public void unsetColumn() { + this.column = null; + } + + /** Returns true if field column is set (has been asigned a value) and false otherwise */ + public boolean isSetColumn() { + return this.column != null; + } + + public void setColumnIsSet(boolean value) { + if (!value) { + this.column = null; + } + } + + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel getConsistency_level() { + return this.consistency_level; + } + + /** + * + * @see ConsistencyLevel + */ + public add_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 asigned 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 COLUMN: + if (value == null) { + unsetColumn(); + } else { + setColumn((CounterColumn)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 COLUMN: + return getColumn(); + + case CONSISTENCY_LEVEL: + return getConsistency_level(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned 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 COLUMN: + return isSetColumn(); + case CONSISTENCY_LEVEL: + return isSetConsistency_level(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof add_args) + return this.equals((add_args)that); + return false; + } + + public boolean equals(add_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_column = true && this.isSetColumn(); + boolean that_present_column = true && that.isSetColumn(); + if (this_present_column || that_present_column) { + if (!(this_present_column && that_present_column)) + return false; + if (!this.column.equals(that.column)) + 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_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + 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(add_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + add_args typedOther = (add_args)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = 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 = TBaseHelper.compareTo(this.column_parent, typedOther.column_parent); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetColumn()).compareTo(typedOther.isSetColumn()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetColumn()) { + lastComparison = TBaseHelper.compareTo(this.column, typedOther.column); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(typedOther.isSetConsistency_level()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetConsistency_level()) { + lastComparison = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == TType.STRING) { + this.key = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // COLUMN_PARENT + if (field.type == TType.STRUCT) { + this.column_parent = new ColumnParent(); + this.column_parent.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // COLUMN + if (field.type == TType.STRUCT) { + this.column = new CounterColumn(); + this.column.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.column_parent != null) { + oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC); + this.column_parent.write(oprot); + oprot.writeFieldEnd(); + } + if (this.column != null) { + oprot.writeFieldBegin(COLUMN_FIELD_DESC); + this.column.write(oprot); + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("add_args("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("column_parent:"); + if (this.column_parent == null) { + sb.append("null"); + } else { + sb.append(this.column_parent); + } + first = false; + if (!first) sb.append(", "); + sb.append("column:"); + if (this.column == null) { + sb.append("null"); + } else { + sb.append(this.column); + } + 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 TException { + // check for required fields + if (key == null) { + throw new TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (column_parent == null) { + throw new TProtocolException("Required field 'column_parent' was not present! Struct: " + toString()); + } + if (column == null) { + throw new TProtocolException("Required field 'column' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class add_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("add_result"); + + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)2); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)3); + + public InvalidRequestException ire; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + IRE((short)1, "ire"), + UE((short)2, "ue"), + TE((short)3, "te"); + + private static final Map byName = new HashMap(); + + 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: // IRE + return IRE; + case 2: // UE + return UE; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(add_result.class, metaDataMap); + } + + public add_result() { + } + + public add_result( + InvalidRequestException ire, + UnavailableException ue, + TimedOutException te) + { + this(); + this.ire = ire; + this.ue = ue; + this.te = te; + } + + /** + * Performs a deep copy on other. + */ + public add_result(add_result other) { + if (other.isSetIre()) { + this.ire = new InvalidRequestException(other.ire); + } + if (other.isSetUe()) { + this.ue = new UnavailableException(other.ue); + } + if (other.isSetTe()) { + this.te = new TimedOutException(other.te); + } + } + + public add_result deepCopy() { + return new add_result(this); + } + + @Override + public void clear() { + this.ire = null; + this.ue = null; + this.te = null; + } + + public InvalidRequestException getIre() { + return this.ire; + } + + public add_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned a value) and false otherwise */ + public boolean isSetIre() { + return this.ire != null; + } + + public void setIreIsSet(boolean value) { + if (!value) { + this.ire = null; + } + } + + public UnavailableException getUe() { + return this.ue; + } + + public add_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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 add_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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 IRE: + if (value == null) { + unsetIre(); + } else { + setIre((InvalidRequestException)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 IRE: + return getIre(); + + case UE: + return getUe(); + + case TE: + return getTe(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case IRE: + return isSetIre(); + 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 add_result) + return this.equals((add_result)that); + return false; + } + + public boolean equals(add_result that) { + if (that == null) + 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_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_ire = true && (isSetIre()); + builder.append(present_ire); + if (present_ire) + builder.append(ire); + + 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(add_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + add_result typedOther = (add_result)other; + + lastComparison = Boolean.valueOf(isSetIre()).compareTo(typedOther.isSetIre()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIre()) { + lastComparison = TBaseHelper.compareTo(this.ire, typedOther.ire); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUe()) { + lastComparison = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("add_result("); + boolean first = true; + + sb.append("ire:"); + if (this.ire == null) { + sb.append("null"); + } else { + sb.append(this.ire); + } + 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 TException { + // check for required fields + } + + } + + public static class batch_add_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("batch_add_args"); + + private static final TField UPDATE_MAP_FIELD_DESC = new TField("update_map", TType.MAP, (short)1); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)2); + + public Map>> update_map; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + UPDATE_MAP((short)1, "update_map"), + /** + * + * @see ConsistencyLevel + */ + CONSISTENCY_LEVEL((short)2, "consistency_level"); + + private static final Map byName = new HashMap(); + + 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: // UPDATE_MAP + return UPDATE_MAP; + case 2: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.UPDATE_MAP, new FieldMetaData("update_map", TFieldRequirementType.REQUIRED, + new MapMetaData(TType.MAP, + new FieldValueMetaData(TType.STRING), + new MapMetaData(TType.MAP, + new FieldValueMetaData(TType.STRING), + new ListMetaData(TType.LIST, + new StructMetaData(TType.STRUCT, CounterMutation.class)))))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(batch_add_args.class, metaDataMap); + } + + public batch_add_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public batch_add_args( + Map>> update_map, + ConsistencyLevel consistency_level) + { + this(); + this.update_map = update_map; + this.consistency_level = consistency_level; + } + + /** + * Performs a deep copy on other. + */ + public batch_add_args(batch_add_args other) { + if (other.isSetUpdate_map()) { + Map>> __this__update_map = new HashMap>>(); + for (Map.Entry>> other_element : other.update_map.entrySet()) { + + ByteBuffer other_element_key = other_element.getKey(); + Map> other_element_value = other_element.getValue(); + + ByteBuffer __this__update_map_copy_key = TBaseHelper.copyBinary(other_element_key); +; + + Map> __this__update_map_copy_value = new HashMap>(); + for (Map.Entry> other_element_value_element : other_element_value.entrySet()) { + + String other_element_value_element_key = other_element_value_element.getKey(); + List other_element_value_element_value = other_element_value_element.getValue(); + + String __this__update_map_copy_value_copy_key = other_element_value_element_key; + + List __this__update_map_copy_value_copy_value = new ArrayList(); + for (CounterMutation other_element_value_element_value_element : other_element_value_element_value) { + __this__update_map_copy_value_copy_value.add(new CounterMutation(other_element_value_element_value_element)); + } + + __this__update_map_copy_value.put(__this__update_map_copy_value_copy_key, __this__update_map_copy_value_copy_value); + } + + __this__update_map.put(__this__update_map_copy_key, __this__update_map_copy_value); + } + this.update_map = __this__update_map; + } + if (other.isSetConsistency_level()) { + this.consistency_level = other.consistency_level; + } + } + + public batch_add_args deepCopy() { + return new batch_add_args(this); + } + + @Override + public void clear() { + this.update_map = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public int getUpdate_mapSize() { + return (this.update_map == null) ? 0 : this.update_map.size(); + } + + public void putToUpdate_map(ByteBuffer key, Map> val) { + if (this.update_map == null) { + this.update_map = new HashMap>>(); + } + this.update_map.put(key, val); + } + + public Map>> getUpdate_map() { + return this.update_map; + } + + public batch_add_args setUpdate_map(Map>> update_map) { + this.update_map = update_map; + return this; + } + + public void unsetUpdate_map() { + this.update_map = null; + } + + /** Returns true if field update_map is set (has been asigned a value) and false otherwise */ + public boolean isSetUpdate_map() { + return this.update_map != null; + } + + public void setUpdate_mapIsSet(boolean value) { + if (!value) { + this.update_map = null; + } + } + + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel getConsistency_level() { + return this.consistency_level; + } + + /** + * + * @see ConsistencyLevel + */ + public batch_add_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 asigned 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 UPDATE_MAP: + if (value == null) { + unsetUpdate_map(); + } else { + setUpdate_map((Map>>)value); + } + break; + + case CONSISTENCY_LEVEL: + if (value == null) { + unsetConsistency_level(); + } else { + setConsistency_level((ConsistencyLevel)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case UPDATE_MAP: + return getUpdate_map(); + + case CONSISTENCY_LEVEL: + return getConsistency_level(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case UPDATE_MAP: + return isSetUpdate_map(); + case CONSISTENCY_LEVEL: + return isSetConsistency_level(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof batch_add_args) + return this.equals((batch_add_args)that); + return false; + } + + public boolean equals(batch_add_args that) { + if (that == null) + return false; + + boolean this_present_update_map = true && this.isSetUpdate_map(); + boolean that_present_update_map = true && that.isSetUpdate_map(); + if (this_present_update_map || that_present_update_map) { + if (!(this_present_update_map && that_present_update_map)) + return false; + if (!this.update_map.equals(that.update_map)) + 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_update_map = true && (isSetUpdate_map()); + builder.append(present_update_map); + if (present_update_map) + builder.append(update_map); + + 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(batch_add_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + batch_add_args typedOther = (batch_add_args)other; + + lastComparison = Boolean.valueOf(isSetUpdate_map()).compareTo(typedOther.isSetUpdate_map()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUpdate_map()) { + lastComparison = TBaseHelper.compareTo(this.update_map, typedOther.update_map); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(typedOther.isSetConsistency_level()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetConsistency_level()) { + lastComparison = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // UPDATE_MAP + if (field.type == TType.MAP) { + { + TMap _map90 = iprot.readMapBegin(); + this.update_map = new HashMap>>(2*_map90.size); + for (int _i91 = 0; _i91 < _map90.size; ++_i91) + { + ByteBuffer _key92; + Map> _val93; + _key92 = iprot.readBinary(); + { + TMap _map94 = iprot.readMapBegin(); + _val93 = new HashMap>(2*_map94.size); + for (int _i95 = 0; _i95 < _map94.size; ++_i95) + { + String _key96; + List _val97; + _key96 = iprot.readString(); + { + TList _list98 = iprot.readListBegin(); + _val97 = new ArrayList(_list98.size); + for (int _i99 = 0; _i99 < _list98.size; ++_i99) + { + CounterMutation _elem100; + _elem100 = new CounterMutation(); + _elem100.read(iprot); + _val97.add(_elem100); + } + iprot.readListEnd(); + } + _val93.put(_key96, _val97); + } + iprot.readMapEnd(); + } + this.update_map.put(_key92, _val93); + } + iprot.readMapEnd(); + } + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.update_map != null) { + oprot.writeFieldBegin(UPDATE_MAP_FIELD_DESC); + { + oprot.writeMapBegin(new TMap(TType.STRING, TType.MAP, this.update_map.size())); + for (Map.Entry>> _iter101 : this.update_map.entrySet()) + { + oprot.writeBinary(_iter101.getKey()); + { + oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, _iter101.getValue().size())); + for (Map.Entry> _iter102 : _iter101.getValue().entrySet()) + { + oprot.writeString(_iter102.getKey()); + { + oprot.writeListBegin(new TList(TType.STRUCT, _iter102.getValue().size())); + for (CounterMutation _iter103 : _iter102.getValue()) + { + _iter103.write(oprot); + } + oprot.writeListEnd(); + } + } + oprot.writeMapEnd(); + } + } + oprot.writeMapEnd(); + } + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("batch_add_args("); + boolean first = true; + + sb.append("update_map:"); + if (this.update_map == null) { + sb.append("null"); + } else { + sb.append(this.update_map); + } + 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 TException { + // check for required fields + if (update_map == null) { + throw new TProtocolException("Required field 'update_map' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class batch_add_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("batch_add_result"); + + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)2); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)3); + + public InvalidRequestException ire; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + IRE((short)1, "ire"), + UE((short)2, "ue"), + TE((short)3, "te"); + + private static final Map byName = new HashMap(); + + 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: // IRE + return IRE; + case 2: // UE + return UE; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(batch_add_result.class, metaDataMap); + } + + public batch_add_result() { + } + + public batch_add_result( + InvalidRequestException ire, + UnavailableException ue, + TimedOutException te) + { + this(); + this.ire = ire; + this.ue = ue; + this.te = te; + } + + /** + * Performs a deep copy on other. + */ + public batch_add_result(batch_add_result other) { + if (other.isSetIre()) { + this.ire = new InvalidRequestException(other.ire); + } + if (other.isSetUe()) { + this.ue = new UnavailableException(other.ue); + } + if (other.isSetTe()) { + this.te = new TimedOutException(other.te); + } + } + + public batch_add_result deepCopy() { + return new batch_add_result(this); + } + + @Override + public void clear() { + this.ire = null; + this.ue = null; + this.te = null; + } + + public InvalidRequestException getIre() { + return this.ire; + } + + public batch_add_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned a value) and false otherwise */ + public boolean isSetIre() { + return this.ire != null; + } + + public void setIreIsSet(boolean value) { + if (!value) { + this.ire = null; + } + } + + public UnavailableException getUe() { + return this.ue; + } + + public batch_add_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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 batch_add_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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 IRE: + if (value == null) { + unsetIre(); + } else { + setIre((InvalidRequestException)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 IRE: + return getIre(); + + case UE: + return getUe(); + + case TE: + return getTe(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case IRE: + return isSetIre(); + 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 batch_add_result) + return this.equals((batch_add_result)that); + return false; + } + + public boolean equals(batch_add_result that) { + if (that == null) + 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_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_ire = true && (isSetIre()); + builder.append(present_ire); + if (present_ire) + builder.append(ire); + + 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(batch_add_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + batch_add_result typedOther = (batch_add_result)other; + + lastComparison = Boolean.valueOf(isSetIre()).compareTo(typedOther.isSetIre()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIre()) { + lastComparison = TBaseHelper.compareTo(this.ire, typedOther.ire); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUe()) { + lastComparison = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("batch_add_result("); + boolean first = true; + + sb.append("ire:"); + if (this.ire == null) { + sb.append("null"); + } else { + sb.append(this.ire); + } + 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 TException { + // check for required fields + } + + } + + public static class get_counter_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("get_counter_args"); + + private static final TField KEY_FIELD_DESC = new TField("key", TType.STRING, (short)1); + private static final TField PATH_FIELD_DESC = new TField("path", TType.STRUCT, (short)2); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)3); + + public ByteBuffer key; + public ColumnPath path; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + KEY((short)1, "key"), + PATH((short)2, "path"), + /** + * + * @see ConsistencyLevel + */ + CONSISTENCY_LEVEL((short)3, "consistency_level"); + + private static final Map byName = new HashMap(); + + 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: // PATH + return PATH; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new FieldMetaData("key", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.PATH, new FieldMetaData("path", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, ColumnPath.class))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(get_counter_args.class, metaDataMap); + } + + public get_counter_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public get_counter_args( + ByteBuffer key, + ColumnPath path, + ConsistencyLevel consistency_level) + { + this(); + this.key = key; + this.path = path; + this.consistency_level = consistency_level; + } + + /** + * Performs a deep copy on other. + */ + public get_counter_args(get_counter_args other) { + if (other.isSetKey()) { + this.key = TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetPath()) { + this.path = new ColumnPath(other.path); + } + if (other.isSetConsistency_level()) { + this.consistency_level = other.consistency_level; + } + } + + public get_counter_args deepCopy() { + return new get_counter_args(this); + } + + @Override + public void clear() { + this.key = null; + this.path = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public byte[] getKey() { + setKey(TBaseHelper.rightSize(key)); + return key.array(); + } + + public ByteBuffer BufferForKey() { + return key; + } + + public get_counter_args setKey(byte[] key) { + setKey(ByteBuffer.wrap(key)); + return this; + } + + public get_counter_args setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been asigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public ColumnPath getPath() { + return this.path; + } + + public get_counter_args setPath(ColumnPath path) { + this.path = path; + return this; + } + + public void unsetPath() { + this.path = null; + } + + /** Returns true if field path is set (has been asigned a value) and false otherwise */ + public boolean isSetPath() { + return this.path != null; + } + + public void setPathIsSet(boolean value) { + if (!value) { + this.path = null; + } + } + + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel getConsistency_level() { + return this.consistency_level; + } + + /** + * + * @see ConsistencyLevel + */ + public get_counter_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 asigned 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 PATH: + if (value == null) { + unsetPath(); + } else { + setPath((ColumnPath)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 PATH: + return getPath(); + + case CONSISTENCY_LEVEL: + return getConsistency_level(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEY: + return isSetKey(); + case PATH: + return isSetPath(); + case CONSISTENCY_LEVEL: + return isSetConsistency_level(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof get_counter_args) + return this.equals((get_counter_args)that); + return false; + } + + public boolean equals(get_counter_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_path = true && this.isSetPath(); + boolean that_present_path = true && that.isSetPath(); + if (this_present_path || that_present_path) { + if (!(this_present_path && that_present_path)) + return false; + if (!this.path.equals(that.path)) + 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_path = true && (isSetPath()); + builder.append(present_path); + if (present_path) + builder.append(path); + + 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_counter_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + get_counter_args typedOther = (get_counter_args)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPath()).compareTo(typedOther.isSetPath()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPath()) { + lastComparison = TBaseHelper.compareTo(this.path, typedOther.path); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(typedOther.isSetConsistency_level()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetConsistency_level()) { + lastComparison = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == TType.STRING) { + this.key = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // PATH + if (field.type == TType.STRUCT) { + this.path = new ColumnPath(); + this.path.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.path != null) { + oprot.writeFieldBegin(PATH_FIELD_DESC); + this.path.write(oprot); + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("get_counter_args("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("path:"); + if (this.path == null) { + sb.append("null"); + } else { + sb.append(this.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 TException { + // check for required fields + if (key == null) { + throw new TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (path == null) { + throw new TProtocolException("Required field 'path' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class get_counter_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("get_counter_result"); + + private static final TField SUCCESS_FIELD_DESC = new TField("success", TType.STRUCT, (short)0); + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField NFE_FIELD_DESC = new TField("nfe", TType.STRUCT, (short)2); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)3); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)4); + + public Counter success; + public InvalidRequestException ire; + public NotFoundException nfe; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements 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 byName = new HashMap(); + + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUCCESS, new FieldMetaData("success", TFieldRequirementType.DEFAULT, + new StructMetaData(TType.STRUCT, Counter.class))); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.NFE, new FieldMetaData("nfe", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(get_counter_result.class, metaDataMap); + } + + public get_counter_result() { + } + + public get_counter_result( + Counter 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 other. + */ + public get_counter_result(get_counter_result other) { + if (other.isSetSuccess()) { + this.success = new Counter(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_counter_result deepCopy() { + return new get_counter_result(this); + } + + @Override + public void clear() { + this.success = null; + this.ire = null; + this.nfe = null; + this.ue = null; + this.te = null; + } + + public Counter getSuccess() { + return this.success; + } + + public get_counter_result setSuccess(Counter success) { + this.success = success; + return this; + } + + public void unsetSuccess() { + this.success = null; + } + + /** Returns true if field success is set (has been asigned 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_counter_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned 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_counter_result setNfe(NotFoundException nfe) { + this.nfe = nfe; + return this; + } + + public void unsetNfe() { + this.nfe = null; + } + + /** Returns true if field nfe is set (has been asigned 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_counter_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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_counter_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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((Counter)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 asigned 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_counter_result) + return this.equals((get_counter_result)that); + return false; + } + + public boolean equals(get_counter_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_counter_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + get_counter_result typedOther = (get_counter_result)other; + + lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuccess()) { + lastComparison = 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 = 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 = 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 = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 0: // SUCCESS + if (field.type == TType.STRUCT) { + this.success = new Counter(); + this.success.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // NFE + if (field.type == TType.STRUCT) { + this.nfe = new NotFoundException(); + this.nfe.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetSuccess()) { + oprot.writeFieldBegin(SUCCESS_FIELD_DESC); + this.success.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetNfe()) { + oprot.writeFieldBegin(NFE_FIELD_DESC); + this.nfe.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("get_counter_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 TException { + // check for required fields + } + + } + + public static class get_counter_slice_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("get_counter_slice_args"); + + private static final TField KEY_FIELD_DESC = new TField("key", TType.STRING, (short)1); + private static final TField COLUMN_PARENT_FIELD_DESC = new TField("column_parent", TType.STRUCT, (short)2); + private static final TField PREDICATE_FIELD_DESC = new TField("predicate", TType.STRUCT, (short)3); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)4); + + public ByteBuffer key; + public ColumnParent column_parent; + public SlicePredicate predicate; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements 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 byName = new HashMap(); + + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new FieldMetaData("key", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.COLUMN_PARENT, new FieldMetaData("column_parent", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, ColumnParent.class))); + tmpMap.put(_Fields.PREDICATE, new FieldMetaData("predicate", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, SlicePredicate.class))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(get_counter_slice_args.class, metaDataMap); + } + + public get_counter_slice_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public get_counter_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 other. + */ + public get_counter_slice_args(get_counter_slice_args other) { + if (other.isSetKey()) { + this.key = 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_counter_slice_args deepCopy() { + return new get_counter_slice_args(this); + } + + @Override + public void clear() { + this.key = null; + this.column_parent = null; + this.predicate = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public byte[] getKey() { + setKey(TBaseHelper.rightSize(key)); + return key.array(); + } + + public ByteBuffer BufferForKey() { + return key; + } + + public get_counter_slice_args setKey(byte[] key) { + setKey(ByteBuffer.wrap(key)); + return this; + } + + public get_counter_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 asigned 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_counter_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 asigned 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_counter_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 asigned 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_counter_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 asigned 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 asigned 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_counter_slice_args) + return this.equals((get_counter_slice_args)that); + return false; + } + + public boolean equals(get_counter_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_counter_slice_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + get_counter_slice_args typedOther = (get_counter_slice_args)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = 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 = 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 = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == TType.STRING) { + this.key = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // COLUMN_PARENT + if (field.type == TType.STRUCT) { + this.column_parent = new ColumnParent(); + this.column_parent.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // PREDICATE + if (field.type == TType.STRUCT) { + this.predicate = new SlicePredicate(); + this.predicate.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.column_parent != null) { + oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC); + this.column_parent.write(oprot); + oprot.writeFieldEnd(); + } + if (this.predicate != null) { + oprot.writeFieldBegin(PREDICATE_FIELD_DESC); + this.predicate.write(oprot); + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("get_counter_slice_args("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("column_parent:"); + if (this.column_parent == null) { + sb.append("null"); + } else { + 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(", "); + 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 TException { + // check for required fields + if (key == null) { + throw new TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (column_parent == null) { + throw new TProtocolException("Required field 'column_parent' was not present! Struct: " + toString()); + } + if (predicate == null) { + throw new TProtocolException("Required field 'predicate' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class get_counter_slice_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("get_counter_slice_result"); + + private static final TField SUCCESS_FIELD_DESC = new TField("success", TType.LIST, (short)0); + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)2); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)3); + + public List success; + public InvalidRequestException ire; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + SUCCESS((short)0, "success"), + IRE((short)1, "ire"), + UE((short)2, "ue"), + TE((short)3, "te"); + + private static final Map byName = new HashMap(); + + 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: // UE + return UE; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUCCESS, new FieldMetaData("success", TFieldRequirementType.DEFAULT, + new ListMetaData(TType.LIST, + new StructMetaData(TType.STRUCT, Counter.class)))); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(get_counter_slice_result.class, metaDataMap); + } + + public get_counter_slice_result() { + } + + public get_counter_slice_result( + List success, + InvalidRequestException ire, + UnavailableException ue, + TimedOutException te) + { + this(); + this.success = success; + this.ire = ire; + this.ue = ue; + this.te = te; + } + + /** + * Performs a deep copy on other. + */ + public get_counter_slice_result(get_counter_slice_result other) { + if (other.isSetSuccess()) { + List __this__success = new ArrayList(); + for (Counter other_element : other.success) { + __this__success.add(new Counter(other_element)); + } + this.success = __this__success; + } + if (other.isSetIre()) { + this.ire = new InvalidRequestException(other.ire); + } + if (other.isSetUe()) { + this.ue = new UnavailableException(other.ue); + } + if (other.isSetTe()) { + this.te = new TimedOutException(other.te); + } + } + + public get_counter_slice_result deepCopy() { + return new get_counter_slice_result(this); + } + + @Override + public void clear() { + this.success = null; + this.ire = null; + this.ue = null; + this.te = null; + } + + public int getSuccessSize() { + return (this.success == null) ? 0 : this.success.size(); + } + + public java.util.Iterator getSuccessIterator() { + return (this.success == null) ? null : this.success.iterator(); + } + + public void addToSuccess(Counter elem) { + if (this.success == null) { + this.success = new ArrayList(); + } + this.success.add(elem); + } + + public List getSuccess() { + return this.success; + } + + public get_counter_slice_result setSuccess(List success) { + this.success = success; + return this; + } + + public void unsetSuccess() { + this.success = null; + } + + /** Returns true if field success is set (has been asigned 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_counter_slice_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned a value) and false otherwise */ + public boolean isSetIre() { + return this.ire != null; + } + + public void setIreIsSet(boolean value) { + if (!value) { + this.ire = null; + } + } + + public UnavailableException getUe() { + return this.ue; + } + + public get_counter_slice_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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_counter_slice_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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((List)value); + } + break; + + case IRE: + if (value == null) { + unsetIre(); + } else { + setIre((InvalidRequestException)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 UE: + return getUe(); + + case TE: + return getTe(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned 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 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_counter_slice_result) + return this.equals((get_counter_slice_result)that); + return false; + } + + public boolean equals(get_counter_slice_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_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_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_counter_slice_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + get_counter_slice_result typedOther = (get_counter_slice_result)other; + + lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuccess()) { + lastComparison = 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 = TBaseHelper.compareTo(this.ire, typedOther.ire); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUe()) { + lastComparison = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 0: // SUCCESS + if (field.type == TType.LIST) { + { + TList _list104 = iprot.readListBegin(); + this.success = new ArrayList(_list104.size); + for (int _i105 = 0; _i105 < _list104.size; ++_i105) + { + Counter _elem106; + _elem106 = new Counter(); + _elem106.read(iprot); + this.success.add(_elem106); + } + iprot.readListEnd(); + } + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetSuccess()) { + oprot.writeFieldBegin(SUCCESS_FIELD_DESC); + { + oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); + for (Counter _iter107 : this.success) + { + _iter107.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } else if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("get_counter_slice_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("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 TException { + // check for required fields + } + + } + + public static class multiget_counter_slice_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("multiget_counter_slice_args"); + + private static final TField KEYS_FIELD_DESC = new TField("keys", TType.LIST, (short)1); + private static final TField COLUMN_PARENT_FIELD_DESC = new TField("column_parent", TType.STRUCT, (short)2); + private static final TField PREDICATE_FIELD_DESC = new TField("predicate", TType.STRUCT, (short)3); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)4); + + public List keys; + public ColumnParent column_parent; + public SlicePredicate predicate; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + KEYS((short)1, "keys"), + COLUMN_PARENT((short)2, "column_parent"), + PREDICATE((short)3, "predicate"), + /** + * + * @see ConsistencyLevel + */ + CONSISTENCY_LEVEL((short)4, "consistency_level"); + + private static final Map byName = new HashMap(); + + 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: // KEYS + return KEYS; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEYS, new FieldMetaData("keys", TFieldRequirementType.REQUIRED, + new ListMetaData(TType.LIST, + new FieldValueMetaData(TType.STRING)))); + tmpMap.put(_Fields.COLUMN_PARENT, new FieldMetaData("column_parent", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, ColumnParent.class))); + tmpMap.put(_Fields.PREDICATE, new FieldMetaData("predicate", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, SlicePredicate.class))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(multiget_counter_slice_args.class, metaDataMap); + } + + public multiget_counter_slice_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public multiget_counter_slice_args( + List keys, + ColumnParent column_parent, + SlicePredicate predicate, + ConsistencyLevel consistency_level) + { + this(); + this.keys = keys; + this.column_parent = column_parent; + this.predicate = predicate; + this.consistency_level = consistency_level; + } + + /** + * Performs a deep copy on other. + */ + public multiget_counter_slice_args(multiget_counter_slice_args other) { + if (other.isSetKeys()) { + List __this__keys = new ArrayList(); + for (ByteBuffer other_element : other.keys) { + ByteBuffer temp_binary_element = TBaseHelper.copyBinary(other_element); +; + __this__keys.add(temp_binary_element); + } + this.keys = __this__keys; + } + 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 multiget_counter_slice_args deepCopy() { + return new multiget_counter_slice_args(this); + } + + @Override + public void clear() { + this.keys = null; + this.column_parent = null; + this.predicate = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public int getKeysSize() { + return (this.keys == null) ? 0 : this.keys.size(); + } + + public java.util.Iterator getKeysIterator() { + return (this.keys == null) ? null : this.keys.iterator(); + } + + public void addToKeys(ByteBuffer elem) { + if (this.keys == null) { + this.keys = new ArrayList(); + } + this.keys.add(elem); + } + + public List getKeys() { + return this.keys; + } + + public multiget_counter_slice_args setKeys(List keys) { + this.keys = keys; + return this; + } + + public void unsetKeys() { + this.keys = null; + } + + /** Returns true if field keys is set (has been asigned a value) and false otherwise */ + public boolean isSetKeys() { + return this.keys != null; + } + + public void setKeysIsSet(boolean value) { + if (!value) { + this.keys = null; + } + } + + public ColumnParent getColumn_parent() { + return this.column_parent; + } + + public multiget_counter_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 asigned 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 multiget_counter_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 asigned 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 multiget_counter_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 asigned 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 KEYS: + if (value == null) { + unsetKeys(); + } else { + setKeys((List)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 KEYS: + return getKeys(); + + 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 asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEYS: + return isSetKeys(); + 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 multiget_counter_slice_args) + return this.equals((multiget_counter_slice_args)that); + return false; + } + + public boolean equals(multiget_counter_slice_args that) { + if (that == null) + return false; + + boolean this_present_keys = true && this.isSetKeys(); + boolean that_present_keys = true && that.isSetKeys(); + if (this_present_keys || that_present_keys) { + if (!(this_present_keys && that_present_keys)) + return false; + if (!this.keys.equals(that.keys)) + 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_keys = true && (isSetKeys()); + builder.append(present_keys); + if (present_keys) + builder.append(keys); + + 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(multiget_counter_slice_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + multiget_counter_slice_args typedOther = (multiget_counter_slice_args)other; + + lastComparison = Boolean.valueOf(isSetKeys()).compareTo(typedOther.isSetKeys()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKeys()) { + lastComparison = TBaseHelper.compareTo(this.keys, typedOther.keys); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetColumn_parent()).compareTo(typedOther.isSetColumn_parent()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetColumn_parent()) { + lastComparison = 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 = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEYS + if (field.type == TType.LIST) { + { + TList _list108 = iprot.readListBegin(); + this.keys = new ArrayList(_list108.size); + for (int _i109 = 0; _i109 < _list108.size; ++_i109) + { + ByteBuffer _elem110; + _elem110 = iprot.readBinary(); + this.keys.add(_elem110); + } + iprot.readListEnd(); + } + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // COLUMN_PARENT + if (field.type == TType.STRUCT) { + this.column_parent = new ColumnParent(); + this.column_parent.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // PREDICATE + if (field.type == TType.STRUCT) { + this.predicate = new SlicePredicate(); + this.predicate.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 4: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.keys != null) { + oprot.writeFieldBegin(KEYS_FIELD_DESC); + { + oprot.writeListBegin(new TList(TType.STRING, this.keys.size())); + for (ByteBuffer _iter111 : this.keys) + { + oprot.writeBinary(_iter111); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + if (this.column_parent != null) { + oprot.writeFieldBegin(COLUMN_PARENT_FIELD_DESC); + this.column_parent.write(oprot); + oprot.writeFieldEnd(); + } + if (this.predicate != null) { + oprot.writeFieldBegin(PREDICATE_FIELD_DESC); + this.predicate.write(oprot); + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("multiget_counter_slice_args("); + boolean first = true; + + sb.append("keys:"); + if (this.keys == null) { + sb.append("null"); + } else { + sb.append(this.keys); + } + first = false; + if (!first) sb.append(", "); + sb.append("column_parent:"); + if (this.column_parent == null) { + sb.append("null"); + } else { + 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(", "); + 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 TException { + // check for required fields + if (keys == null) { + throw new TProtocolException("Required field 'keys' was not present! Struct: " + toString()); + } + if (column_parent == null) { + throw new TProtocolException("Required field 'column_parent' was not present! Struct: " + toString()); + } + if (predicate == null) { + throw new TProtocolException("Required field 'predicate' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class multiget_counter_slice_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("multiget_counter_slice_result"); + + private static final TField SUCCESS_FIELD_DESC = new TField("success", TType.MAP, (short)0); + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)2); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)3); + + public Map> success; + public InvalidRequestException ire; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + SUCCESS((short)0, "success"), + IRE((short)1, "ire"), + UE((short)2, "ue"), + TE((short)3, "te"); + + private static final Map byName = new HashMap(); + + 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: // UE + return UE; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUCCESS, new FieldMetaData("success", TFieldRequirementType.DEFAULT, + new MapMetaData(TType.MAP, + new FieldValueMetaData(TType.STRING), + new ListMetaData(TType.LIST, + new StructMetaData(TType.STRUCT, Counter.class))))); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(multiget_counter_slice_result.class, metaDataMap); + } + + public multiget_counter_slice_result() { + } + + public multiget_counter_slice_result( + Map> success, + InvalidRequestException ire, + UnavailableException ue, + TimedOutException te) + { + this(); + this.success = success; + this.ire = ire; + this.ue = ue; + this.te = te; + } + + /** + * Performs a deep copy on other. + */ + public multiget_counter_slice_result(multiget_counter_slice_result other) { + if (other.isSetSuccess()) { + Map> __this__success = new HashMap>(); + for (Map.Entry> other_element : other.success.entrySet()) { + + ByteBuffer other_element_key = other_element.getKey(); + List other_element_value = other_element.getValue(); + + ByteBuffer __this__success_copy_key = TBaseHelper.copyBinary(other_element_key); +; + + List __this__success_copy_value = new ArrayList(); + for (Counter other_element_value_element : other_element_value) { + __this__success_copy_value.add(new Counter(other_element_value_element)); + } + + __this__success.put(__this__success_copy_key, __this__success_copy_value); + } + this.success = __this__success; + } + if (other.isSetIre()) { + this.ire = new InvalidRequestException(other.ire); + } + if (other.isSetUe()) { + this.ue = new UnavailableException(other.ue); + } + if (other.isSetTe()) { + this.te = new TimedOutException(other.te); + } + } + + public multiget_counter_slice_result deepCopy() { + return new multiget_counter_slice_result(this); + } + + @Override + public void clear() { + this.success = null; + this.ire = null; + this.ue = null; + this.te = null; + } + + public int getSuccessSize() { + return (this.success == null) ? 0 : this.success.size(); + } + + public void putToSuccess(ByteBuffer key, List val) { + if (this.success == null) { + this.success = new HashMap>(); + } + this.success.put(key, val); + } + + public Map> getSuccess() { + return this.success; + } + + public multiget_counter_slice_result setSuccess(Map> success) { + this.success = success; + return this; + } + + public void unsetSuccess() { + this.success = null; + } + + /** Returns true if field success is set (has been asigned 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 multiget_counter_slice_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned a value) and false otherwise */ + public boolean isSetIre() { + return this.ire != null; + } + + public void setIreIsSet(boolean value) { + if (!value) { + this.ire = null; + } + } + + public UnavailableException getUe() { + return this.ue; + } + + public multiget_counter_slice_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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 multiget_counter_slice_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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((Map>)value); + } + break; + + case IRE: + if (value == null) { + unsetIre(); + } else { + setIre((InvalidRequestException)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 UE: + return getUe(); + + case TE: + return getTe(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned 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 UE: + return isSetUe(); + case TE: + return isSetTe(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof multiget_counter_slice_result) + return this.equals((multiget_counter_slice_result)that); + return false; + } + + public boolean equals(multiget_counter_slice_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_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_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(multiget_counter_slice_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + multiget_counter_slice_result typedOther = (multiget_counter_slice_result)other; + + lastComparison = Boolean.valueOf(isSetSuccess()).compareTo(typedOther.isSetSuccess()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuccess()) { + lastComparison = 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 = TBaseHelper.compareTo(this.ire, typedOther.ire); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUe()) { + lastComparison = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 0: // SUCCESS + if (field.type == TType.MAP) { + { + TMap _map112 = iprot.readMapBegin(); + this.success = new HashMap>(2*_map112.size); + for (int _i113 = 0; _i113 < _map112.size; ++_i113) + { + ByteBuffer _key114; + List _val115; + _key114 = iprot.readBinary(); + { + TList _list116 = iprot.readListBegin(); + _val115 = new ArrayList(_list116.size); + for (int _i117 = 0; _i117 < _list116.size; ++_i117) + { + Counter _elem118; + _elem118 = new Counter(); + _elem118.read(iprot); + _val115.add(_elem118); + } + iprot.readListEnd(); + } + this.success.put(_key114, _val115); + } + iprot.readMapEnd(); + } + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetSuccess()) { + oprot.writeFieldBegin(SUCCESS_FIELD_DESC); + { + oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, this.success.size())); + for (Map.Entry> _iter119 : this.success.entrySet()) + { + oprot.writeBinary(_iter119.getKey()); + { + oprot.writeListBegin(new TList(TType.STRUCT, _iter119.getValue().size())); + for (Counter _iter120 : _iter119.getValue()) + { + _iter120.write(oprot); + } + oprot.writeListEnd(); + } + } + oprot.writeMapEnd(); + } + oprot.writeFieldEnd(); + } else if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("multiget_counter_slice_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("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 TException { + // check for required fields + } + + } + + public static class remove_counter_args implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("remove_counter_args"); + + private static final TField KEY_FIELD_DESC = new TField("key", TType.STRING, (short)1); + private static final TField PATH_FIELD_DESC = new TField("path", TType.STRUCT, (short)2); + private static final TField CONSISTENCY_LEVEL_FIELD_DESC = new TField("consistency_level", TType.I32, (short)3); + + public ByteBuffer key; + public ColumnPath path; + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel consistency_level; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + KEY((short)1, "key"), + PATH((short)2, "path"), + /** + * + * @see ConsistencyLevel + */ + CONSISTENCY_LEVEL((short)3, "consistency_level"); + + private static final Map byName = new HashMap(); + + 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: // PATH + return PATH; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.KEY, new FieldMetaData("key", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.PATH, new FieldMetaData("path", TFieldRequirementType.REQUIRED, + new StructMetaData(TType.STRUCT, ColumnPath.class))); + tmpMap.put(_Fields.CONSISTENCY_LEVEL, new FieldMetaData("consistency_level", TFieldRequirementType.REQUIRED, + new EnumMetaData(TType.ENUM, ConsistencyLevel.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(remove_counter_args.class, metaDataMap); + } + + public remove_counter_args() { + this.consistency_level = ConsistencyLevel.ONE; + + } + + public remove_counter_args( + ByteBuffer key, + ColumnPath path, + ConsistencyLevel consistency_level) + { + this(); + this.key = key; + this.path = path; + this.consistency_level = consistency_level; + } + + /** + * Performs a deep copy on other. + */ + public remove_counter_args(remove_counter_args other) { + if (other.isSetKey()) { + this.key = TBaseHelper.copyBinary(other.key); +; + } + if (other.isSetPath()) { + this.path = new ColumnPath(other.path); + } + if (other.isSetConsistency_level()) { + this.consistency_level = other.consistency_level; + } + } + + public remove_counter_args deepCopy() { + return new remove_counter_args(this); + } + + @Override + public void clear() { + this.key = null; + this.path = null; + this.consistency_level = ConsistencyLevel.ONE; + + } + + public byte[] getKey() { + setKey(TBaseHelper.rightSize(key)); + return key.array(); + } + + public ByteBuffer BufferForKey() { + return key; + } + + public remove_counter_args setKey(byte[] key) { + setKey(ByteBuffer.wrap(key)); + return this; + } + + public remove_counter_args setKey(ByteBuffer key) { + this.key = key; + return this; + } + + public void unsetKey() { + this.key = null; + } + + /** Returns true if field key is set (has been asigned a value) and false otherwise */ + public boolean isSetKey() { + return this.key != null; + } + + public void setKeyIsSet(boolean value) { + if (!value) { + this.key = null; + } + } + + public ColumnPath getPath() { + return this.path; + } + + public remove_counter_args setPath(ColumnPath path) { + this.path = path; + return this; + } + + public void unsetPath() { + this.path = null; + } + + /** Returns true if field path is set (has been asigned a value) and false otherwise */ + public boolean isSetPath() { + return this.path != null; + } + + public void setPathIsSet(boolean value) { + if (!value) { + this.path = null; + } + } + + /** + * + * @see ConsistencyLevel + */ + public ConsistencyLevel getConsistency_level() { + return this.consistency_level; + } + + /** + * + * @see ConsistencyLevel + */ + public remove_counter_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 asigned 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 PATH: + if (value == null) { + unsetPath(); + } else { + setPath((ColumnPath)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 PATH: + return getPath(); + + case CONSISTENCY_LEVEL: + return getConsistency_level(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case KEY: + return isSetKey(); + case PATH: + return isSetPath(); + case CONSISTENCY_LEVEL: + return isSetConsistency_level(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof remove_counter_args) + return this.equals((remove_counter_args)that); + return false; + } + + public boolean equals(remove_counter_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_path = true && this.isSetPath(); + boolean that_present_path = true && that.isSetPath(); + if (this_present_path || that_present_path) { + if (!(this_present_path && that_present_path)) + return false; + if (!this.path.equals(that.path)) + 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_path = true && (isSetPath()); + builder.append(present_path); + if (present_path) + builder.append(path); + + 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(remove_counter_args other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + remove_counter_args typedOther = (remove_counter_args)other; + + lastComparison = Boolean.valueOf(isSetKey()).compareTo(typedOther.isSetKey()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetKey()) { + lastComparison = TBaseHelper.compareTo(this.key, typedOther.key); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPath()).compareTo(typedOther.isSetPath()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPath()) { + lastComparison = TBaseHelper.compareTo(this.path, typedOther.path); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetConsistency_level()).compareTo(typedOther.isSetConsistency_level()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetConsistency_level()) { + lastComparison = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // KEY + if (field.type == TType.STRING) { + this.key = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // PATH + if (field.type == TType.STRUCT) { + this.path = new ColumnPath(); + this.path.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // CONSISTENCY_LEVEL + if (field.type == TType.I32) { + this.consistency_level = ConsistencyLevel.findByValue(iprot.readI32()); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.key != null) { + oprot.writeFieldBegin(KEY_FIELD_DESC); + oprot.writeBinary(this.key); + oprot.writeFieldEnd(); + } + if (this.path != null) { + oprot.writeFieldBegin(PATH_FIELD_DESC); + this.path.write(oprot); + oprot.writeFieldEnd(); + } + if (this.consistency_level != null) { + oprot.writeFieldBegin(CONSISTENCY_LEVEL_FIELD_DESC); + oprot.writeI32(this.consistency_level.getValue()); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("remove_counter_args("); + boolean first = true; + + sb.append("key:"); + if (this.key == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.key, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("path:"); + if (this.path == null) { + sb.append("null"); + } else { + sb.append(this.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 TException { + // check for required fields + if (key == null) { + throw new TProtocolException("Required field 'key' was not present! Struct: " + toString()); + } + if (path == null) { + throw new TProtocolException("Required field 'path' was not present! Struct: " + toString()); + } + if (consistency_level == null) { + throw new TProtocolException("Required field 'consistency_level' was not present! Struct: " + toString()); + } + } + + } + + public static class remove_counter_result implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("remove_counter_result"); + + private static final TField IRE_FIELD_DESC = new TField("ire", TType.STRUCT, (short)1); + private static final TField UE_FIELD_DESC = new TField("ue", TType.STRUCT, (short)2); + private static final TField TE_FIELD_DESC = new TField("te", TType.STRUCT, (short)3); + + public InvalidRequestException ire; + public UnavailableException ue; + public TimedOutException te; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + IRE((short)1, "ire"), + UE((short)2, "ue"), + TE((short)3, "te"); + + private static final Map byName = new HashMap(); + + 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: // IRE + return IRE; + case 2: // UE + return UE; + case 3: // 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.IRE, new FieldMetaData("ire", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.UE, new FieldMetaData("ue", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + tmpMap.put(_Fields.TE, new FieldMetaData("te", TFieldRequirementType.DEFAULT, + new FieldValueMetaData(TType.STRUCT))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(remove_counter_result.class, metaDataMap); + } + + public remove_counter_result() { + } + + public remove_counter_result( + InvalidRequestException ire, + UnavailableException ue, + TimedOutException te) + { + this(); + this.ire = ire; + this.ue = ue; + this.te = te; + } + + /** + * Performs a deep copy on other. + */ + public remove_counter_result(remove_counter_result other) { + if (other.isSetIre()) { + this.ire = new InvalidRequestException(other.ire); + } + if (other.isSetUe()) { + this.ue = new UnavailableException(other.ue); + } + if (other.isSetTe()) { + this.te = new TimedOutException(other.te); + } + } + + public remove_counter_result deepCopy() { + return new remove_counter_result(this); + } + + @Override + public void clear() { + this.ire = null; + this.ue = null; + this.te = null; + } + + public InvalidRequestException getIre() { + return this.ire; + } + + public remove_counter_result setIre(InvalidRequestException ire) { + this.ire = ire; + return this; + } + + public void unsetIre() { + this.ire = null; + } + + /** Returns true if field ire is set (has been asigned a value) and false otherwise */ + public boolean isSetIre() { + return this.ire != null; + } + + public void setIreIsSet(boolean value) { + if (!value) { + this.ire = null; + } + } + + public UnavailableException getUe() { + return this.ue; + } + + public remove_counter_result setUe(UnavailableException ue) { + this.ue = ue; + return this; + } + + public void unsetUe() { + this.ue = null; + } + + /** Returns true if field ue is set (has been asigned 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 remove_counter_result setTe(TimedOutException te) { + this.te = te; + return this; + } + + public void unsetTe() { + this.te = null; + } + + /** Returns true if field te is set (has been asigned 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 IRE: + if (value == null) { + unsetIre(); + } else { + setIre((InvalidRequestException)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 IRE: + return getIre(); + + case UE: + return getUe(); + + case TE: + return getTe(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case IRE: + return isSetIre(); + 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 remove_counter_result) + return this.equals((remove_counter_result)that); + return false; + } + + public boolean equals(remove_counter_result that) { + if (that == null) + 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_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_ire = true && (isSetIre()); + builder.append(present_ire); + if (present_ire) + builder.append(ire); + + 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(remove_counter_result other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + remove_counter_result typedOther = (remove_counter_result)other; + + lastComparison = Boolean.valueOf(isSetIre()).compareTo(typedOther.isSetIre()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetIre()) { + lastComparison = TBaseHelper.compareTo(this.ire, typedOther.ire); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetUe()).compareTo(typedOther.isSetUe()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetUe()) { + lastComparison = 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 = 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(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // IRE + if (field.type == TType.STRUCT) { + this.ire = new InvalidRequestException(); + this.ire.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // UE + if (field.type == TType.STRUCT) { + this.ue = new UnavailableException(); + this.ue.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 3: // TE + if (field.type == TType.STRUCT) { + this.te = new TimedOutException(); + this.te.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + oprot.writeStructBegin(STRUCT_DESC); + + if (this.isSetIre()) { + oprot.writeFieldBegin(IRE_FIELD_DESC); + this.ire.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetUe()) { + oprot.writeFieldBegin(UE_FIELD_DESC); + this.ue.write(oprot); + oprot.writeFieldEnd(); + } else if (this.isSetTe()) { + oprot.writeFieldBegin(TE_FIELD_DESC); + this.te.write(oprot); + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("remove_counter_result("); + boolean first = true; + + sb.append("ire:"); + if (this.ire == null) { + sb.append("null"); + } else { + sb.append(this.ire); + } + 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 TException { + // check for required fields + } + + } + public static class describe_schema_versions_args implements TBase, java.io.Serializable, Cloneable { private static final TStruct STRUCT_DESC = new TStruct("describe_schema_versions_args"); @@ -17767,25 +25347,25 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.MAP) { { - TMap _map86 = iprot.readMapBegin(); - this.success = new HashMap>(2*_map86.size); - for (int _i87 = 0; _i87 < _map86.size; ++_i87) + TMap _map121 = iprot.readMapBegin(); + this.success = new HashMap>(2*_map121.size); + for (int _i122 = 0; _i122 < _map121.size; ++_i122) { - String _key88; - List _val89; - _key88 = iprot.readString(); + String _key123; + List _val124; + _key123 = iprot.readString(); { - TList _list90 = iprot.readListBegin(); - _val89 = new ArrayList(_list90.size); - for (int _i91 = 0; _i91 < _list90.size; ++_i91) + TList _list125 = iprot.readListBegin(); + _val124 = new ArrayList(_list125.size); + for (int _i126 = 0; _i126 < _list125.size; ++_i126) { - String _elem92; - _elem92 = iprot.readString(); - _val89.add(_elem92); + String _elem127; + _elem127 = iprot.readString(); + _val124.add(_elem127); } iprot.readListEnd(); } - this.success.put(_key88, _val89); + this.success.put(_key123, _val124); } iprot.readMapEnd(); } @@ -17819,14 +25399,14 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeMapBegin(new TMap(TType.STRING, TType.LIST, this.success.size())); - for (Map.Entry> _iter93 : this.success.entrySet()) + for (Map.Entry> _iter128 : this.success.entrySet()) { - oprot.writeString(_iter93.getKey()); + oprot.writeString(_iter128.getKey()); { - oprot.writeListBegin(new TList(TType.STRING, _iter93.getValue().size())); - for (String _iter94 : _iter93.getValue()) + oprot.writeListBegin(new TList(TType.STRING, _iter128.getValue().size())); + for (String _iter129 : _iter128.getValue()) { - oprot.writeString(_iter94); + oprot.writeString(_iter129); } oprot.writeListEnd(); } @@ -18393,14 +25973,14 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list95 = iprot.readListBegin(); - this.success = new ArrayList(_list95.size); - for (int _i96 = 0; _i96 < _list95.size; ++_i96) + TList _list130 = iprot.readListBegin(); + this.success = new ArrayList(_list130.size); + for (int _i131 = 0; _i131 < _list130.size; ++_i131) { - KsDef _elem97; - _elem97 = new KsDef(); - _elem97.read(iprot); - this.success.add(_elem97); + KsDef _elem132; + _elem132 = new KsDef(); + _elem132.read(iprot); + this.success.add(_elem132); } iprot.readListEnd(); } @@ -18434,9 +26014,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); - for (KsDef _iter98 : this.success) + for (KsDef _iter133 : this.success) { - _iter98.write(oprot); + _iter133.write(oprot); } oprot.writeListEnd(); } @@ -20053,14 +27633,14 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list99 = iprot.readListBegin(); - this.success = new ArrayList(_list99.size); - for (int _i100 = 0; _i100 < _list99.size; ++_i100) + TList _list134 = iprot.readListBegin(); + this.success = new ArrayList(_list134.size); + for (int _i135 = 0; _i135 < _list134.size; ++_i135) { - TokenRange _elem101; - _elem101 = new TokenRange(); - _elem101.read(iprot); - this.success.add(_elem101); + TokenRange _elem136; + _elem136 = new TokenRange(); + _elem136.read(iprot); + this.success.add(_elem136); } iprot.readListEnd(); } @@ -20094,9 +27674,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.success.size())); - for (TokenRange _iter102 : this.success) + for (TokenRange _iter137 : this.success) { - _iter102.write(oprot); + _iter137.write(oprot); } oprot.writeListEnd(); } @@ -22696,13 +30276,13 @@ public class Cassandra { case 0: // SUCCESS if (field.type == TType.LIST) { { - TList _list103 = iprot.readListBegin(); - this.success = new ArrayList(_list103.size); - for (int _i104 = 0; _i104 < _list103.size; ++_i104) + TList _list138 = iprot.readListBegin(); + this.success = new ArrayList(_list138.size); + for (int _i139 = 0; _i139 < _list138.size; ++_i139) { - String _elem105; - _elem105 = iprot.readString(); - this.success.add(_elem105); + String _elem140; + _elem140 = iprot.readString(); + this.success.add(_elem140); } iprot.readListEnd(); } @@ -22728,9 +30308,9 @@ public class Cassandra { oprot.writeFieldBegin(SUCCESS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRING, this.success.size())); - for (String _iter106 : this.success) + for (String _iter141 : this.success) { - oprot.writeString(_iter106); + oprot.writeString(_iter141); } oprot.writeListEnd(); } diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java index d00a0d539c..0058ee4145 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/CfDef.java @@ -71,6 +71,7 @@ public class CfDef implements TBase, java.io.Serializable, private static final TField MEMTABLE_FLUSH_AFTER_MINS_FIELD_DESC = new TField("memtable_flush_after_mins", TType.I32, (short)21); private static final TField MEMTABLE_THROUGHPUT_IN_MB_FIELD_DESC = new TField("memtable_throughput_in_mb", TType.I32, (short)22); private static final TField MEMTABLE_OPERATIONS_IN_MILLIONS_FIELD_DESC = new TField("memtable_operations_in_millions", TType.DOUBLE, (short)23); + private static final TField REPLICATE_ON_WRITE_FIELD_DESC = new TField("replicate_on_write", TType.BOOL, (short)24); public String keyspace; public String name; @@ -92,6 +93,7 @@ public class CfDef implements TBase, java.io.Serializable, public int memtable_flush_after_mins; public int memtable_throughput_in_mb; public double memtable_operations_in_millions; + public boolean replicate_on_write; /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ public enum _Fields implements TFieldIdEnum { @@ -114,7 +116,8 @@ public class CfDef implements TBase, java.io.Serializable, KEY_CACHE_SAVE_PERIOD_IN_SECONDS((short)20, "key_cache_save_period_in_seconds"), MEMTABLE_FLUSH_AFTER_MINS((short)21, "memtable_flush_after_mins"), MEMTABLE_THROUGHPUT_IN_MB((short)22, "memtable_throughput_in_mb"), - MEMTABLE_OPERATIONS_IN_MILLIONS((short)23, "memtable_operations_in_millions"); + MEMTABLE_OPERATIONS_IN_MILLIONS((short)23, "memtable_operations_in_millions"), + REPLICATE_ON_WRITE((short)24, "replicate_on_write"); private static final Map byName = new HashMap(); @@ -169,6 +172,8 @@ public class CfDef implements TBase, java.io.Serializable, return MEMTABLE_THROUGHPUT_IN_MB; case 23: // MEMTABLE_OPERATIONS_IN_MILLIONS return MEMTABLE_OPERATIONS_IN_MILLIONS; + case 24: // REPLICATE_ON_WRITE + return REPLICATE_ON_WRITE; default: return null; } @@ -221,7 +226,8 @@ public class CfDef implements TBase, java.io.Serializable, private static final int __MEMTABLE_FLUSH_AFTER_MINS_ISSET_ID = 9; private static final int __MEMTABLE_THROUGHPUT_IN_MB_ISSET_ID = 10; private static final int __MEMTABLE_OPERATIONS_IN_MILLIONS_ISSET_ID = 11; - private BitSet __isset_bit_vector = new BitSet(12); + private static final int __REPLICATE_ON_WRITE_ISSET_ID = 12; + private BitSet __isset_bit_vector = new BitSet(13); public static final Map<_Fields, FieldMetaData> metaDataMap; static { @@ -267,6 +273,8 @@ public class CfDef implements TBase, java.io.Serializable, new FieldValueMetaData(TType.I32))); tmpMap.put(_Fields.MEMTABLE_OPERATIONS_IN_MILLIONS, new FieldMetaData("memtable_operations_in_millions", TFieldRequirementType.OPTIONAL, new FieldValueMetaData(TType.DOUBLE))); + tmpMap.put(_Fields.REPLICATE_ON_WRITE, new FieldMetaData("replicate_on_write", TFieldRequirementType.OPTIONAL, + new FieldValueMetaData(TType.BOOL))); metaDataMap = Collections.unmodifiableMap(tmpMap); FieldMetaData.addStructMetaDataMap(CfDef.class, metaDataMap); } @@ -282,6 +290,8 @@ public class CfDef implements TBase, java.io.Serializable, this.read_repair_chance = 1; + this.replicate_on_write = false; + } public CfDef( @@ -339,6 +349,7 @@ public class CfDef implements TBase, java.io.Serializable, this.memtable_flush_after_mins = other.memtable_flush_after_mins; this.memtable_throughput_in_mb = other.memtable_throughput_in_mb; this.memtable_operations_in_millions = other.memtable_operations_in_millions; + this.replicate_on_write = other.replicate_on_write; } public CfDef deepCopy() { @@ -381,6 +392,8 @@ public class CfDef implements TBase, java.io.Serializable, this.memtable_throughput_in_mb = 0; setMemtable_operations_in_millionsIsSet(false); this.memtable_operations_in_millions = 0.0; + this.replicate_on_write = false; + } public String getKeyspace() { @@ -866,6 +879,29 @@ public class CfDef implements TBase, java.io.Serializable, __isset_bit_vector.set(__MEMTABLE_OPERATIONS_IN_MILLIONS_ISSET_ID, value); } + public boolean isReplicate_on_write() { + return this.replicate_on_write; + } + + public CfDef setReplicate_on_write(boolean replicate_on_write) { + this.replicate_on_write = replicate_on_write; + setReplicate_on_writeIsSet(true); + return this; + } + + public void unsetReplicate_on_write() { + __isset_bit_vector.clear(__REPLICATE_ON_WRITE_ISSET_ID); + } + + /** Returns true if field replicate_on_write is set (has been asigned a value) and false otherwise */ + public boolean isSetReplicate_on_write() { + return __isset_bit_vector.get(__REPLICATE_ON_WRITE_ISSET_ID); + } + + public void setReplicate_on_writeIsSet(boolean value) { + __isset_bit_vector.set(__REPLICATE_ON_WRITE_ISSET_ID, value); + } + public void setFieldValue(_Fields field, Object value) { switch (field) { case KEYSPACE: @@ -1028,6 +1064,14 @@ public class CfDef implements TBase, java.io.Serializable, } break; + case REPLICATE_ON_WRITE: + if (value == null) { + unsetReplicate_on_write(); + } else { + setReplicate_on_write((Boolean)value); + } + break; + } } @@ -1093,6 +1137,9 @@ public class CfDef implements TBase, java.io.Serializable, case MEMTABLE_OPERATIONS_IN_MILLIONS: return new Double(getMemtable_operations_in_millions()); + case REPLICATE_ON_WRITE: + return new Boolean(isReplicate_on_write()); + } throw new IllegalStateException(); } @@ -1144,6 +1191,8 @@ public class CfDef implements TBase, java.io.Serializable, return isSetMemtable_throughput_in_mb(); case MEMTABLE_OPERATIONS_IN_MILLIONS: return isSetMemtable_operations_in_millions(); + case REPLICATE_ON_WRITE: + return isSetReplicate_on_write(); } throw new IllegalStateException(); } @@ -1341,6 +1390,15 @@ public class CfDef implements TBase, java.io.Serializable, return false; } + boolean this_present_replicate_on_write = true && this.isSetReplicate_on_write(); + boolean that_present_replicate_on_write = true && that.isSetReplicate_on_write(); + if (this_present_replicate_on_write || that_present_replicate_on_write) { + if (!(this_present_replicate_on_write && that_present_replicate_on_write)) + return false; + if (this.replicate_on_write != that.replicate_on_write) + return false; + } + return true; } @@ -1448,6 +1506,11 @@ public class CfDef implements TBase, java.io.Serializable, if (present_memtable_operations_in_millions) builder.append(memtable_operations_in_millions); + boolean present_replicate_on_write = true && (isSetReplicate_on_write()); + builder.append(present_replicate_on_write); + if (present_replicate_on_write) + builder.append(replicate_on_write); + return builder.toHashCode(); } @@ -1659,6 +1722,16 @@ public class CfDef implements TBase, java.io.Serializable, return lastComparison; } } + lastComparison = Boolean.valueOf(isSetReplicate_on_write()).compareTo(typedOther.isSetReplicate_on_write()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetReplicate_on_write()) { + lastComparison = TBaseHelper.compareTo(this.replicate_on_write, typedOther.replicate_on_write); + if (lastComparison != 0) { + return lastComparison; + } + } return 0; } @@ -1745,14 +1818,14 @@ public class CfDef implements TBase, java.io.Serializable, case 13: // COLUMN_METADATA if (field.type == TType.LIST) { { - TList _list25 = iprot.readListBegin(); - this.column_metadata = new ArrayList(_list25.size); - for (int _i26 = 0; _i26 < _list25.size; ++_i26) + TList _list29 = iprot.readListBegin(); + this.column_metadata = new ArrayList(_list29.size); + for (int _i30 = 0; _i30 < _list29.size; ++_i30) { - ColumnDef _elem27; - _elem27 = new ColumnDef(); - _elem27.read(iprot); - this.column_metadata.add(_elem27); + ColumnDef _elem31; + _elem31 = new ColumnDef(); + _elem31.read(iprot); + this.column_metadata.add(_elem31); } iprot.readListEnd(); } @@ -1839,6 +1912,14 @@ public class CfDef implements TBase, java.io.Serializable, TProtocolUtil.skip(iprot, field.type); } break; + case 24: // REPLICATE_ON_WRITE + if (field.type == TType.BOOL) { + this.replicate_on_write = iprot.readBool(); + setReplicate_on_writeIsSet(true); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; default: TProtocolUtil.skip(iprot, field.type); } @@ -1912,9 +1993,9 @@ public class CfDef implements TBase, java.io.Serializable, oprot.writeFieldBegin(COLUMN_METADATA_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.column_metadata.size())); - for (ColumnDef _iter28 : this.column_metadata) + for (ColumnDef _iter32 : this.column_metadata) { - _iter28.write(oprot); + _iter32.write(oprot); } oprot.writeListEnd(); } @@ -1973,6 +2054,11 @@ public class CfDef implements TBase, java.io.Serializable, oprot.writeDouble(this.memtable_operations_in_millions); oprot.writeFieldEnd(); } + if (isSetReplicate_on_write()) { + oprot.writeFieldBegin(REPLICATE_ON_WRITE_FIELD_DESC); + oprot.writeBool(this.replicate_on_write); + oprot.writeFieldEnd(); + } oprot.writeFieldStop(); oprot.writeStructEnd(); } @@ -2129,6 +2215,12 @@ public class CfDef implements TBase, java.io.Serializable, sb.append(this.memtable_operations_in_millions); first = false; } + if (isSetReplicate_on_write()) { + if (!first) sb.append(", "); + sb.append("replicate_on_write:"); + sb.append(this.replicate_on_write); + first = false; + } sb.append(")"); return sb.toString(); } diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/Counter.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/Counter.java new file mode 100644 index 0000000000..cfc09db9dd --- /dev/null +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/Counter.java @@ -0,0 +1,433 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.apache.cassandra.thrift; +/* + * + * 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. + * + */ + + +import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.*; +import org.apache.thrift.async.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.protocol.*; + +public class Counter implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("Counter"); + + private static final TField COLUMN_FIELD_DESC = new TField("column", TType.STRUCT, (short)1); + private static final TField SUPER_COLUMN_FIELD_DESC = new TField("super_column", TType.STRUCT, (short)2); + + public CounterColumn column; + public CounterSuperColumn super_column; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + COLUMN((short)1, "column"), + SUPER_COLUMN((short)2, "super_column"); + + private static final Map byName = new HashMap(); + + 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: // COLUMN + return COLUMN; + case 2: // SUPER_COLUMN + return SUPER_COLUMN; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.COLUMN, new FieldMetaData("column", TFieldRequirementType.OPTIONAL, + new StructMetaData(TType.STRUCT, CounterColumn.class))); + tmpMap.put(_Fields.SUPER_COLUMN, new FieldMetaData("super_column", TFieldRequirementType.OPTIONAL, + new StructMetaData(TType.STRUCT, CounterSuperColumn.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(Counter.class, metaDataMap); + } + + public Counter() { + } + + /** + * Performs a deep copy on other. + */ + public Counter(Counter other) { + if (other.isSetColumn()) { + this.column = new CounterColumn(other.column); + } + if (other.isSetSuper_column()) { + this.super_column = new CounterSuperColumn(other.super_column); + } + } + + public Counter deepCopy() { + return new Counter(this); + } + + @Override + public void clear() { + this.column = null; + this.super_column = null; + } + + public CounterColumn getColumn() { + return this.column; + } + + public Counter setColumn(CounterColumn column) { + this.column = column; + return this; + } + + public void unsetColumn() { + this.column = null; + } + + /** Returns true if field column is set (has been asigned a value) and false otherwise */ + public boolean isSetColumn() { + return this.column != null; + } + + public void setColumnIsSet(boolean value) { + if (!value) { + this.column = null; + } + } + + public CounterSuperColumn getSuper_column() { + return this.super_column; + } + + public Counter setSuper_column(CounterSuperColumn super_column) { + this.super_column = super_column; + return this; + } + + public void unsetSuper_column() { + this.super_column = null; + } + + /** Returns true if field super_column is set (has been asigned a value) and false otherwise */ + public boolean isSetSuper_column() { + return this.super_column != null; + } + + public void setSuper_columnIsSet(boolean value) { + if (!value) { + this.super_column = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case COLUMN: + if (value == null) { + unsetColumn(); + } else { + setColumn((CounterColumn)value); + } + break; + + case SUPER_COLUMN: + if (value == null) { + unsetSuper_column(); + } else { + setSuper_column((CounterSuperColumn)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case COLUMN: + return getColumn(); + + case SUPER_COLUMN: + return getSuper_column(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case COLUMN: + return isSetColumn(); + case SUPER_COLUMN: + return isSetSuper_column(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof Counter) + return this.equals((Counter)that); + return false; + } + + public boolean equals(Counter that) { + if (that == null) + return false; + + boolean this_present_column = true && this.isSetColumn(); + boolean that_present_column = true && that.isSetColumn(); + if (this_present_column || that_present_column) { + if (!(this_present_column && that_present_column)) + return false; + if (!this.column.equals(that.column)) + return false; + } + + boolean this_present_super_column = true && this.isSetSuper_column(); + boolean that_present_super_column = true && that.isSetSuper_column(); + if (this_present_super_column || that_present_super_column) { + if (!(this_present_super_column && that_present_super_column)) + return false; + if (!this.super_column.equals(that.super_column)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_column = true && (isSetColumn()); + builder.append(present_column); + if (present_column) + builder.append(column); + + boolean present_super_column = true && (isSetSuper_column()); + builder.append(present_super_column); + if (present_super_column) + builder.append(super_column); + + return builder.toHashCode(); + } + + public int compareTo(Counter other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + Counter typedOther = (Counter)other; + + lastComparison = Boolean.valueOf(isSetColumn()).compareTo(typedOther.isSetColumn()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetColumn()) { + lastComparison = TBaseHelper.compareTo(this.column, typedOther.column); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetSuper_column()).compareTo(typedOther.isSetSuper_column()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuper_column()) { + lastComparison = TBaseHelper.compareTo(this.super_column, typedOther.super_column); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // COLUMN + if (field.type == TType.STRUCT) { + this.column = new CounterColumn(); + this.column.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // SUPER_COLUMN + if (field.type == TType.STRUCT) { + this.super_column = new CounterSuperColumn(); + this.super_column.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.column != null) { + if (isSetColumn()) { + oprot.writeFieldBegin(COLUMN_FIELD_DESC); + this.column.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.super_column != null) { + if (isSetSuper_column()) { + oprot.writeFieldBegin(SUPER_COLUMN_FIELD_DESC); + this.super_column.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("Counter("); + boolean first = true; + + if (isSetColumn()) { + sb.append("column:"); + if (this.column == null) { + sb.append("null"); + } else { + sb.append(this.column); + } + first = false; + } + if (isSetSuper_column()) { + if (!first) sb.append(", "); + sb.append("super_column:"); + if (this.super_column == null) { + sb.append("null"); + } else { + sb.append(this.super_column); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws TException { + // check for required fields + } + +} + diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterColumn.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterColumn.java new file mode 100644 index 0000000000..ef4360c6b4 --- /dev/null +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterColumn.java @@ -0,0 +1,448 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.apache.cassandra.thrift; +/* + * + * 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. + * + */ + + +import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.*; +import org.apache.thrift.async.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.protocol.*; + +public class CounterColumn implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("CounterColumn"); + + private static final TField NAME_FIELD_DESC = new TField("name", TType.STRING, (short)1); + private static final TField VALUE_FIELD_DESC = new TField("value", TType.I64, (short)2); + + public ByteBuffer name; + public long value; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + NAME((short)1, "name"), + VALUE((short)2, "value"); + + private static final Map byName = new HashMap(); + + 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: // NAME + return NAME; + case 2: // VALUE + return VALUE; + 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 + private static final int __VALUE_ISSET_ID = 0; + private BitSet __isset_bit_vector = new BitSet(1); + + public static final Map<_Fields, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.NAME, new FieldMetaData("name", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.VALUE, new FieldMetaData("value", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.I64))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(CounterColumn.class, metaDataMap); + } + + public CounterColumn() { + } + + public CounterColumn( + ByteBuffer name, + long value) + { + this(); + this.name = name; + this.value = value; + setValueIsSet(true); + } + + /** + * Performs a deep copy on other. + */ + public CounterColumn(CounterColumn other) { + __isset_bit_vector.clear(); + __isset_bit_vector.or(other.__isset_bit_vector); + if (other.isSetName()) { + this.name = TBaseHelper.copyBinary(other.name); +; + } + this.value = other.value; + } + + public CounterColumn deepCopy() { + return new CounterColumn(this); + } + + @Override + public void clear() { + this.name = null; + setValueIsSet(false); + this.value = 0; + } + + public byte[] getName() { + setName(TBaseHelper.rightSize(name)); + return name.array(); + } + + public ByteBuffer BufferForName() { + return name; + } + + public CounterColumn setName(byte[] name) { + setName(ByteBuffer.wrap(name)); + return this; + } + + public CounterColumn setName(ByteBuffer name) { + this.name = name; + return this; + } + + public void unsetName() { + this.name = null; + } + + /** Returns true if field name is set (has been asigned a value) and false otherwise */ + public boolean isSetName() { + return this.name != null; + } + + public void setNameIsSet(boolean value) { + if (!value) { + this.name = null; + } + } + + public long getValue() { + return this.value; + } + + public CounterColumn setValue(long value) { + this.value = value; + setValueIsSet(true); + return this; + } + + public void unsetValue() { + __isset_bit_vector.clear(__VALUE_ISSET_ID); + } + + /** Returns true if field value is set (has been asigned a value) and false otherwise */ + public boolean isSetValue() { + return __isset_bit_vector.get(__VALUE_ISSET_ID); + } + + public void setValueIsSet(boolean value) { + __isset_bit_vector.set(__VALUE_ISSET_ID, value); + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case NAME: + if (value == null) { + unsetName(); + } else { + setName((ByteBuffer)value); + } + break; + + case VALUE: + if (value == null) { + unsetValue(); + } else { + setValue((Long)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case NAME: + return getName(); + + case VALUE: + return new Long(getValue()); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case NAME: + return isSetName(); + case VALUE: + return isSetValue(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CounterColumn) + return this.equals((CounterColumn)that); + return false; + } + + public boolean equals(CounterColumn that) { + if (that == null) + return false; + + boolean this_present_name = true && this.isSetName(); + boolean that_present_name = true && that.isSetName(); + if (this_present_name || that_present_name) { + if (!(this_present_name && that_present_name)) + return false; + if (!this.name.equals(that.name)) + return false; + } + + boolean this_present_value = true; + boolean that_present_value = true; + if (this_present_value || that_present_value) { + if (!(this_present_value && that_present_value)) + return false; + if (this.value != that.value) + return false; + } + + return true; + } + + @Override + public int hashCode() { + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_name = true && (isSetName()); + builder.append(present_name); + if (present_name) + builder.append(name); + + boolean present_value = true; + builder.append(present_value); + if (present_value) + builder.append(value); + + return builder.toHashCode(); + } + + public int compareTo(CounterColumn other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CounterColumn typedOther = (CounterColumn)other; + + lastComparison = Boolean.valueOf(isSetName()).compareTo(typedOther.isSetName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetName()) { + lastComparison = TBaseHelper.compareTo(this.name, typedOther.name); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetValue()).compareTo(typedOther.isSetValue()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetValue()) { + lastComparison = TBaseHelper.compareTo(this.value, typedOther.value); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // NAME + if (field.type == TType.STRING) { + this.name = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // VALUE + if (field.type == TType.I64) { + this.value = iprot.readI64(); + setValueIsSet(true); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + if (!isSetValue()) { + throw new TProtocolException("Required field 'value' was not found in serialized data! Struct: " + toString()); + } + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.name != null) { + oprot.writeFieldBegin(NAME_FIELD_DESC); + oprot.writeBinary(this.name); + oprot.writeFieldEnd(); + } + oprot.writeFieldBegin(VALUE_FIELD_DESC); + oprot.writeI64(this.value); + oprot.writeFieldEnd(); + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CounterColumn("); + boolean first = true; + + sb.append("name:"); + if (this.name == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.name, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("value:"); + sb.append(this.value); + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws TException { + // check for required fields + if (name == null) { + throw new TProtocolException("Required field 'name' was not present! Struct: " + toString()); + } + // alas, we cannot check 'value' because it's a primitive and you chose the non-beans generator. + } + +} + diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterDeletion.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterDeletion.java new file mode 100644 index 0000000000..f426c67901 --- /dev/null +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterDeletion.java @@ -0,0 +1,443 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.apache.cassandra.thrift; +/* + * + * 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. + * + */ + + +import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.*; +import org.apache.thrift.async.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.protocol.*; + +public class CounterDeletion implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("CounterDeletion"); + + private static final TField SUPER_COLUMN_FIELD_DESC = new TField("super_column", TType.STRING, (short)1); + private static final TField PREDICATE_FIELD_DESC = new TField("predicate", TType.STRUCT, (short)2); + + public ByteBuffer super_column; + public SlicePredicate predicate; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + SUPER_COLUMN((short)1, "super_column"), + PREDICATE((short)2, "predicate"); + + private static final Map byName = new HashMap(); + + 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: // SUPER_COLUMN + return SUPER_COLUMN; + case 2: // PREDICATE + return PREDICATE; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.SUPER_COLUMN, new FieldMetaData("super_column", TFieldRequirementType.OPTIONAL, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.PREDICATE, new FieldMetaData("predicate", TFieldRequirementType.OPTIONAL, + new StructMetaData(TType.STRUCT, SlicePredicate.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(CounterDeletion.class, metaDataMap); + } + + public CounterDeletion() { + } + + /** + * Performs a deep copy on other. + */ + public CounterDeletion(CounterDeletion other) { + if (other.isSetSuper_column()) { + this.super_column = TBaseHelper.copyBinary(other.super_column); +; + } + if (other.isSetPredicate()) { + this.predicate = new SlicePredicate(other.predicate); + } + } + + public CounterDeletion deepCopy() { + return new CounterDeletion(this); + } + + @Override + public void clear() { + this.super_column = null; + this.predicate = null; + } + + public byte[] getSuper_column() { + setSuper_column(TBaseHelper.rightSize(super_column)); + return super_column.array(); + } + + public ByteBuffer BufferForSuper_column() { + return super_column; + } + + public CounterDeletion setSuper_column(byte[] super_column) { + setSuper_column(ByteBuffer.wrap(super_column)); + return this; + } + + public CounterDeletion setSuper_column(ByteBuffer super_column) { + this.super_column = super_column; + return this; + } + + public void unsetSuper_column() { + this.super_column = null; + } + + /** Returns true if field super_column is set (has been asigned a value) and false otherwise */ + public boolean isSetSuper_column() { + return this.super_column != null; + } + + public void setSuper_columnIsSet(boolean value) { + if (!value) { + this.super_column = null; + } + } + + public SlicePredicate getPredicate() { + return this.predicate; + } + + public CounterDeletion setPredicate(SlicePredicate predicate) { + this.predicate = predicate; + return this; + } + + public void unsetPredicate() { + this.predicate = null; + } + + /** Returns true if field predicate is set (has been asigned a value) and false otherwise */ + public boolean isSetPredicate() { + return this.predicate != null; + } + + public void setPredicateIsSet(boolean value) { + if (!value) { + this.predicate = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case SUPER_COLUMN: + if (value == null) { + unsetSuper_column(); + } else { + setSuper_column((ByteBuffer)value); + } + break; + + case PREDICATE: + if (value == null) { + unsetPredicate(); + } else { + setPredicate((SlicePredicate)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case SUPER_COLUMN: + return getSuper_column(); + + case PREDICATE: + return getPredicate(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case SUPER_COLUMN: + return isSetSuper_column(); + case PREDICATE: + return isSetPredicate(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CounterDeletion) + return this.equals((CounterDeletion)that); + return false; + } + + public boolean equals(CounterDeletion that) { + if (that == null) + return false; + + boolean this_present_super_column = true && this.isSetSuper_column(); + boolean that_present_super_column = true && that.isSetSuper_column(); + if (this_present_super_column || that_present_super_column) { + if (!(this_present_super_column && that_present_super_column)) + return false; + if (!this.super_column.equals(that.super_column)) + 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; + } + + return true; + } + + @Override + public int hashCode() { + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_super_column = true && (isSetSuper_column()); + builder.append(present_super_column); + if (present_super_column) + builder.append(super_column); + + boolean present_predicate = true && (isSetPredicate()); + builder.append(present_predicate); + if (present_predicate) + builder.append(predicate); + + return builder.toHashCode(); + } + + public int compareTo(CounterDeletion other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CounterDeletion typedOther = (CounterDeletion)other; + + lastComparison = Boolean.valueOf(isSetSuper_column()).compareTo(typedOther.isSetSuper_column()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetSuper_column()) { + lastComparison = TBaseHelper.compareTo(this.super_column, typedOther.super_column); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetPredicate()).compareTo(typedOther.isSetPredicate()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetPredicate()) { + lastComparison = TBaseHelper.compareTo(this.predicate, typedOther.predicate); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // SUPER_COLUMN + if (field.type == TType.STRING) { + this.super_column = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // PREDICATE + if (field.type == TType.STRUCT) { + this.predicate = new SlicePredicate(); + this.predicate.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.super_column != null) { + if (isSetSuper_column()) { + oprot.writeFieldBegin(SUPER_COLUMN_FIELD_DESC); + oprot.writeBinary(this.super_column); + oprot.writeFieldEnd(); + } + } + if (this.predicate != null) { + if (isSetPredicate()) { + oprot.writeFieldBegin(PREDICATE_FIELD_DESC); + this.predicate.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CounterDeletion("); + boolean first = true; + + if (isSetSuper_column()) { + sb.append("super_column:"); + if (this.super_column == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.super_column, sb); + } + first = false; + } + if (isSetPredicate()) { + if (!first) sb.append(", "); + sb.append("predicate:"); + if (this.predicate == null) { + sb.append("null"); + } else { + sb.append(this.predicate); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws TException { + // check for required fields + } + +} + diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterMutation.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterMutation.java new file mode 100644 index 0000000000..9b66eb0df3 --- /dev/null +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterMutation.java @@ -0,0 +1,438 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.apache.cassandra.thrift; +/* + * + * 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. + * + */ + + +import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.*; +import org.apache.thrift.async.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.protocol.*; + +/** + * A CounterMutation is either an insert, represented by filling counter, or a deletion, represented by filling the deletion attribute. + * @param counter. An insert to a counter column or supercolumn + * @param deletion. A deletion of a counter column or supercolumn + */ +public class CounterMutation implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("CounterMutation"); + + private static final TField COUNTER_FIELD_DESC = new TField("counter", TType.STRUCT, (short)1); + private static final TField DELETION_FIELD_DESC = new TField("deletion", TType.STRUCT, (short)2); + + public Counter counter; + public CounterDeletion deletion; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + COUNTER((short)1, "counter"), + DELETION((short)2, "deletion"); + + private static final Map byName = new HashMap(); + + 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: // COUNTER + return COUNTER; + case 2: // DELETION + return DELETION; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.COUNTER, new FieldMetaData("counter", TFieldRequirementType.OPTIONAL, + new StructMetaData(TType.STRUCT, Counter.class))); + tmpMap.put(_Fields.DELETION, new FieldMetaData("deletion", TFieldRequirementType.OPTIONAL, + new StructMetaData(TType.STRUCT, CounterDeletion.class))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(CounterMutation.class, metaDataMap); + } + + public CounterMutation() { + } + + /** + * Performs a deep copy on other. + */ + public CounterMutation(CounterMutation other) { + if (other.isSetCounter()) { + this.counter = new Counter(other.counter); + } + if (other.isSetDeletion()) { + this.deletion = new CounterDeletion(other.deletion); + } + } + + public CounterMutation deepCopy() { + return new CounterMutation(this); + } + + @Override + public void clear() { + this.counter = null; + this.deletion = null; + } + + public Counter getCounter() { + return this.counter; + } + + public CounterMutation setCounter(Counter counter) { + this.counter = counter; + return this; + } + + public void unsetCounter() { + this.counter = null; + } + + /** Returns true if field counter is set (has been asigned a value) and false otherwise */ + public boolean isSetCounter() { + return this.counter != null; + } + + public void setCounterIsSet(boolean value) { + if (!value) { + this.counter = null; + } + } + + public CounterDeletion getDeletion() { + return this.deletion; + } + + public CounterMutation setDeletion(CounterDeletion deletion) { + this.deletion = deletion; + return this; + } + + public void unsetDeletion() { + this.deletion = null; + } + + /** Returns true if field deletion is set (has been asigned a value) and false otherwise */ + public boolean isSetDeletion() { + return this.deletion != null; + } + + public void setDeletionIsSet(boolean value) { + if (!value) { + this.deletion = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case COUNTER: + if (value == null) { + unsetCounter(); + } else { + setCounter((Counter)value); + } + break; + + case DELETION: + if (value == null) { + unsetDeletion(); + } else { + setDeletion((CounterDeletion)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case COUNTER: + return getCounter(); + + case DELETION: + return getDeletion(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case COUNTER: + return isSetCounter(); + case DELETION: + return isSetDeletion(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CounterMutation) + return this.equals((CounterMutation)that); + return false; + } + + public boolean equals(CounterMutation that) { + if (that == null) + return false; + + boolean this_present_counter = true && this.isSetCounter(); + boolean that_present_counter = true && that.isSetCounter(); + if (this_present_counter || that_present_counter) { + if (!(this_present_counter && that_present_counter)) + return false; + if (!this.counter.equals(that.counter)) + return false; + } + + boolean this_present_deletion = true && this.isSetDeletion(); + boolean that_present_deletion = true && that.isSetDeletion(); + if (this_present_deletion || that_present_deletion) { + if (!(this_present_deletion && that_present_deletion)) + return false; + if (!this.deletion.equals(that.deletion)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_counter = true && (isSetCounter()); + builder.append(present_counter); + if (present_counter) + builder.append(counter); + + boolean present_deletion = true && (isSetDeletion()); + builder.append(present_deletion); + if (present_deletion) + builder.append(deletion); + + return builder.toHashCode(); + } + + public int compareTo(CounterMutation other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CounterMutation typedOther = (CounterMutation)other; + + lastComparison = Boolean.valueOf(isSetCounter()).compareTo(typedOther.isSetCounter()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetCounter()) { + lastComparison = TBaseHelper.compareTo(this.counter, typedOther.counter); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetDeletion()).compareTo(typedOther.isSetDeletion()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetDeletion()) { + lastComparison = TBaseHelper.compareTo(this.deletion, typedOther.deletion); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // COUNTER + if (field.type == TType.STRUCT) { + this.counter = new Counter(); + this.counter.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // DELETION + if (field.type == TType.STRUCT) { + this.deletion = new CounterDeletion(); + this.deletion.read(iprot); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.counter != null) { + if (isSetCounter()) { + oprot.writeFieldBegin(COUNTER_FIELD_DESC); + this.counter.write(oprot); + oprot.writeFieldEnd(); + } + } + if (this.deletion != null) { + if (isSetDeletion()) { + oprot.writeFieldBegin(DELETION_FIELD_DESC); + this.deletion.write(oprot); + oprot.writeFieldEnd(); + } + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CounterMutation("); + boolean first = true; + + if (isSetCounter()) { + sb.append("counter:"); + if (this.counter == null) { + sb.append("null"); + } else { + sb.append(this.counter); + } + first = false; + } + if (isSetDeletion()) { + if (!first) sb.append(", "); + sb.append("deletion:"); + if (this.deletion == null) { + sb.append("null"); + } else { + sb.append(this.deletion); + } + first = false; + } + sb.append(")"); + return sb.toString(); + } + + public void validate() throws TException { + // check for required fields + } + +} + diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterSuperColumn.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterSuperColumn.java new file mode 100644 index 0000000000..55c2037daf --- /dev/null +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/CounterSuperColumn.java @@ -0,0 +1,487 @@ +/** + * Autogenerated by Thrift + * + * DO NOT EDIT UNLESS YOU ARE SURE THAT YOU KNOW WHAT YOU ARE DOING + */ +package org.apache.cassandra.thrift; +/* + * + * 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. + * + */ + + +import org.apache.commons.lang.builder.HashCodeBuilder; +import java.util.List; +import java.util.ArrayList; +import java.util.Map; +import java.util.HashMap; +import java.util.EnumMap; +import java.util.Set; +import java.util.HashSet; +import java.util.EnumSet; +import java.util.Collections; +import java.util.BitSet; +import java.nio.ByteBuffer; +import java.util.Arrays; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import org.apache.thrift.*; +import org.apache.thrift.async.*; +import org.apache.thrift.meta_data.*; +import org.apache.thrift.transport.*; +import org.apache.thrift.protocol.*; + +public class CounterSuperColumn implements TBase, java.io.Serializable, Cloneable { + private static final TStruct STRUCT_DESC = new TStruct("CounterSuperColumn"); + + private static final TField NAME_FIELD_DESC = new TField("name", TType.STRING, (short)1); + private static final TField COLUMNS_FIELD_DESC = new TField("columns", TType.LIST, (short)2); + + public ByteBuffer name; + public List columns; + + /** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */ + public enum _Fields implements TFieldIdEnum { + NAME((short)1, "name"), + COLUMNS((short)2, "columns"); + + private static final Map byName = new HashMap(); + + 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: // NAME + return NAME; + case 2: // COLUMNS + return COLUMNS; + 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, FieldMetaData> metaDataMap; + static { + Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class); + tmpMap.put(_Fields.NAME, new FieldMetaData("name", TFieldRequirementType.REQUIRED, + new FieldValueMetaData(TType.STRING))); + tmpMap.put(_Fields.COLUMNS, new FieldMetaData("columns", TFieldRequirementType.REQUIRED, + new ListMetaData(TType.LIST, + new StructMetaData(TType.STRUCT, CounterColumn.class)))); + metaDataMap = Collections.unmodifiableMap(tmpMap); + FieldMetaData.addStructMetaDataMap(CounterSuperColumn.class, metaDataMap); + } + + public CounterSuperColumn() { + } + + public CounterSuperColumn( + ByteBuffer name, + List columns) + { + this(); + this.name = name; + this.columns = columns; + } + + /** + * Performs a deep copy on other. + */ + public CounterSuperColumn(CounterSuperColumn other) { + if (other.isSetName()) { + this.name = TBaseHelper.copyBinary(other.name); +; + } + if (other.isSetColumns()) { + List __this__columns = new ArrayList(); + for (CounterColumn other_element : other.columns) { + __this__columns.add(new CounterColumn(other_element)); + } + this.columns = __this__columns; + } + } + + public CounterSuperColumn deepCopy() { + return new CounterSuperColumn(this); + } + + @Override + public void clear() { + this.name = null; + this.columns = null; + } + + public byte[] getName() { + setName(TBaseHelper.rightSize(name)); + return name.array(); + } + + public ByteBuffer BufferForName() { + return name; + } + + public CounterSuperColumn setName(byte[] name) { + setName(ByteBuffer.wrap(name)); + return this; + } + + public CounterSuperColumn setName(ByteBuffer name) { + this.name = name; + return this; + } + + public void unsetName() { + this.name = null; + } + + /** Returns true if field name is set (has been asigned a value) and false otherwise */ + public boolean isSetName() { + return this.name != null; + } + + public void setNameIsSet(boolean value) { + if (!value) { + this.name = null; + } + } + + public int getColumnsSize() { + return (this.columns == null) ? 0 : this.columns.size(); + } + + public java.util.Iterator getColumnsIterator() { + return (this.columns == null) ? null : this.columns.iterator(); + } + + public void addToColumns(CounterColumn elem) { + if (this.columns == null) { + this.columns = new ArrayList(); + } + this.columns.add(elem); + } + + public List getColumns() { + return this.columns; + } + + public CounterSuperColumn setColumns(List columns) { + this.columns = columns; + return this; + } + + public void unsetColumns() { + this.columns = null; + } + + /** Returns true if field columns is set (has been asigned a value) and false otherwise */ + public boolean isSetColumns() { + return this.columns != null; + } + + public void setColumnsIsSet(boolean value) { + if (!value) { + this.columns = null; + } + } + + public void setFieldValue(_Fields field, Object value) { + switch (field) { + case NAME: + if (value == null) { + unsetName(); + } else { + setName((ByteBuffer)value); + } + break; + + case COLUMNS: + if (value == null) { + unsetColumns(); + } else { + setColumns((List)value); + } + break; + + } + } + + public Object getFieldValue(_Fields field) { + switch (field) { + case NAME: + return getName(); + + case COLUMNS: + return getColumns(); + + } + throw new IllegalStateException(); + } + + /** Returns true if field corresponding to fieldID is set (has been asigned a value) and false otherwise */ + public boolean isSet(_Fields field) { + if (field == null) { + throw new IllegalArgumentException(); + } + + switch (field) { + case NAME: + return isSetName(); + case COLUMNS: + return isSetColumns(); + } + throw new IllegalStateException(); + } + + @Override + public boolean equals(Object that) { + if (that == null) + return false; + if (that instanceof CounterSuperColumn) + return this.equals((CounterSuperColumn)that); + return false; + } + + public boolean equals(CounterSuperColumn that) { + if (that == null) + return false; + + boolean this_present_name = true && this.isSetName(); + boolean that_present_name = true && that.isSetName(); + if (this_present_name || that_present_name) { + if (!(this_present_name && that_present_name)) + return false; + if (!this.name.equals(that.name)) + return false; + } + + boolean this_present_columns = true && this.isSetColumns(); + boolean that_present_columns = true && that.isSetColumns(); + if (this_present_columns || that_present_columns) { + if (!(this_present_columns && that_present_columns)) + return false; + if (!this.columns.equals(that.columns)) + return false; + } + + return true; + } + + @Override + public int hashCode() { + HashCodeBuilder builder = new HashCodeBuilder(); + + boolean present_name = true && (isSetName()); + builder.append(present_name); + if (present_name) + builder.append(name); + + boolean present_columns = true && (isSetColumns()); + builder.append(present_columns); + if (present_columns) + builder.append(columns); + + return builder.toHashCode(); + } + + public int compareTo(CounterSuperColumn other) { + if (!getClass().equals(other.getClass())) { + return getClass().getName().compareTo(other.getClass().getName()); + } + + int lastComparison = 0; + CounterSuperColumn typedOther = (CounterSuperColumn)other; + + lastComparison = Boolean.valueOf(isSetName()).compareTo(typedOther.isSetName()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetName()) { + lastComparison = TBaseHelper.compareTo(this.name, typedOther.name); + if (lastComparison != 0) { + return lastComparison; + } + } + lastComparison = Boolean.valueOf(isSetColumns()).compareTo(typedOther.isSetColumns()); + if (lastComparison != 0) { + return lastComparison; + } + if (isSetColumns()) { + lastComparison = TBaseHelper.compareTo(this.columns, typedOther.columns); + if (lastComparison != 0) { + return lastComparison; + } + } + return 0; + } + + public _Fields fieldForId(int fieldId) { + return _Fields.findByThriftId(fieldId); + } + + public void read(TProtocol iprot) throws TException { + TField field; + iprot.readStructBegin(); + while (true) + { + field = iprot.readFieldBegin(); + if (field.type == TType.STOP) { + break; + } + switch (field.id) { + case 1: // NAME + if (field.type == TType.STRING) { + this.name = iprot.readBinary(); + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + case 2: // COLUMNS + if (field.type == TType.LIST) { + { + TList _list4 = iprot.readListBegin(); + this.columns = new ArrayList(_list4.size); + for (int _i5 = 0; _i5 < _list4.size; ++_i5) + { + CounterColumn _elem6; + _elem6 = new CounterColumn(); + _elem6.read(iprot); + this.columns.add(_elem6); + } + iprot.readListEnd(); + } + } else { + TProtocolUtil.skip(iprot, field.type); + } + break; + default: + TProtocolUtil.skip(iprot, field.type); + } + iprot.readFieldEnd(); + } + iprot.readStructEnd(); + + // check for required fields of primitive type, which can't be checked in the validate method + validate(); + } + + public void write(TProtocol oprot) throws TException { + validate(); + + oprot.writeStructBegin(STRUCT_DESC); + if (this.name != null) { + oprot.writeFieldBegin(NAME_FIELD_DESC); + oprot.writeBinary(this.name); + oprot.writeFieldEnd(); + } + if (this.columns != null) { + oprot.writeFieldBegin(COLUMNS_FIELD_DESC); + { + oprot.writeListBegin(new TList(TType.STRUCT, this.columns.size())); + for (CounterColumn _iter7 : this.columns) + { + _iter7.write(oprot); + } + oprot.writeListEnd(); + } + oprot.writeFieldEnd(); + } + oprot.writeFieldStop(); + oprot.writeStructEnd(); + } + + @Override + public String toString() { + StringBuilder sb = new StringBuilder("CounterSuperColumn("); + boolean first = true; + + sb.append("name:"); + if (this.name == null) { + sb.append("null"); + } else { + TBaseHelper.toString(this.name, sb); + } + first = false; + if (!first) sb.append(", "); + sb.append("columns:"); + if (this.columns == null) { + sb.append("null"); + } else { + sb.append(this.columns); + } + first = false; + sb.append(")"); + return sb.toString(); + } + + public void validate() throws TException { + // check for required fields + if (name == null) { + throw new TProtocolException("Required field 'name' was not present! Struct: " + toString()); + } + if (columns == null) { + throw new TProtocolException("Required field 'columns' was not present! Struct: " + toString()); + } + } + +} + diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/IndexClause.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/IndexClause.java index 98f5f58b33..91f1563a13 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/IndexClause.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/IndexClause.java @@ -470,14 +470,14 @@ public class IndexClause implements TBase, jav case 1: // EXPRESSIONS if (field.type == TType.LIST) { { - TList _list8 = iprot.readListBegin(); - this.expressions = new ArrayList(_list8.size); - for (int _i9 = 0; _i9 < _list8.size; ++_i9) + TList _list12 = iprot.readListBegin(); + this.expressions = new ArrayList(_list12.size); + for (int _i13 = 0; _i13 < _list12.size; ++_i13) { - IndexExpression _elem10; - _elem10 = new IndexExpression(); - _elem10.read(iprot); - this.expressions.add(_elem10); + IndexExpression _elem14; + _elem14 = new IndexExpression(); + _elem14.read(iprot); + this.expressions.add(_elem14); } iprot.readListEnd(); } @@ -522,9 +522,9 @@ public class IndexClause implements TBase, jav oprot.writeFieldBegin(EXPRESSIONS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.expressions.size())); - for (IndexExpression _iter11 : this.expressions) + for (IndexExpression _iter15 : this.expressions) { - _iter11.write(oprot); + _iter15.write(oprot); } oprot.writeListEnd(); } diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/KeySlice.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/KeySlice.java index b105dce479..99e78c4476 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/KeySlice.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/KeySlice.java @@ -405,14 +405,14 @@ public class KeySlice implements TBase, java.io.Seri case 2: // COLUMNS if (field.type == TType.LIST) { { - TList _list12 = iprot.readListBegin(); - this.columns = new ArrayList(_list12.size); - for (int _i13 = 0; _i13 < _list12.size; ++_i13) + TList _list16 = iprot.readListBegin(); + this.columns = new ArrayList(_list16.size); + for (int _i17 = 0; _i17 < _list16.size; ++_i17) { - ColumnOrSuperColumn _elem14; - _elem14 = new ColumnOrSuperColumn(); - _elem14.read(iprot); - this.columns.add(_elem14); + ColumnOrSuperColumn _elem18; + _elem18 = new ColumnOrSuperColumn(); + _elem18.read(iprot); + this.columns.add(_elem18); } iprot.readListEnd(); } @@ -444,9 +444,9 @@ public class KeySlice implements TBase, java.io.Seri oprot.writeFieldBegin(COLUMNS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.columns.size())); - for (ColumnOrSuperColumn _iter15 : this.columns) + for (ColumnOrSuperColumn _iter19 : this.columns) { - _iter15.write(oprot); + _iter19.write(oprot); } oprot.writeListEnd(); } diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/KsDef.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/KsDef.java index 65e13c10ac..df95d19bbc 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/KsDef.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/KsDef.java @@ -642,15 +642,15 @@ public class KsDef implements TBase, java.io.Serializable, case 3: // STRATEGY_OPTIONS if (field.type == TType.MAP) { { - TMap _map29 = iprot.readMapBegin(); - this.strategy_options = new HashMap(2*_map29.size); - for (int _i30 = 0; _i30 < _map29.size; ++_i30) + TMap _map33 = iprot.readMapBegin(); + this.strategy_options = new HashMap(2*_map33.size); + for (int _i34 = 0; _i34 < _map33.size; ++_i34) { - String _key31; - String _val32; - _key31 = iprot.readString(); - _val32 = iprot.readString(); - this.strategy_options.put(_key31, _val32); + String _key35; + String _val36; + _key35 = iprot.readString(); + _val36 = iprot.readString(); + this.strategy_options.put(_key35, _val36); } iprot.readMapEnd(); } @@ -669,14 +669,14 @@ public class KsDef implements TBase, java.io.Serializable, case 5: // CF_DEFS if (field.type == TType.LIST) { { - TList _list33 = iprot.readListBegin(); - this.cf_defs = new ArrayList(_list33.size); - for (int _i34 = 0; _i34 < _list33.size; ++_i34) + TList _list37 = iprot.readListBegin(); + this.cf_defs = new ArrayList(_list37.size); + for (int _i38 = 0; _i38 < _list37.size; ++_i38) { - CfDef _elem35; - _elem35 = new CfDef(); - _elem35.read(iprot); - this.cf_defs.add(_elem35); + CfDef _elem39; + _elem39 = new CfDef(); + _elem39.read(iprot); + this.cf_defs.add(_elem39); } iprot.readListEnd(); } @@ -717,10 +717,10 @@ public class KsDef implements TBase, java.io.Serializable, oprot.writeFieldBegin(STRATEGY_OPTIONS_FIELD_DESC); { oprot.writeMapBegin(new TMap(TType.STRING, TType.STRING, this.strategy_options.size())); - for (Map.Entry _iter36 : this.strategy_options.entrySet()) + for (Map.Entry _iter40 : this.strategy_options.entrySet()) { - oprot.writeString(_iter36.getKey()); - oprot.writeString(_iter36.getValue()); + oprot.writeString(_iter40.getKey()); + oprot.writeString(_iter40.getValue()); } oprot.writeMapEnd(); } @@ -734,9 +734,9 @@ public class KsDef implements TBase, java.io.Serializable, oprot.writeFieldBegin(CF_DEFS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRUCT, this.cf_defs.size())); - for (CfDef _iter37 : this.cf_defs) + for (CfDef _iter41 : this.cf_defs) { - _iter37.write(oprot); + _iter41.write(oprot); } oprot.writeListEnd(); } diff --git a/interface/thrift/gen-java/org/apache/cassandra/thrift/SlicePredicate.java b/interface/thrift/gen-java/org/apache/cassandra/thrift/SlicePredicate.java index b458740031..01a254adb3 100644 --- a/interface/thrift/gen-java/org/apache/cassandra/thrift/SlicePredicate.java +++ b/interface/thrift/gen-java/org/apache/cassandra/thrift/SlicePredicate.java @@ -385,13 +385,13 @@ public class SlicePredicate implements TBase(_list4.size); - for (int _i5 = 0; _i5 < _list4.size; ++_i5) + TList _list8 = iprot.readListBegin(); + this.column_names = new ArrayList(_list8.size); + for (int _i9 = 0; _i9 < _list8.size; ++_i9) { - ByteBuffer _elem6; - _elem6 = iprot.readBinary(); - this.column_names.add(_elem6); + ByteBuffer _elem10; + _elem10 = iprot.readBinary(); + this.column_names.add(_elem10); } iprot.readListEnd(); } @@ -427,9 +427,9 @@ public class SlicePredicate implements TBase, java.i case 3: // ENDPOINTS if (field.type == TType.LIST) { { - TList _list16 = iprot.readListBegin(); - this.endpoints = new ArrayList(_list16.size); - for (int _i17 = 0; _i17 < _list16.size; ++_i17) + TList _list20 = iprot.readListBegin(); + this.endpoints = new ArrayList(_list20.size); + for (int _i21 = 0; _i21 < _list20.size; ++_i21) { - String _elem18; - _elem18 = iprot.readString(); - this.endpoints.add(_elem18); + String _elem22; + _elem22 = iprot.readString(); + this.endpoints.add(_elem22); } iprot.readListEnd(); } @@ -511,9 +511,9 @@ public class TokenRange implements TBase, java.i oprot.writeFieldBegin(ENDPOINTS_FIELD_DESC); { oprot.writeListBegin(new TList(TType.STRING, this.endpoints.size())); - for (String _iter19 : this.endpoints) + for (String _iter23 : this.endpoints) { - oprot.writeString(_iter19); + oprot.writeString(_iter23); } oprot.writeListEnd(); } diff --git a/src/java/org/apache/cassandra/avro/CassandraServer.java b/src/java/org/apache/cassandra/avro/CassandraServer.java index ece781e395..e9264489fb 100644 --- a/src/java/org/apache/cassandra/avro/CassandraServer.java +++ b/src/java/org/apache/cassandra/avro/CassandraServer.java @@ -88,7 +88,6 @@ public class CassandraServer implements Cassandra { // CfDef default values private final static String D_CF_CFTYPE = "Standard"; - private final static String D_CF_CFCLOCKTYPE = "Timestamp"; private final static String D_CF_COMPTYPE = "BytesType"; private final static String D_CF_SUBCOMPTYPE = ""; private final static String D_CF_RECONCILER = null; @@ -837,6 +836,7 @@ public class CassandraServer implements Cassandra { cf_def.row_cache_size == null ? CFMetaData.DEFAULT_ROW_CACHE_SIZE : cf_def.row_cache_size, cf_def.key_cache_size == null ? CFMetaData.DEFAULT_KEY_CACHE_SIZE : cf_def.key_cache_size, cf_def.read_repair_chance == null ? CFMetaData.DEFAULT_READ_REPAIR_CHANCE : cf_def.read_repair_chance, + cf_def.replicate_on_write == null ? CFMetaData.DEFAULT_REPLICATE_ON_WRITE : cf_def.replicate_on_write, cf_def.gc_grace_seconds != null ? cf_def.gc_grace_seconds : CFMetaData.DEFAULT_GC_GRACE_SECONDS, DatabaseDescriptor.getComparator(validate), cf_def.min_compaction_threshold == null ? CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD : cf_def.min_compaction_threshold, diff --git a/src/java/org/apache/cassandra/concurrent/Stage.java b/src/java/org/apache/cassandra/concurrent/Stage.java index 924f413ac5..a96bb9e46f 100644 --- a/src/java/org/apache/cassandra/concurrent/Stage.java +++ b/src/java/org/apache/cassandra/concurrent/Stage.java @@ -31,7 +31,8 @@ public enum Stage ANTI_ENTROPY, MIGRATION, MISC, - INTERNAL_RESPONSE; + INTERNAL_RESPONSE, + REPLICATE_ON_WRITE; public String getJmxType() { @@ -47,6 +48,7 @@ public enum Stage case MUTATION: case READ: case REQUEST_RESPONSE: + case REPLICATE_ON_WRITE: return "request"; default: throw new AssertionError("Unknown stage " + this); diff --git a/src/java/org/apache/cassandra/concurrent/StageManager.java b/src/java/org/apache/cassandra/concurrent/StageManager.java index e4a0a7d3e5..699539dcea 100644 --- a/src/java/org/apache/cassandra/concurrent/StageManager.java +++ b/src/java/org/apache/cassandra/concurrent/StageManager.java @@ -25,6 +25,7 @@ import java.util.concurrent.TimeUnit; import static org.apache.cassandra.config.DatabaseDescriptor.getConcurrentReaders; import static org.apache.cassandra.config.DatabaseDescriptor.getConcurrentWriters; +import static org.apache.cassandra.config.DatabaseDescriptor.getConcurrentReplicators; /** @@ -44,6 +45,7 @@ public class StageManager stages.put(Stage.READ, multiThreadedConfigurableStage(Stage.READ, getConcurrentReaders())); stages.put(Stage.REQUEST_RESPONSE, multiThreadedStage(Stage.REQUEST_RESPONSE, Math.max(2, Runtime.getRuntime().availableProcessors()))); stages.put(Stage.INTERNAL_RESPONSE, multiThreadedStage(Stage.INTERNAL_RESPONSE, Math.max(2, Runtime.getRuntime().availableProcessors()))); + stages.put(Stage.REPLICATE_ON_WRITE, multiThreadedConfigurableStage(Stage.REPLICATE_ON_WRITE, getConcurrentReplicators())); // the rest are all single-threaded stages.put(Stage.STREAM, new JMXEnabledThreadPoolExecutor(Stage.STREAM)); stages.put(Stage.GOSSIP, new JMXEnabledThreadPoolExecutor(Stage.GOSSIP)); diff --git a/src/java/org/apache/cassandra/config/CFMetaData.java b/src/java/org/apache/cassandra/config/CFMetaData.java index f782b401a3..a19dc4ad61 100644 --- a/src/java/org/apache/cassandra/config/CFMetaData.java +++ b/src/java/org/apache/cassandra/config/CFMetaData.java @@ -58,6 +58,7 @@ public final class CFMetaData public final static double DEFAULT_ROW_CACHE_SIZE = 0.0; public final static double DEFAULT_KEY_CACHE_SIZE = 200000; public final static double DEFAULT_READ_REPAIR_CHANCE = 1.0; + public final static boolean DEFAULT_REPLICATE_ON_WRITE = true; public final static int DEFAULT_ROW_CACHE_SAVE_PERIOD_IN_SECONDS = 0; public final static int DEFAULT_KEY_CACHE_SAVE_PERIOD_IN_SECONDS = 3600; public final static int DEFAULT_GC_GRACE_SECONDS = 864000; @@ -90,6 +91,7 @@ public final class CFMetaData 0, 0.01, 0, + false, 0, BytesType.instance, DEFAULT_MIN_COMPACTION_THRESHOLD, @@ -155,6 +157,7 @@ public final class CFMetaData private double rowCacheSize; // default 0 private double keyCacheSize; // default 0.01 private double readRepairChance; // default 1.0 (always), chance [0.0,1.0] of read repair + private boolean replicateOnWrite; // default false private int gcGraceSeconds; // default 864000 (ten days) private AbstractType defaultValidator; // default none, use comparator types private Integer minCompactionThreshold; // default 4 @@ -177,6 +180,7 @@ public final class CFMetaData double rowCacheSize, double keyCacheSize, double readRepairChance, + boolean replicateOnWrite, int gcGraceSeconds, AbstractType defaultValidator, int minCompactionThreshold, @@ -204,6 +208,7 @@ public final class CFMetaData this.rowCacheSize = rowCacheSize; this.keyCacheSize = keyCacheSize; this.readRepairChance = readRepairChance; + this.replicateOnWrite = replicateOnWrite; this.gcGraceSeconds = gcGraceSeconds; this.defaultValidator = defaultValidator; this.minCompactionThreshold = minCompactionThreshold; @@ -242,6 +247,7 @@ public final class CFMetaData double rowCacheSize, double keyCacheSize, double readRepairChance, + boolean replicateOnWrite, int gcGraceSeconds, AbstractType defaultValidator, int minCompactionThreshold, @@ -263,6 +269,7 @@ public final class CFMetaData rowCacheSize, keyCacheSize, readRepairChance, + replicateOnWrite, gcGraceSeconds, defaultValidator, minCompactionThreshold, @@ -287,6 +294,7 @@ public final class CFMetaData 0, 0, 0, + false, DEFAULT_GC_GRACE_SECONDS, BytesType.instance, DEFAULT_MIN_COMPACTION_THRESHOLD, @@ -311,6 +319,7 @@ public final class CFMetaData cfm.rowCacheSize, cfm.keyCacheSize, cfm.readRepairChance, + cfm.replicateOnWrite, cfm.gcGraceSeconds, cfm.defaultValidator, cfm.minCompactionThreshold, @@ -336,6 +345,7 @@ public final class CFMetaData cfm.rowCacheSize, cfm.keyCacheSize, cfm.readRepairChance, + cfm.replicateOnWrite, cfm.gcGraceSeconds, cfm.defaultValidator, cfm.minCompactionThreshold, @@ -369,6 +379,7 @@ public final class CFMetaData cf.row_cache_size = rowCacheSize; cf.key_cache_size = keyCacheSize; cf.read_repair_chance = readRepairChance; + cf.replicate_on_write = replicateOnWrite; cf.gc_grace_seconds = gcGraceSeconds; cf.default_validation_class = new Utf8(defaultValidator.getClass().getName()); cf.min_compaction_threshold = minCompactionThreshold; @@ -428,6 +439,7 @@ public final class CFMetaData cf.row_cache_size, cf.key_cache_size, cf.read_repair_chance, + cf.replicate_on_write, cf.gc_grace_seconds, validator, minct, @@ -460,6 +472,11 @@ public final class CFMetaData { return readRepairChance; } + + public boolean getReplicateOnWrite() + { + return replicateOnWrite; + } public int getGcGraceSeconds() { @@ -533,6 +550,7 @@ public final class CFMetaData .append(rowCacheSize, rhs.rowCacheSize) .append(keyCacheSize, rhs.keyCacheSize) .append(readRepairChance, rhs.readRepairChance) + .append(replicateOnWrite, rhs.replicateOnWrite) .append(gcGraceSeconds, rhs.gcGraceSeconds) .append(minCompactionThreshold, rhs.minCompactionThreshold) .append(maxCompactionThreshold, rhs.maxCompactionThreshold) @@ -558,6 +576,7 @@ public final class CFMetaData .append(rowCacheSize) .append(keyCacheSize) .append(readRepairChance) + .append(replicateOnWrite) .append(gcGraceSeconds) .append(defaultValidator) .append(minCompactionThreshold) @@ -654,6 +673,7 @@ public final class CFMetaData rowCacheSize = cf_def.row_cache_size; keyCacheSize = cf_def.key_cache_size; readRepairChance = cf_def.read_repair_chance; + replicateOnWrite = cf_def.replicate_on_write; gcGraceSeconds = cf_def.gc_grace_seconds; defaultValidator = DatabaseDescriptor.getComparator(cf_def.default_validation_class); minCompactionThreshold = cf_def.min_compaction_threshold; @@ -716,6 +736,7 @@ public final class CFMetaData def.setRow_cache_size(cfm.rowCacheSize); def.setKey_cache_size(cfm.keyCacheSize); def.setRead_repair_chance(cfm.readRepairChance); + def.setReplicate_on_write(cfm.replicateOnWrite); def.setGc_grace_seconds(cfm.gcGraceSeconds); def.setDefault_validation_class(cfm.defaultValidator.getClass().getName()); def.setMin_compaction_threshold(cfm.minCompactionThreshold); @@ -757,6 +778,7 @@ public final class CFMetaData def.row_cache_size = cfm.rowCacheSize; def.key_cache_size = cfm.keyCacheSize; def.read_repair_chance = cfm.readRepairChance; + def.replicate_on_write = cfm.replicateOnWrite; def.gc_grace_seconds = cfm.gcGraceSeconds; def.default_validation_class = cfm.defaultValidator == null ? null : cfm.defaultValidator.getClass().getName(); def.min_compaction_threshold = cfm.minCompactionThreshold; @@ -799,6 +821,7 @@ public final class CFMetaData newDef.memtable_throughput_in_mb = def.getMemtable_throughput_in_mb(); newDef.min_compaction_threshold = def.getMin_compaction_threshold(); newDef.read_repair_chance = def.getRead_repair_chance(); + newDef.replicate_on_write = def.isReplicate_on_write(); newDef.row_cache_save_period_in_seconds = def.getRow_cache_save_period_in_seconds(); newDef.row_cache_size = def.getRow_cache_size(); newDef.subcomparator_type = def.getSubcomparator_type(); @@ -917,6 +940,7 @@ public final class CFMetaData .append("rowCacheSize", rowCacheSize) .append("keyCacheSize", keyCacheSize) .append("readRepairChance", readRepairChance) + .append("replicateOnWrite", replicateOnWrite) .append("gcGraceSeconds", gcGraceSeconds) .append("defaultValidator", defaultValidator) .append("minCompactionThreshold", minCompactionThreshold) diff --git a/src/java/org/apache/cassandra/config/Config.java b/src/java/org/apache/cassandra/config/Config.java index ccf04f6dbd..3ee494f082 100644 --- a/src/java/org/apache/cassandra/config/Config.java +++ b/src/java/org/apache/cassandra/config/Config.java @@ -53,6 +53,7 @@ public class Config public Integer concurrent_reads = 8; public Integer concurrent_writes = 32; + public Integer concurrent_replicates = 32; public Integer memtable_flush_writers = null; // will get set to the length of data dirs in DatabaseDescriptor diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java index 7f59afc5c2..f85ded7371 100644 --- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java +++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java @@ -224,6 +224,11 @@ public class DatabaseDescriptor throw new ConfigurationException("concurrent_writes must be at least 2"); } + if (conf.concurrent_replicates != null && conf.concurrent_replicates < 2) + { + throw new ConfigurationException("conf.concurrent_replicates must be at least 2"); + } + /* Memtable flush writer threads */ if (conf.memtable_flush_writers != null && conf.memtable_flush_writers < 1) { @@ -613,6 +618,7 @@ public class DatabaseDescriptor cf.rows_cached, cf.keys_cached, cf.read_repair_chance, + cf.replicate_on_write, cf.gc_grace_seconds, default_validator, cf.min_compaction_threshold, @@ -841,6 +847,11 @@ public class DatabaseDescriptor return conf.concurrent_writes; } + public static int getConcurrentReplicators() + { + return conf.concurrent_replicates; + } + public static int getFlushWriters() { return conf.memtable_flush_writers; diff --git a/src/java/org/apache/cassandra/config/RawColumnFamily.java b/src/java/org/apache/cassandra/config/RawColumnFamily.java index 62f54c59fe..ca7138c01f 100644 --- a/src/java/org/apache/cassandra/config/RawColumnFamily.java +++ b/src/java/org/apache/cassandra/config/RawColumnFamily.java @@ -36,6 +36,7 @@ public class RawColumnFamily public double rows_cached = CFMetaData.DEFAULT_ROW_CACHE_SIZE; public double keys_cached = CFMetaData.DEFAULT_KEY_CACHE_SIZE; public double read_repair_chance = CFMetaData.DEFAULT_READ_REPAIR_CHANCE; + public boolean replicate_on_write = CFMetaData.DEFAULT_REPLICATE_ON_WRITE; public int gc_grace_seconds = CFMetaData.DEFAULT_GC_GRACE_SECONDS; public String default_validation_class; public int min_compaction_threshold = CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD; diff --git a/src/java/org/apache/cassandra/db/ColumnFamily.java b/src/java/org/apache/cassandra/db/ColumnFamily.java index eb574dbc64..3c75fe634e 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamily.java +++ b/src/java/org/apache/cassandra/db/ColumnFamily.java @@ -33,6 +33,7 @@ import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.filter.QueryPath; import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; import org.apache.cassandra.io.ICompactSerializer2; import org.apache.cassandra.io.util.IIterableColumns; import org.apache.cassandra.utils.FBUtilities; @@ -154,18 +155,25 @@ public class ColumnFamily implements IColumnContainer, IIterableColumns public void addColumn(QueryPath path, ByteBuffer value, long timestamp) { - assert path.columnName != null : path; - addColumn(path.superColumnName, new Column(path.columnName, value, timestamp)); + addColumn(path, value, timestamp, 0); } public void addColumn(QueryPath path, ByteBuffer value, long timestamp, int timeToLive) { assert path.columnName != null : path; Column column; - if (timeToLive > 0) - column = new ExpiringColumn(path.columnName, value, timestamp, timeToLive); + AbstractType defaultValidator = metadata().getDefaultValidator(); + if (!defaultValidator.isCommutative()) + { + if (timeToLive > 0) + column = new ExpiringColumn(path.columnName, value, timestamp, timeToLive); + else + column = new Column(path.columnName, value, timestamp); + } else - column = new Column(path.columnName, value, timestamp); + { + column = ((AbstractCommutativeType)defaultValidator).createColumn(path.columnName, value, timestamp); + } addColumn(path.superColumnName, column); } diff --git a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java index a128cfa7ee..03455c7cce 100644 --- a/src/java/org/apache/cassandra/db/ColumnFamilyStore.java +++ b/src/java/org/apache/cassandra/db/ColumnFamilyStore.java @@ -25,6 +25,7 @@ import java.util.*; import java.util.concurrent.*; import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicReference; +import java.util.concurrent.locks.ReentrantReadWriteLock; import java.util.regex.Pattern; import javax.management.MBeanServer; import javax.management.ObjectName; @@ -292,6 +293,42 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean return keys; } + public boolean reverseReadWriteOrder() + { + //XXX: PURPOSE: allow less harmful race condition w/o locking + + // normal read/write order (non-commutative): + // purpose: + // avoid missing an MT; may double reconcile + // read path order: + // 1) live MT + // 2) MTs pending flush + // 3) SSTs + // write path order: (live MT => MT pending flush) + // 1) add live MT to MTs pending flush + // 2) reset live MT + // write path order: (MT pending flush => SST) + // 1) add SST + // 2) remove MT pending flush + + // reversed read/write order (commutative): + // purpose: + // avoid over-counting an MT; may miss an MT + // read path order: + // 1) SSTs + // 2) MTs pending flush + // 3) live MT + // write path order: (live MT => MT pending flush) + // 1) save live MT + // 2) reset live MT + // 3) add saved MT to MTs pending flush + // write path order: (MT pending flush => SST) + // 1) remove MT pending flush + // 2) add SST + + return metadata.getDefaultValidator().isCommutative(); + } + public void addIndex(final ColumnDefinition info) { assert info.getIndexType() != null; @@ -650,8 +687,19 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean final CountDownLatch latch = new CountDownLatch(icc.size()); for (ColumnFamilyStore cfs : icc) { - submitFlush(cfs.memtable, latch); - cfs.memtable = new Memtable(cfs); + if (!reverseReadWriteOrder()) + { + //XXX: race condition: may allow double reconcile; but never misses an MT + submitFlush(cfs.memtable, latch); + cfs.memtable = new Memtable(cfs); + } + else + { + //XXX: race condition: may miss an MT, but no double counts + Memtable pendingFlush = cfs.memtable; + cfs.memtable = new Memtable(cfs); + submitFlush(pendingFlush, latch); + } } // when all the memtables have been written, including for indexes, mark the flush in the commitlog header. @@ -793,7 +841,6 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean // remove columns if // (a) the column itself is tombstoned or // (b) the CF is tombstoned and the column is not newer than it - // (we split the test to avoid computing ClockRelationship if not necessary) if ((c.isMarkedForDelete() && c.getLocalDeletionTime() <= gcBefore) || c.timestamp() <= cf.getMarkedForDeleteAt()) { @@ -1180,36 +1227,75 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean { IColumnIterator iter; - /* add the current memtable */ - iter = filter.getMemtableColumnIterator(getMemtableThreadSafe(), getComparator()); - if (iter != null) + int sstablesToIterate = 0; + if (!reverseReadWriteOrder()) { - returnCF.delete(iter.getColumnFamily()); - - iterators.add(iter); - } + //XXX: race condition: may allow double reconcile; but never misses an MT - /* add the memtables being flushed */ - for (Memtable memtable : memtablesPendingFlush) - { - iter = filter.getMemtableColumnIterator(memtable, getComparator()); + /* add the current memtable */ + iter = filter.getMemtableColumnIterator(getMemtableThreadSafe(), getComparator()); if (iter != null) { returnCF.delete(iter.getColumnFamily()); iterators.add(iter); } - } - /* add the SSTables on disk */ - int sstablesToIterate = 0; - for (SSTableReader sstable : ssTables) + /* add the memtables being flushed */ + for (Memtable memtable : memtablesPendingFlush) + { + iter = filter.getMemtableColumnIterator(memtable, getComparator()); + if (iter != null) + { + returnCF.delete(iter.getColumnFamily()); + iterators.add(iter); + } + } + + /* add the SSTables on disk */ + for (SSTableReader sstable : ssTables) + { + iter = filter.getSSTableColumnIterator(sstable); + if (iter.getColumnFamily() != null) + { + returnCF.delete(iter.getColumnFamily()); + iterators.add(iter); + } + sstablesToIterate++; + } + } + else { - iter = filter.getSSTableColumnIterator(sstable); - if (iter.getColumnFamily() != null) + //XXX: race condition: may miss an MT, but no double counts + + /* add the SSTables on disk */ + for (SSTableReader sstable : ssTables) + { + iter = filter.getSSTableColumnIterator(sstable); + if (iter.getColumnFamily() != null) + { + returnCF.delete(iter.getColumnFamily()); + iterators.add(iter); + } + sstablesToIterate++; + } + + /* add the memtables being flushed */ + for (Memtable memtable : memtablesPendingFlush) + { + iter = filter.getMemtableColumnIterator(memtable, getComparator()); + if (iter != null) + { + returnCF.delete(iter.getColumnFamily()); + iterators.add(iter); + } + } + + /* add the current memtable */ + iter = filter.getMemtableColumnIterator(getMemtableThreadSafe(), getComparator()); + if (iter != null) { returnCF.delete(iter.getColumnFamily()); iterators.add(iter); - sstablesToIterate++; } } recentSSTablesPerRead.add(sstablesToIterate); @@ -1270,12 +1356,23 @@ public class ColumnFamilyStore implements ColumnFamilyStoreMBean QueryFilter filter = new QueryFilter(null, new QueryPath(columnFamily, superColumn, null), columnFilter); Collection memtables = new ArrayList(); - memtables.add(getMemtableThreadSafe()); - memtables.addAll(memtablesPendingFlush); - Collection sstables = new ArrayList(); - Iterables.addAll(sstables, ssTables); + if (!reverseReadWriteOrder()) + { + //XXX: race condition: may allow double reconcile; but never misses an MT + memtables.add(getMemtableThreadSafe()); + memtables.addAll(memtablesPendingFlush); + Iterables.addAll(sstables, ssTables); + } + else + { + //XXX: race condition: may miss an MT, but no double counts + Iterables.addAll(sstables, ssTables); + memtables.addAll(memtablesPendingFlush); + memtables.add(getMemtableThreadSafe()); + } + RowIterator iterator = RowIteratorFactory.getIterator(memtables, sstables, startWith, stopAt, filter, getComparator(), this); int gcBefore = (int)(System.currentTimeMillis() / 1000) - metadata.getGcGraceSeconds(); diff --git a/src/java/org/apache/cassandra/db/ColumnSerializer.java b/src/java/org/apache/cassandra/db/ColumnSerializer.java index d7d025e612..9c4e12c472 100644 --- a/src/java/org/apache/cassandra/db/ColumnSerializer.java +++ b/src/java/org/apache/cassandra/db/ColumnSerializer.java @@ -25,6 +25,7 @@ import java.io.DataInput; import java.io.DataOutput; import java.io.IOException; import java.nio.ByteBuffer; +import java.util.Arrays; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -35,9 +36,10 @@ import org.apache.cassandra.utils.FBUtilities; public class ColumnSerializer implements ICompactSerializer2 { private static final Logger logger = LoggerFactory.getLogger(ColumnSerializer.class); - + public final static int DELETION_MASK = 0x01; public final static int EXPIRATION_MASK = 0x02; + public final static int COUNTER_MASK = 0x04; public void serialize(IColumn column, DataOutput dos) { @@ -45,12 +47,21 @@ public class ColumnSerializer implements ICompactSerializer2 FBUtilities.writeShortByteArray(column.name(), dos); try { - if (column instanceof ExpiringColumn) { - dos.writeByte(EXPIRATION_MASK); - dos.writeInt(((ExpiringColumn) column).getTimeToLive()); - dos.writeInt(column.getLocalDeletionTime()); - } else { - dos.writeByte((column.isMarkedForDelete()) ? DELETION_MASK : 0); + if (column instanceof CounterColumn) + { + dos.writeByte(COUNTER_MASK); + dos.writeLong(((CounterColumn)column).timestampOfLastDelete()); + FBUtilities.writeShortByteArray(ByteBuffer.wrap(((CounterColumn)column).partitionedCounter()), dos); + } + else if (column instanceof ExpiringColumn) + { + dos.writeByte(EXPIRATION_MASK); + dos.writeInt(((ExpiringColumn) column).getTimeToLive()); + dos.writeInt(column.getLocalDeletionTime()); + } + else + { + dos.writeByte((column.isMarkedForDelete()) ? DELETION_MASK : 0); } dos.writeLong(column.timestamp()); FBUtilities.writeByteArray(column.value(), dos); @@ -68,7 +79,16 @@ public class ColumnSerializer implements ICompactSerializer2 throw new CorruptColumnException("invalid column name length " + name.remaining()); int b = dis.readUnsignedByte(); - if ((b & EXPIRATION_MASK) != 0) + if ((b & COUNTER_MASK) != 0) + { + long timestampOfLastDelete = dis.readLong(); + ByteBuffer pc = FBUtilities.readShortByteArray(dis); + byte[] partitionedCounter = Arrays.copyOfRange(pc.array(), pc.position() + pc.arrayOffset(), pc.limit()); + long timestamp = dis.readLong(); + ByteBuffer value = FBUtilities.readByteArray(dis); + return new CounterColumn(name, value, timestamp, partitionedCounter, timestampOfLastDelete); + } + else if ((b & EXPIRATION_MASK) != 0) { int ttl = dis.readInt(); int expiration = dis.readInt(); diff --git a/src/java/org/apache/cassandra/db/CompactionManager.java b/src/java/org/apache/cassandra/db/CompactionManager.java index 23dbbf5d56..10100383fa 100644 --- a/src/java/org/apache/cassandra/db/CompactionManager.java +++ b/src/java/org/apache/cassandra/db/CompactionManager.java @@ -52,6 +52,7 @@ import org.apache.cassandra.io.sstable.*; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.service.AntiEntropyService; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.Pair; import org.cliffc.high_scale_lib.NonBlockingHashMap; @@ -595,11 +596,11 @@ public class CompactionManager implements CompactionManagerMBean else return executor.submit(runnable); } - - public Future submitSSTableBuild(Descriptor desc) + + public Future submitSSTableBuild(Descriptor desc, OperationType type) { // invalid descriptions due to missing or dropped CFS are handled by SSTW and StreamInSession. - final SSTableWriter.Builder builder = SSTableWriter.createBuilder(desc); + final SSTableWriter.Builder builder = SSTableWriter.createBuilder(desc, type); Callable callable = new Callable() { public SSTableReader call() throws IOException diff --git a/src/java/org/apache/cassandra/db/CounterColumn.java b/src/java/org/apache/cassandra/db/CounterColumn.java new file mode 100644 index 0000000000..bfe52e6e4b --- /dev/null +++ b/src/java/org/apache/cassandra/db/CounterColumn.java @@ -0,0 +1,287 @@ +/** + * 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.db; + +import java.io.IOException; +import java.net.InetAddress; +import java.nio.ByteBuffer; +import java.security.MessageDigest; +import java.util.Arrays; + +import org.apache.log4j.Logger; + +import org.apache.cassandra.db.context.CounterContext; +import org.apache.cassandra.db.context.IContext.ContextRelationship; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.io.util.DataOutputBuffer; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.FBUtilities; + +/** + * A column that represents a partitioned counter. + */ +public class CounterColumn extends Column +{ + private static Logger logger = Logger.getLogger(CounterColumn.class); + + private static CounterContext contextManager = CounterContext.instance(); + + protected ByteBuffer value; // NOT final: delta OR total of partitioned counter + protected byte[] partitionedCounter; // NOT final: only modify inline, carefully + protected final long timestampOfLastDelete; + + public CounterColumn(ByteBuffer name, ByteBuffer value, long timestamp) + { + this(name, value, timestamp, contextManager.create()); + } + + public CounterColumn(ByteBuffer name, ByteBuffer value, long timestamp, byte[] partitionedCounter) + { + this(name, value, timestamp, partitionedCounter, Long.MIN_VALUE); + } + + public CounterColumn(ByteBuffer name, ByteBuffer value, long timestamp, byte[] partitionedCounter, long timestampOfLastDelete) + { + super(name, FBUtilities.EMPTY_BYTE_BUFFER, timestamp); + this.value = value; + this.partitionedCounter = partitionedCounter; + this.timestampOfLastDelete = timestampOfLastDelete; + } + + @Override + public ByteBuffer value() + { + return value; + } + + public byte[] partitionedCounter() + { + return partitionedCounter; + } + + public long timestampOfLastDelete() + { + return timestampOfLastDelete; + } + + @Override + public int size() + { + /* + * An expired column adds to a Column : + * 4 bytes for length of partitionedCounter + * + length of partitionedCounter + * + 8 bytes for timestampOfLastDelete + */ + return super.size() + DBConstants.intSize_ + partitionedCounter.length + DBConstants.tsSize_; + } + + @Override + public IColumn diff(IColumn column) + { + assert column instanceof CounterColumn : "Wrong class type."; + + if (timestamp() < column.timestamp()) + return column; + if (timestampOfLastDelete() < ((CounterColumn)column).timestampOfLastDelete()) + return column; + ContextRelationship rel = contextManager.diff( + ((CounterColumn)column).partitionedCounter(), + partitionedCounter()); + if (ContextRelationship.GREATER_THAN == rel || ContextRelationship.DISJOINT == rel) + return column; + return null; + } + + @Override + public void updateDigest(MessageDigest digest) + { + digest.update(name.array(),name.position()+name.arrayOffset(),name.remaining()); + digest.update(value.array(),value.position()+name.arrayOffset(),value.remaining()); + digest.update(FBUtilities.toByteArray(timestamp)); + digest.update(partitionedCounter); + digest.update(FBUtilities.toByteArray(timestampOfLastDelete)); + } + + @Override + public IColumn reconcile(IColumn column) + { + assert (column instanceof CounterColumn) || (column instanceof DeletedColumn) : "Wrong class type."; + + if (isMarkedForDelete()) + { + if (column.isMarkedForDelete()) // tombstone + tombstone: keep later tombstone + { + return timestamp() > column.timestamp() ? this : column; + } + else // tombstone + live: track last tombstone + { + if (timestamp() > column.timestamp()) // tombstone > live + { + return this; + } + // tombstone <= live last delete + if (timestamp() <= ((CounterColumn)column).timestampOfLastDelete()) + { + return column; + } + // tombstone > live last delete + return new CounterColumn( + column.name(), + column.value(), + column.timestamp(), + ((CounterColumn)column).partitionedCounter(), + timestamp()); + } + } + else if (column.isMarkedForDelete()) // live + tombstone: track last tombstone + { + if (timestamp() < column.timestamp()) // live < tombstone + { + return column; + } + // live last delete >= tombstone + if (timestampOfLastDelete() >= column.timestamp()) + { + return this; + } + // live last delete < tombstone + return new CounterColumn( + name(), + value(), + timestamp(), + partitionedCounter(), + column.timestamp()); + } + // live + live: merge clocks; update value + byte[] mergedPartitionedCounter = contextManager.merge( + partitionedCounter(), + ((CounterColumn)column).partitionedCounter()); + ByteBuffer byteBufferValue; + if (0 == mergedPartitionedCounter.length) + { + long mergedValue = value().getLong(value().arrayOffset()) + + column.value().getLong(column.value().arrayOffset()); + byteBufferValue = FBUtilities.toByteBuffer(mergedValue); + } else + byteBufferValue = ByteBuffer.wrap(contextManager.total(mergedPartitionedCounter)); + return new CounterColumn( + name(), + byteBufferValue, + Math.max(timestamp(), column.timestamp()), + mergedPartitionedCounter, + Math.max(timestampOfLastDelete(), ((CounterColumn)column).timestampOfLastDelete())); + } + + @Override + public boolean equals(Object o) + { + if (this == o) + return true; + if (o == null || getClass() != o.getClass()) + return false; + + CounterColumn column = (CounterColumn)o; + + if (timestamp != column.timestamp) + return false; + + if (timestampOfLastDelete != column.timestampOfLastDelete) + return false; + + if (!Arrays.equals(partitionedCounter, column.partitionedCounter)) + return false; + + if (!name.equals(column.name)) + return false; + + return value.equals(column.value); + } + + @Override + public int hashCode() + { + int result = super.hashCode(); + result = 31 * result + (partitionedCounter != null ? Arrays.hashCode(partitionedCounter) : 0); + result = 31 * result + (int)(timestampOfLastDelete ^ (timestampOfLastDelete >>> 32)); + return result; + } + + @Override + public IColumn deepCopy() + { + return new CounterColumn( + ByteBufferUtil.clone(name), + ByteBufferUtil.clone(value), + timestamp, + partitionedCounter, + timestampOfLastDelete); + } + + @Override + public String getString(AbstractType comparator) + { + StringBuilder sb = new StringBuilder(); + sb.append(comparator.getString(name)); + sb.append(":"); + sb.append(isMarkedForDelete()); + sb.append(":"); + sb.append(value.getLong(value.arrayOffset())); + sb.append("@"); + sb.append(timestamp()); + sb.append("!"); + sb.append(timestampOfLastDelete); + sb.append("@"); + sb.append(contextManager.toString(partitionedCounter)); + return sb.toString(); + } + + private void updateValue() + { + value = ByteBuffer.wrap(contextManager.total(partitionedCounter)); + } + + public void update(InetAddress node) + { + long delta = value.getLong(value.arrayOffset()); + partitionedCounter = contextManager.update(partitionedCounter, node, delta); + updateValue(); + } + + public CounterColumn cleanNodeCounts(InetAddress node) + { + //XXX: inline modification non-destructive; cases: + // 1) AES post-stream + // 2) RRR, after CF.cloneMe() + // 3) RRR, after CF.diff() which creates a new CF + byte[] cleanPartitionedCounter = contextManager.cleanNodeCounts(partitionedCounter, node); + if (cleanPartitionedCounter == partitionedCounter) + return this; + if (0 == cleanPartitionedCounter.length) + return null; + return new CounterColumn( + name, + ByteBuffer.wrap(contextManager.total(cleanPartitionedCounter)), + timestamp, + cleanPartitionedCounter, + timestampOfLastDelete + ); + } +} + diff --git a/src/java/org/apache/cassandra/db/DeletedColumn.java b/src/java/org/apache/cassandra/db/DeletedColumn.java index 7af5af5190..8d64c8f353 100644 --- a/src/java/org/apache/cassandra/db/DeletedColumn.java +++ b/src/java/org/apache/cassandra/db/DeletedColumn.java @@ -56,6 +56,14 @@ public class DeletedColumn extends Column { return value.getInt(value.position()+value.arrayOffset() ); } + + @Override + public IColumn reconcile(IColumn column) + { + if (column instanceof DeletedColumn) + return super.reconcile(column); + return column.reconcile(this); + } @Override public IColumn deepCopy() diff --git a/src/java/org/apache/cassandra/db/IColumnContainer.java b/src/java/org/apache/cassandra/db/IColumnContainer.java index c22f1c8c46..6e2e4ac240 100644 --- a/src/java/org/apache/cassandra/db/IColumnContainer.java +++ b/src/java/org/apache/cassandra/db/IColumnContainer.java @@ -20,15 +20,20 @@ package org.apache.cassandra.db; * */ +import java.nio.ByteBuffer; +import java.util.Collection; import org.apache.cassandra.db.marshal.AbstractType; public interface IColumnContainer { public void addColumn(IColumn column); + public void remove(ByteBuffer columnName); public boolean isMarkedForDelete(); public long getMarkedForDeleteAt(); public AbstractType getComparator(); + + public Collection getSortedColumns(); } diff --git a/src/java/org/apache/cassandra/db/Memtable.java b/src/java/org/apache/cassandra/db/Memtable.java index e11388264d..0fe14b23bc 100644 --- a/src/java/org/apache/cassandra/db/Memtable.java +++ b/src/java/org/apache/cassandra/db/Memtable.java @@ -171,8 +171,18 @@ public class Memtable implements Comparable, IFlushable { public void runMayThrow() throws IOException { - cfs.addSSTable(writeSortedContents()); - cfs.getMemtablesPendingFlush().remove(Memtable.this); + if (!cfs.reverseReadWriteOrder()) + { + //XXX: race condition: may allow double reconcile; but never misses an MT + cfs.addSSTable(writeSortedContents()); + cfs.getMemtablesPendingFlush().remove(Memtable.this); + } + else + { + //XXX: race condition: may miss an MT, but no double counts + cfs.getMemtablesPendingFlush().remove(Memtable.this); + cfs.addSSTable(writeSortedContents()); + } latch.countDown(); } }); diff --git a/src/java/org/apache/cassandra/db/ReplicateOnWriteTask.java b/src/java/org/apache/cassandra/db/ReplicateOnWriteTask.java new file mode 100644 index 0000000000..5cad412800 --- /dev/null +++ b/src/java/org/apache/cassandra/db/ReplicateOnWriteTask.java @@ -0,0 +1,129 @@ +package org.apache.cassandra.db; + +import java.io.IOException; +import java.util.Collection; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.net.InetAddress; +import java.nio.ByteBuffer; + +import org.apache.log4j.Logger; + +import org.apache.cassandra.db.filter.QueryPath; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; +import org.apache.cassandra.net.Message; +import org.apache.cassandra.net.MessagingService; +import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.utils.FBUtilities; + +public class ReplicateOnWriteTask implements Runnable +{ + private RowMutation mutation; + private static Logger logger = Logger.getLogger(ReplicateOnWriteTask.class); + + public ReplicateOnWriteTask(RowMutation mutation) + { + this.mutation = mutation; + } + + public void run() + { + // construct SliceByNamesReadCommand for CFs to repair + List readCommands = new LinkedList(); + for (ColumnFamily columnFamily : mutation.getColumnFamilies()) + { + // filter out non-repair CFs + if (!columnFamily.metadata().getReplicateOnWrite()) + continue; + + // CF type: regular + if (!columnFamily.isSuper()) + { + QueryPath queryPath = new QueryPath(columnFamily.metadata().cfName); + ReadCommand readCommand = new SliceByNamesReadCommand( + mutation.getTable(), + mutation.key(), + queryPath, + columnFamily.getColumnNames() + ); + + readCommands.add(readCommand); + continue; + } + + // CF type: super + for (IColumn superColumn : columnFamily.getSortedColumns()) + { + QueryPath queryPath = new QueryPath(columnFamily.metadata().cfName, superColumn.name()); + + // construct set of sub-column names + Collection subColumns = superColumn.getSubColumns(); + Collection subColNames = new HashSet(subColumns.size()); + for (IColumn subCol : subColumns) + { + subColNames.add(subCol.name()); + } + + ReadCommand readCommand = new SliceByNamesReadCommand( + mutation.getTable(), + mutation.key(), + queryPath, + subColNames + ); + readCommands.add(readCommand); + } + } + + if (0 == readCommands.size()) + return; + + try + { + // send repair to non-local replicas + List foreignReplicas = StorageService.instance.getLiveNaturalEndpoints( + mutation.getTable(), + mutation.key() + ); + foreignReplicas.remove(FBUtilities.getLocalAddress()); // remove local replica + + // create a repair RowMutation + RowMutation repairRowMutation = new RowMutation(mutation.getTable(), mutation.key()); + for (ReadCommand readCommand : readCommands) + { + Table table = Table.open(readCommand.table); + Row row = readCommand.getRow(table); + AbstractType defaultValidator = row.cf.metadata().getDefaultValidator(); + if (defaultValidator.isCommutative()) + { + /** + * Clean out contexts for all nodes we're sending the repair to, otherwise, + * we could send a context which is local to one of the foreign replicas, + * which would then incorrectly add that to its own count, because + * local resolution aggregates. + */ + // note: the following logic could be optimized + for (InetAddress foreignNode : foreignReplicas) + { + ((AbstractCommutativeType)defaultValidator).cleanContext(row.cf, foreignNode); + } + } + repairRowMutation.add(row.cf); + } + + // send repair to non-local replicas + for (InetAddress foreignReplica : foreignReplicas) + { + RowMutationMessage repairMessage = new RowMutationMessage( + repairRowMutation); + Message message = repairMessage.makeRowMutationMessage(StorageService.Verb.REPLICATE_ON_WRITE); + MessagingService.instance.sendOneWay(message, foreignReplica); + } + } + catch (IOException e) + { + throw new RuntimeException(e); + } + } +} diff --git a/src/java/org/apache/cassandra/db/ReplicateOnWriteVerbHandler.java b/src/java/org/apache/cassandra/db/ReplicateOnWriteVerbHandler.java new file mode 100644 index 0000000000..e9897fe30c --- /dev/null +++ b/src/java/org/apache/cassandra/db/ReplicateOnWriteVerbHandler.java @@ -0,0 +1,51 @@ +/** + * 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.db; + +import java.io.*; + +import org.apache.cassandra.net.IVerbHandler; +import org.apache.cassandra.net.Message; +import org.apache.cassandra.utils.FBUtilities; + +import org.apache.log4j.Logger; + +public class ReplicateOnWriteVerbHandler implements IVerbHandler +{ + private static Logger logger = Logger.getLogger(ReplicateOnWriteVerbHandler.class); + + public void doVerb(Message message) + { + byte[] body = message.getMessageBody(); + ByteArrayInputStream buffer = new ByteArrayInputStream(body); + + try + { + RowMutationMessage rmMsg = RowMutationMessage.serializer().deserialize(new DataInputStream(buffer)); + RowMutation rm = rmMsg.getRowMutation(); + if (logger.isDebugEnabled()) + logger.debug("repair-on-write for key " + FBUtilities.bytesToHex(rm.key())); + rm.apply(); + } + catch (IOException e) + { + throw new IOError(e); + } + } +} diff --git a/src/java/org/apache/cassandra/db/RowMutation.java b/src/java/org/apache/cassandra/db/RowMutation.java index 485c488e07..1c8a743e93 100644 --- a/src/java/org/apache/cassandra/db/RowMutation.java +++ b/src/java/org/apache/cassandra/db/RowMutation.java @@ -23,6 +23,9 @@ import java.io.ByteArrayOutputStream; import java.io.DataInputStream; import java.io.DataOutputStream; import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.*; import java.nio.ByteBuffer; import java.util.ArrayList; import java.util.Collection; @@ -43,6 +46,9 @@ import org.apache.cassandra.thrift.Deletion; import org.apache.cassandra.thrift.Mutation; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; +import org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; public class RowMutation @@ -316,7 +322,21 @@ public class RowMutation rm.delete(new QueryPath(cfName, del.super_column), del.timestamp); } } - + + /** + * Update the context of all CounterColumns in this RowMutation + */ + public void updateCommutativeTypes(InetAddress node) + { + for (ColumnFamily cf : modifications_.values()) + { + AbstractType defaultValidator = cf.metadata().getDefaultValidator(); + if (!defaultValidator.isCommutative()) + continue; + ((AbstractCommutativeType)defaultValidator).update(cf, node); + } + } + static RowMutation fromBytes(byte[] raw) throws IOException { RowMutation rm = serializer_.deserialize(new DataInputStream(new ByteArrayInputStream(raw))); diff --git a/src/java/org/apache/cassandra/db/RowMutationVerbHandler.java b/src/java/org/apache/cassandra/db/RowMutationVerbHandler.java index f283405069..814ba754c5 100644 --- a/src/java/org/apache/cassandra/db/RowMutationVerbHandler.java +++ b/src/java/org/apache/cassandra/db/RowMutationVerbHandler.java @@ -31,6 +31,8 @@ import org.apache.cassandra.net.Message; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import org.apache.cassandra.concurrent.Stage; +import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.net.*; import org.apache.cassandra.utils.ByteBufferUtil; import org.apache.cassandra.utils.FBUtilities; @@ -74,6 +76,10 @@ public class RowMutationVerbHandler implements IVerbHandler if (logger_.isDebugEnabled()) logger_.debug(rm + " applied. Sending response to " + message.getMessageId() + "@" + message.getFrom()); MessagingService.instance.sendOneWay(responseMessage, message.getFrom()); + + // repair-on-write (remote message) + ReplicateOnWriteTask replicateOnWriteTask = new ReplicateOnWriteTask(rm); + StageManager.getStage(Stage.REPLICATE_ON_WRITE).execute(replicateOnWriteTask); } catch (IOException e) { diff --git a/src/java/org/apache/cassandra/db/SuperColumn.java b/src/java/org/apache/cassandra/db/SuperColumn.java index 0d5def4485..503a5fdb8b 100644 --- a/src/java/org/apache/cassandra/db/SuperColumn.java +++ b/src/java/org/apache/cassandra/db/SuperColumn.java @@ -99,6 +99,11 @@ public class SuperColumn implements IColumn, IColumnContainer return columns_.values(); } + public Collection getSortedColumns() + { + return getSubColumns(); + } + public IColumn getSubColumn(ByteBuffer columnName) { IColumn column = columns_.get(columnName); diff --git a/src/java/org/apache/cassandra/db/context/CounterContext.java b/src/java/org/apache/cassandra/db/context/CounterContext.java new file mode 100644 index 0000000000..f3719d43fe --- /dev/null +++ b/src/java/org/apache/cassandra/db/context/CounterContext.java @@ -0,0 +1,553 @@ +/** + * 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.db.context; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.ArrayList; +import java.util.Collections; +import java.util.Comparator; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +import org.apache.cassandra.db.DBConstants; +import org.apache.cassandra.db.context.IContext; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.commons.lang.ArrayUtils; + +/** + * An implementation of a partitioned counter context. + * + * The data structure is: + * a vector of (node id, logical clock, count) tuples. + * + * On update, the node will: + * 1) increment the logical clock, and + * 2) update the count associated w/ its tuple. + * + * The logical clock represents the # of operations executed + * by the node. The aggregated count can be determined + * by rolling up all the counts from each tuple. + * + * NOTE: only a given node id may increment its associated count and + * care must be taken to ensure that tuples are correctly made consistent. + */ +public class CounterContext implements IContext +{ + private static final int idLength; + private static final FBUtilities.ByteArrayWrapper idWrapper; + private static final int clockLength = DBConstants.longSize_; + private static final int countLength = DBConstants.longSize_; + private static final int stepLength; // length: id + logical clock + count + + // lazy-load singleton + private static class LazyHolder + { + private static final CounterContext counterContext = new CounterContext(); + } + + static + { + byte[] id = FBUtilities.getLocalAddress().getAddress(); + idLength = id.length; + idWrapper = new FBUtilities.ByteArrayWrapper(id); + stepLength = idLength + clockLength + countLength; + } + + public static CounterContext instance() + { + return LazyHolder.counterContext; + } + + /** + * Creates an initial counter context. + * + * @return an empty counter context. + */ + public byte[] create() + { + return new byte[0]; + } + + // write a tuple (node id, clock, count) at the front + protected static void writeElement(byte[] context, byte[] id, long clock, long count) + { + writeElementAtStepOffset(context, 0, id, clock, count); + } + + // write a tuple (node id, clock, count) at step offset + protected static void writeElementAtStepOffset(byte[] context, int stepOffset, byte[] id, long clock, long count) + { + int offset = stepOffset * stepLength; + System.arraycopy(id, 0, context, offset, idLength); + FBUtilities.copyIntoBytes(context, offset + idLength, clock); + FBUtilities.copyIntoBytes(context, offset + idLength + clockLength, count); + } + + public byte[] update(byte[] context, InetAddress node, long delta) + { + // calculate node id + byte[] nodeId = node.getAddress(); + + // look for this node id + for (int offset = 0; offset < context.length; offset += stepLength) + { + if (FBUtilities.compareByteSubArrays(nodeId, 0, context, offset, idLength) != 0) + continue; + + // node id found: increment clock, update count; shift to front + long clock = FBUtilities.byteArrayToLong(context, offset + idLength); + long count = FBUtilities.byteArrayToLong(context, offset + idLength + clockLength); + + System.arraycopy( + context, + 0, + context, + stepLength, + offset); + writeElement(context, nodeId, clock + 1L, count + delta); + + return context; + } + + // node id not found: widen context + byte[] previous = context; + context = new byte[previous.length + stepLength]; + + writeElement(context, nodeId, 1L, delta); + System.arraycopy( + previous, + 0, + context, + stepLength, + previous.length); + + return context; + } + + // swap bytes of step length in context + protected static void swapElement(byte[] context, int left, int right) + { + if (left == right) return; + + byte temp; + for (int i = 0; i < stepLength; i++) + { + temp = context[left+i]; + context[left+i] = context[right+i]; + context[right+i] = temp; + } + } + + // partition bytes of step length in context (for quicksort) + protected static int partitionElements(byte[] context, int left, int right, int pivotIndex) + { + int leftOffset = left * stepLength; + int rightOffset = right * stepLength; + int pivotOffset = pivotIndex * stepLength; + + byte[] pivotValue = ArrayUtils.subarray(context, pivotOffset, pivotOffset + stepLength); + swapElement(context, pivotOffset, rightOffset); + int storeOffset = leftOffset; + for (int i = leftOffset; i < rightOffset; i += stepLength) + { + if (FBUtilities.compareByteSubArrays(context, i, pivotValue, 0, stepLength) <= 0) + { + swapElement(context, i, storeOffset); + storeOffset += stepLength; + } + } + swapElement(context, storeOffset, rightOffset); + return storeOffset / stepLength; + } + + // quicksort helper + protected static void sortElementsByIdHelper(byte[] context, int left, int right) + { + if (right <= left) return; + + int pivotIndex = (left + right) / 2; + int pivotIndexNew = partitionElements(context, left, right, pivotIndex); + sortElementsByIdHelper(context, left, pivotIndexNew - 1); + sortElementsByIdHelper(context, pivotIndexNew + 1, right); + } + + // quicksort context by id + protected static byte[] sortElementsById(byte[] context) + { + assert 0 == (context.length % stepLength) : "context size is not correct."; + sortElementsByIdHelper( + context, + 0, + (int)(context.length / stepLength) - 1); + return context; + } + + /** + * Determine the count relationship between two contexts. + * + * EQUAL: Equal set of nodes and every count is equal. + * GREATER_THAN: Superset of nodes and every count is equal or greater than its corollary. + * LESS_THAN: Subset of nodes and every count is equal or less than its corollary. + * DISJOINT: Node sets are not equal and/or counts are not all greater or less than. + * + * Strategy: + * compare node logical clocks (like a version vector). + * + * @param left + * counter context. + * @param right + * counter context. + * @return the ContextRelationship between the contexts. + */ + public ContextRelationship diff(byte[] left, byte[] right) + { + left = sortElementsById(left); + right = sortElementsById(right); + + ContextRelationship relationship = ContextRelationship.EQUAL; + + int leftIndex = 0; + int rightIndex = 0; + while (leftIndex < left.length && rightIndex < right.length) + { + // compare id bytes + int compareId = FBUtilities.compareByteSubArrays(left, leftIndex, right, rightIndex, idLength); + if (compareId == 0) + { + long leftClock = FBUtilities.byteArrayToLong(left, leftIndex + idLength); + long rightClock = FBUtilities.byteArrayToLong(right, rightIndex + idLength); + + // advance indexes + leftIndex += stepLength; + rightIndex += stepLength; + + // process clock comparisons + if (leftClock == rightClock) + { + continue; + } + else if (leftClock > rightClock) + { + if (relationship == ContextRelationship.EQUAL) + { + relationship = ContextRelationship.GREATER_THAN; + } + else if (relationship == ContextRelationship.GREATER_THAN) + { + continue; + } + else + { + // relationship == ContextRelationship.LESS_THAN + return ContextRelationship.DISJOINT; + } + } + else + // leftClock < rightClock + { + if (relationship == ContextRelationship.EQUAL) + { + relationship = ContextRelationship.LESS_THAN; + } + else if (relationship == ContextRelationship.GREATER_THAN) + { + return ContextRelationship.DISJOINT; + } + else + { + // relationship == ContextRelationship.LESS_THAN + continue; + } + } + } + else if (compareId > 0) + { + // only advance the right context + rightIndex += stepLength; + + if (relationship == ContextRelationship.EQUAL) + { + relationship = ContextRelationship.LESS_THAN; + } + else if (relationship == ContextRelationship.GREATER_THAN) + { + return ContextRelationship.DISJOINT; + } + else + { + // relationship == ContextRelationship.LESS_THAN + continue; + } + } + else + { + // compareId < 0 + // only advance the left context + leftIndex += stepLength; + + if (relationship == ContextRelationship.EQUAL) + { + relationship = ContextRelationship.GREATER_THAN; + } + else if (relationship == ContextRelationship.GREATER_THAN) + { + continue; + } + else + // relationship == ContextRelationship.LESS_THAN + { + return ContextRelationship.DISJOINT; + } + } + } + + // check final lengths + if (leftIndex < left.length) + { + if (relationship == ContextRelationship.EQUAL) + { + return ContextRelationship.GREATER_THAN; + } + else if (relationship == ContextRelationship.LESS_THAN) + { + return ContextRelationship.DISJOINT; + } + } + else if (rightIndex < right.length) + { + if (relationship == ContextRelationship.EQUAL) + { + return ContextRelationship.LESS_THAN; + } + else if (relationship == ContextRelationship.GREATER_THAN) + { + return ContextRelationship.DISJOINT; + } + } + + return relationship; + } + + private class CounterNode + { + public final long clock; + public final long count; + + public CounterNode(long clock, long count) + { + this.clock = clock; + this.count = count; + } + + public int compareClockTo(CounterNode o) + { + if (clock == o.clock) + { + return 0; + } + else if (clock > o.clock) + { + return 1; + } + // clock < o.clock + return -1; + } + + @Override + public String toString() + { + return "(" + clock + "," + count + ")"; + } + } + + /** + * Return a context w/ an aggregated count for each node id. + * + * @param left + * counter context. + * @param right + * counter context. + */ + public byte[] merge(byte[] left, byte[] right) + { + // strategy: + // 1) map id -> (clock, count) + // a) local id: sum clocks, counts + // b) remote id: keep highest clock, count (reconcile) + // 2) create a context from sorted array + Map contextsMap = + new HashMap(); + + // map left context: id -> (clock, count) + for (int offset = 0; offset < left.length; offset += stepLength) + { + FBUtilities.ByteArrayWrapper id = new FBUtilities.ByteArrayWrapper( + ArrayUtils.subarray(left, offset, offset + idLength)); + long clock = FBUtilities.byteArrayToLong(left, offset + idLength); + long count = FBUtilities.byteArrayToLong(left, offset + idLength + clockLength); + + contextsMap.put(id, new CounterNode(clock, count)); + } + + // map right context: id -> (clock, count) + for (int offset = 0; offset < right.length; offset += stepLength) + { + FBUtilities.ByteArrayWrapper id = new FBUtilities.ByteArrayWrapper( + ArrayUtils.subarray(right, offset, offset + idLength)); + long clock = FBUtilities.byteArrayToLong(right, offset + idLength); + long count = FBUtilities.byteArrayToLong(right, offset + idLength + clockLength); + + if (!contextsMap.containsKey(id)) + { + contextsMap.put(id, new CounterNode(clock, count)); + continue; + } + + CounterNode node = contextsMap.get(id); + + // local id: sum clocks, counts + if (this.idWrapper.equals(id)) + { + contextsMap.put(id, new CounterNode( + clock + node.clock, + count + node.count)); + continue; + } + + // remote id: keep highest clock and its count + if (node.clock < clock) + { + contextsMap.put(id, new CounterNode(clock, count)); + } + } + + // sort merged tuples + List> contextsList = + new ArrayList>( + contextsMap.entrySet()); + Collections.sort( + contextsList, + new Comparator>() + { + public int compare( + Map.Entry e1, + Map.Entry e2) + { + // reversed + return e2.getValue().compareClockTo(e1.getValue()); + } + }); + + // create merged context + int length = contextsList.size(); + byte[] merged = new byte[length * stepLength]; + for (int i = 0; i < length; i++) + { + Map.Entry entry = contextsList.get(i); + writeElementAtStepOffset( + merged, + i, + entry.getKey().data, + entry.getValue().clock, + entry.getValue().count); + } + return merged; + } + + /** + * Human-readable String from context. + * + * @param context + * version context. + * @return a human-readable String of the context. + */ + public String toString(byte[] context) + { + StringBuilder sb = new StringBuilder(); + sb.append("["); + for (int offset = 0; offset < context.length; offset += stepLength) + { + if (offset > 0) + { + sb.append(","); + } + sb.append("{"); + try + { + InetAddress address = InetAddress.getByAddress( + ArrayUtils.subarray(context, offset, offset + idLength)); + sb.append(address.getHostAddress()); + } + catch (UnknownHostException uhe) + { + sb.append("?.?.?.?"); + } + sb.append(", "); + sb.append(FBUtilities.byteArrayToLong(context, offset + idLength)); + sb.append(", "); + sb.append(FBUtilities.byteArrayToLong(context, offset + idLength + clockLength)); + + sb.append("}"); + } + sb.append("]"); + return sb.toString(); + } + + // return an aggregated count across all node ids + public byte[] total(byte[] context) + { + long total = 0L; + + for (int offset = 0; offset < context.length; offset += stepLength) + { + long count = FBUtilities.byteArrayToLong(context, offset + idLength + clockLength); + total += count; + } + + return FBUtilities.toByteArray(total); + } + + // remove the count for a given node id + public byte[] cleanNodeCounts(byte[] context, InetAddress node) + { + // calculate node id + byte[] nodeId = node.getAddress(); + + // look for this node id + for (int offset = 0; offset < context.length; offset += stepLength) + { + if (FBUtilities.compareByteSubArrays(context, offset, nodeId, 0, idLength) != 0) + continue; + + // node id found: remove node count + byte[] truncatedContext = new byte[context.length - stepLength]; + System.arraycopy(context, 0, truncatedContext, 0, offset); + System.arraycopy( + context, + offset + stepLength, + truncatedContext, + offset, + context.length - (offset + stepLength)); + return truncatedContext; + } + + return context; + } +} diff --git a/src/java/org/apache/cassandra/db/context/IContext.java b/src/java/org/apache/cassandra/db/context/IContext.java new file mode 100644 index 0000000000..6b4bfffea0 --- /dev/null +++ b/src/java/org/apache/cassandra/db/context/IContext.java @@ -0,0 +1,79 @@ +/** + * 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.db.context; + +import java.net.InetAddress; +import java.util.List; + +/** + * An opaque commutative context. + * + * Maintains a byte[] context that represents a partitioned commutative value. + */ +public interface IContext +{ + public static enum ContextRelationship + { + EQUAL, + GREATER_THAN, + LESS_THAN, + DISJOINT + }; + + /** + * Creates an initial context. + * + * @return the initial context. + */ + public byte[] create(); + + /** + * Determine the relationship between two contexts. + * + * EQUAL: Equal set of nodes and every count is equal. + * GREATER_THAN: Superset of nodes and every count is equal or greater than its corollary. + * LESS_THAN: Subset of nodes and every count is equal or less than its corollary. + * DISJOINT: Node sets are not equal and/or counts are not all greater or less than. + * + * @param left + * context. + * @param right + * context. + * @return the ContextRelationship between the contexts. + */ + public ContextRelationship diff(byte[] left, byte[] right); + + /** + * Return a context w/ an aggregated count for each node id. + * + * @param left + * context. + * @param right + * context. + */ + public byte[] merge(byte[] left, byte[] right); + + /** + * Human-readable String from context. + * + * @param context + * context. + * @return a human-readable String of the context. + */ + public String toString(byte[] context); +} diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java b/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java new file mode 100644 index 0000000000..e03a719098 --- /dev/null +++ b/src/java/org/apache/cassandra/db/marshal/AbstractCommutativeType.java @@ -0,0 +1,50 @@ +/* + * + * 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.db.marshal; + +import java.net.InetAddress; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.Column; +import org.apache.cassandra.db.IColumnContainer; + +public abstract class AbstractCommutativeType extends AbstractType +{ + public boolean isCommutative() + { + return true; + } + + /** + * create commutative column + */ + public abstract Column createColumn(ByteBuffer name, ByteBuffer value, long timestamp); + + /** + * update commutative columns for target node + */ + public abstract void update(IColumnContainer cc, InetAddress node); + + /** + * remove target node from commutative columns + */ + public abstract void cleanContext(IColumnContainer cc, InetAddress node); +} diff --git a/src/java/org/apache/cassandra/db/marshal/AbstractType.java b/src/java/org/apache/cassandra/db/marshal/AbstractType.java index d159ac4945..be7ab3eb7c 100644 --- a/src/java/org/apache/cassandra/db/marshal/AbstractType.java +++ b/src/java/org/apache/cassandra/db/marshal/AbstractType.java @@ -91,4 +91,9 @@ public abstract class AbstractType implements Comparator } return builder.toString(); } + + public boolean isCommutative() + { + return false; + } } diff --git a/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java b/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java new file mode 100644 index 0000000000..3334b9fd0a --- /dev/null +++ b/src/java/org/apache/cassandra/db/marshal/CounterColumnType.java @@ -0,0 +1,133 @@ +/* + * + * 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.db.marshal; + +import java.net.InetAddress; +import java.nio.ByteBuffer; + +import org.apache.cassandra.db.ColumnFamily; +import org.apache.cassandra.db.CounterColumn; +import org.apache.cassandra.db.Column; +import org.apache.cassandra.db.DeletedColumn; +import org.apache.cassandra.db.IColumn; +import org.apache.cassandra.db.IColumnContainer; +import org.apache.cassandra.db.SuperColumn; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.FBUtilities; + +public class CounterColumnType extends AbstractCommutativeType +{ + public static final CounterColumnType instance = new CounterColumnType(); + + CounterColumnType() {} // singleton + + public int compare(ByteBuffer o1, ByteBuffer o2) + { + if (o1.remaining() == 0) + { + return o2.remaining() == 0 ? 0 : -1; + } + if (o2.remaining() == 0) + { + return 1; + } + + return ByteBufferUtil.compareUnsigned(o1, o2); + } + + public String getString(ByteBuffer bytes) + { + if (bytes.remaining() == 0) + { + return ""; + } + if (bytes.remaining() != 8) + { + throw new MarshalException("A long is exactly 8 bytes"); + } + return String.valueOf(bytes.getLong(bytes.position()+bytes.arrayOffset())); + } + + /** + * create commutative column + */ + public Column createColumn(ByteBuffer name, ByteBuffer value, long timestamp) + { + return new CounterColumn(name, value, timestamp); + } + + /** + * update commutative columns for target node + */ + public void update(IColumnContainer cc, InetAddress node) + { + for (IColumn column : cc.getSortedColumns()) + { + if (column instanceof SuperColumn) + { + update((IColumnContainer)column, node); + continue; + } + + if (column instanceof DeletedColumn) + continue; + + ((CounterColumn)column).update(node); + } + } + + /** + * remove target node from commutative columns + */ + public void cleanContext(IColumnContainer cc, InetAddress node) + { + if ((cc instanceof ColumnFamily) && ((ColumnFamily)cc).isSuper()) + { + for (IColumn column : cc.getSortedColumns()) + { + SuperColumn supercol = (SuperColumn)column; + cleanContext(supercol, node); + if (0 == supercol.getSubColumns().size()) + cc.remove(supercol.name()); + } + return; + } + + for (IColumn column : cc.getSortedColumns()) + { + CounterColumn counterColumn = (CounterColumn)column; + CounterColumn cleanedColumn = counterColumn.cleanNodeCounts(node); + if (cleanedColumn == counterColumn) + continue; + cc.remove(counterColumn.name()); + //XXX: on "clean," must copy-and-replace + if (null != cleanedColumn) + cc.addColumn(cleanedColumn); + } + } + + public void validate(ByteBuffer bytes) throws MarshalException + { + if (bytes.remaining() != 8 && bytes.remaining() != 0) + throw new MarshalException(String.format("Expected 8 or 0 byte long (%d)", bytes.remaining())); + } +} + diff --git a/src/java/org/apache/cassandra/dht/BootStrapper.java b/src/java/org/apache/cassandra/dht/BootStrapper.java index 2473280d28..fb0a12f7fd 100644 --- a/src/java/org/apache/cassandra/dht/BootStrapper.java +++ b/src/java/org/apache/cassandra/dht/BootStrapper.java @@ -45,6 +45,7 @@ package org.apache.cassandra.dht; import org.apache.cassandra.net.Message; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.service.StorageService; + import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.streaming.StreamIn; import org.apache.cassandra.utils.FBUtilities; import org.apache.cassandra.utils.SimpleCondition; @@ -107,8 +108,8 @@ public class BootStrapper } }; if (logger.isDebugEnabled()) - logger.debug("Bootstrapping from " + source + " ranges " + StringUtils.join(ranges, ", ")); - StreamIn.requestRanges(source, table, ranges, callback); + logger.debug("Bootstrapping from " + source + " ranges " + StringUtils.join(entry.getValue(), ", ")); + StreamIn.requestRanges(source, table, entry.getValue(), callback, OperationType.BOOTSTRAP); } } diff --git a/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java b/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java index b3b5040a00..c0cc3fc7e1 100644 --- a/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java +++ b/src/java/org/apache/cassandra/io/sstable/SSTableWriter.java @@ -19,6 +19,8 @@ package org.apache.cassandra.io.sstable; +import java.io.*; +import java.net.InetAddress; import java.io.DataOutputStream; import java.io.File; import java.io.FileOutputStream; @@ -31,6 +33,9 @@ import java.util.Set; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.db.*; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; import org.apache.cassandra.db.ColumnFamily; import org.apache.cassandra.db.ColumnFamilyStore; import org.apache.cassandra.db.DecoratedKey; @@ -43,6 +48,7 @@ import org.apache.cassandra.io.util.FileMark; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.io.util.SegmentedFile; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.utils.BloomFilter; import org.apache.cassandra.utils.EstimatedHistogram; import org.apache.cassandra.utils.FBUtilities; @@ -221,7 +227,7 @@ public class SSTableWriter extends SSTable return dataFile.getFilePointer(); } - public static Builder createBuilder(Descriptor desc) + public static Builder createBuilder(Descriptor desc, OperationType type) { if (!desc.isLatestVersion) // TODO: streaming between different versions will fail: need support for @@ -229,7 +235,7 @@ public class SSTableWriter extends SSTable throw new RuntimeException(String.format("Cannot recover SSTable with version %s (current version %s).", desc.version, Descriptor.CURRENT_VERSION)); - return new Builder(desc); + return new Builder(desc, type); } /** @@ -240,16 +246,18 @@ public class SSTableWriter extends SSTable { private final Descriptor desc; public final ColumnFamilyStore cfs; - private BufferedRandomAccessFile dfile; + private final RowIndexer indexer; - public Builder(Descriptor desc) + public Builder(Descriptor desc, OperationType type) { - this.desc = desc; cfs = Table.open(desc.ksname).getColumnFamilyStore(desc.cfname); try { - dfile = new BufferedRandomAccessFile(desc.filenameFor(SSTable.COMPONENT_DATA), "r", 8 * 1024 * 1024); + if (OperationType.AES == type && cfs.metadata.getDefaultValidator().isCommutative()) + indexer = new AESCommutativeRowIndexer(desc, cfs.metadata); + else + indexer = new RowIndexer(desc, cfs.metadata); } catch (IOException e) { @@ -266,47 +274,79 @@ public class SSTableWriter extends SSTable assert !ifile.exists(); assert !ffile.exists(); - EstimatedHistogram rowSizes = SSTable.defaultRowHistogram(); - EstimatedHistogram columnCounts = SSTable.defaultColumnHistogram(); + long estimatedRows = indexer.prepareIndexing(); - IndexWriter iwriter; + // build the index and filter + long rows = indexer.index(); + + logger.debug("estimated row count was {} of real count", ((double)estimatedRows) / rows); + return SSTableReader.open(rename(desc, SSTable.componentsFor(desc))); + } + + public long getTotalBytes() + { + try + { + return indexer.dfile.length(); + } + catch (IOException e) + { + throw new IOError(e); + } + } + + public long getBytesRead() + { + return indexer.dfile.getFilePointer(); + } + + public String getTaskType() + { + return "SSTable rebuild"; + } + } + + static class RowIndexer + { + protected final Descriptor desc; + public final BufferedRandomAccessFile dfile; + + protected IndexWriter iwriter; + protected CFMetaData metadata; + + RowIndexer(Descriptor desc, CFMetaData metadata) throws IOException + { + this(desc, new BufferedRandomAccessFile(desc.filenameFor(SSTable.COMPONENT_DATA), "r", 8 * 1024 * 1024), metadata); + } + + protected RowIndexer(Descriptor desc, BufferedRandomAccessFile dfile, CFMetaData metadata) throws IOException + { + this.desc = desc; + this.dfile = dfile; + this.metadata = metadata; + } + + long prepareIndexing() throws IOException + { long estimatedRows; try { estimatedRows = SSTable.estimateRowsFromData(desc, dfile); iwriter = new IndexWriter(desc, StorageService.getPartitioner(), estimatedRows); + return estimatedRows; } catch(IOException e) { dfile.close(); throw e; } + } - // build the index and filter - long rows = 0; + long index() throws IOException + { try { - DecoratedKey key; - long rowPosition = 0; - while (rowPosition < dfile.length()) - { - key = SSTableReader.decodeKey(StorageService.getPartitioner(), desc, FBUtilities.readShortByteArray(dfile)); - iwriter.afterAppend(key, rowPosition); - - long dataSize = SSTableReader.readRowSize(dfile, desc); - rowPosition = dfile.getFilePointer() + dataSize; // next row - - IndexHelper.skipBloomFilter(dfile); - IndexHelper.skipIndex(dfile); - ColumnFamily.serializer().deserializeFromSSTableNoColumns(ColumnFamily.create(cfs.metadata), dfile); - rowSizes.add(dataSize); - columnCounts.add(dfile.readInt()); - - dfile.seek(rowPosition); - rows++; - } - - writeStatistics(desc, rowSizes, columnCounts); + return doIndexing(); } finally { @@ -320,31 +360,113 @@ public class SSTableWriter extends SSTable throw new IOError(e); } } - - logger.debug("estimated row count was %s of real count", ((double)estimatedRows) / rows); - return SSTableReader.open(rename(desc, SSTable.componentsFor(desc))); } - public long getTotalBytes() + protected long doIndexing() throws IOException { - try + EstimatedHistogram rowSizes = SSTable.defaultRowHistogram(); + EstimatedHistogram columnCounts = SSTable.defaultColumnHistogram(); + long rows = 0; + DecoratedKey key; + long rowPosition = 0; + while (rowPosition < dfile.length()) { - return dfile.length(); + // read key + key = SSTableReader.decodeKey(StorageService.getPartitioner(), desc, FBUtilities.readShortByteArray(dfile)); + iwriter.afterAppend(key, rowPosition); + + // seek to next key + long dataSize = SSTableReader.readRowSize(dfile, desc); + rowPosition = dfile.getFilePointer() + dataSize; + + IndexHelper.skipBloomFilter(dfile); + IndexHelper.skipIndex(dfile); + ColumnFamily.serializer().deserializeFromSSTableNoColumns(ColumnFamily.create(metadata), dfile); + rowSizes.add(dataSize); + columnCounts.add(dfile.readInt()); + + dfile.seek(rowPosition); + + rows++; } - catch (IOException e) + return rows; + } + } + + static class AESCommutativeRowIndexer extends RowIndexer + { + AESCommutativeRowIndexer(Descriptor desc, CFMetaData metadata) throws IOException + { + super(desc, new BufferedRandomAccessFile(desc.filenameFor(SSTable.COMPONENT_DATA), "rw", 8 * 1024 * 1024), metadata); + } + + @Override + protected long doIndexing() throws IOException + { + EstimatedHistogram rowSizes = SSTable.defaultRowHistogram(); + EstimatedHistogram columnCounts = SSTable.defaultColumnHistogram(); + long rows = 0L; + ByteBuffer diskKey; + DecoratedKey key; + + long readRowPosition = 0L; + long writeRowPosition = 0L; + while (readRowPosition < dfile.length()) { - throw new IOError(e); + // read key + dfile.seek(readRowPosition); + diskKey = FBUtilities.readShortByteArray(dfile); + + // skip data size, bloom filter, column index + long dataSize = SSTableReader.readRowSize(dfile, desc); + dfile.skipBytes(dfile.readInt()); + dfile.skipBytes(dfile.readInt()); + + // deserialize CF + ColumnFamily cf = ColumnFamily.create(desc.ksname, desc.cfname); + ColumnFamily.serializer().deserializeFromSSTableNoColumns(cf, dfile); + ColumnFamily.serializer().deserializeColumns(dfile, cf); + rowSizes.add(dataSize); + columnCounts.add(cf.getEstimatedColumnCount()); + + // remove source node from CF's commutative columns + ((AbstractCommutativeType)cf.metadata().getDefaultValidator()).cleanContext(cf, FBUtilities.getLocalAddress()); + + readRowPosition = dfile.getFilePointer(); + + + // update index writer + key = SSTableReader.decodeKey(StorageService.getPartitioner(), desc, diskKey); + iwriter.afterAppend(key, writeRowPosition); + + + // write key + dfile.seek(writeRowPosition); + FBUtilities.writeShortByteArray(diskKey, dfile); + + // write data size; serialize CF w/ bloom filter, column index + long writeSizePosition = dfile.getFilePointer(); + dfile.writeLong(-1L); + ColumnFamily.serializer().serializeWithIndexes(cf, dfile); + long writeEndPosition = dfile.getFilePointer(); + dfile.seek(writeSizePosition); + dfile.writeLong(writeEndPosition - (writeSizePosition + 8L)); + + writeRowPosition = writeEndPosition; + + rows++; + + dfile.sync(); } - } - public long getBytesRead() - { - return dfile.getFilePointer(); - } + if (writeRowPosition != readRowPosition) + { + // truncate file to new, reduced length + dfile.setLength(writeRowPosition); + dfile.sync(); + } - public String getTaskType() - { - return "SSTable rebuild"; + return rows; } } diff --git a/src/java/org/apache/cassandra/service/AntiEntropyService.java b/src/java/org/apache/cassandra/service/AntiEntropyService.java index 85dea09891..f54a8ee2d9 100644 --- a/src/java/org/apache/cassandra/service/AntiEntropyService.java +++ b/src/java/org/apache/cassandra/service/AntiEntropyService.java @@ -42,6 +42,7 @@ import org.apache.cassandra.dht.Token; import org.apache.cassandra.io.AbstractCompactedRow; import org.apache.cassandra.io.ICompactSerializer; import org.apache.cassandra.io.sstable.SSTableReader; +import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.streaming.StreamIn; import org.apache.cassandra.streaming.StreamOut; import org.apache.cassandra.net.CompactEndpointSerializationHelper; @@ -502,9 +503,9 @@ public class AntiEntropyService Callback callback = new Callback(); // send ranges to the remote node StreamOutSession outsession = StreamOutSession.create(request.cf.left, request.endpoint, callback); - StreamOut.transferSSTables(outsession, sstables, ranges); + StreamOut.transferSSTables(outsession, sstables, ranges, OperationType.AES); // request ranges from the remote node - StreamIn.requestRanges(request.endpoint, request.cf.left, ranges, callback); + StreamIn.requestRanges(request.endpoint, request.cf.left, ranges, callback, OperationType.AES); } catch(Exception e) { diff --git a/src/java/org/apache/cassandra/service/ReadResponseResolver.java b/src/java/org/apache/cassandra/service/ReadResponseResolver.java index 6c47cd6225..6e97c34855 100644 --- a/src/java/org/apache/cassandra/service/ReadResponseResolver.java +++ b/src/java/org/apache/cassandra/service/ReadResponseResolver.java @@ -25,6 +25,8 @@ import java.io.IOException; import java.util.*; import org.apache.cassandra.db.*; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; import java.net.InetAddress; import java.nio.ByteBuffer; @@ -52,6 +54,13 @@ public class ReadResponseResolver implements IResponseResolver this.table = table; this.key = StorageService.getPartitioner().decorateKey(key); } + + private void checkDigest(DecoratedKey key, ByteBuffer digest, ByteBuffer resultDigest) throws DigestMismatchException + { + if (resultDigest.equals(digest)) + return; + throw new DigestMismatchException(key, digest, resultDigest); + } /* * This method for resolving read data should look at the timestamps of each @@ -82,21 +91,25 @@ public class ReadResponseResolver implements IResponseResolver Message message = entry.getKey(); if (result.isDigestQuery()) { - if (digest == null) - { - digest = result.digest(); - } - else - { - ByteBuffer digest2 = result.digest(); - if (!digest.equals(digest2)) - throw new DigestMismatchException(key, digest, digest2); - } + if (digest != null) + checkDigest(key, digest, result.digest()); + digest = result.digest(); } else { - versions.add(result.row().cf); - endpoints.add(message.getFrom()); + ColumnFamily cf = result.row().cf; + InetAddress from = message.getFrom(); + + if(cf != null) { + AbstractType defaultValidator = cf.metadata().getDefaultValidator(); + if (!FBUtilities.getLocalAddress().equals(from) && cf != null && defaultValidator.isCommutative()) + { + cf = cf.cloneMe(); + ((AbstractCommutativeType)defaultValidator).cleanContext(cf, FBUtilities.getLocalAddress()); + } + } + versions.add(cf); + endpoints.add(from); } } @@ -107,9 +120,7 @@ public class ReadResponseResolver implements IResponseResolver for (ColumnFamily cf : versions) { - ByteBuffer digest2 = ColumnFamily.digest(cf); - if (!digest.equals(digest2)) - throw new DigestMismatchException(key, digest, digest2); + checkDigest(key, digest, ColumnFamily.digest(cf)); } if (logger_.isDebugEnabled()) logger_.debug("digests verified"); @@ -147,6 +158,14 @@ public class ReadResponseResolver implements IResponseResolver // create and send the row mutation message based on the diff RowMutation rowMutation = new RowMutation(table, key.key); + + AbstractType defaultValidator = diffCf.metadata().getDefaultValidator(); + if (defaultValidator.isCommutative()) + ((AbstractCommutativeType)defaultValidator).cleanContext(diffCf, endpoints.get(i)); + + if (diffCf.getColumnsMap().isEmpty() && !diffCf.isMarkedForDelete()) + continue; + rowMutation.add(diffCf); RowMutationMessage rowMutationMessage = new RowMutationMessage(rowMutation); Message repairMessage; @@ -170,7 +189,7 @@ public class ReadResponseResolver implements IResponseResolver { if (cf != null) { - resolved = cf.cloneMe(); + resolved = cf.cloneMeShallow(); break; } } diff --git a/src/java/org/apache/cassandra/service/StorageProxy.java b/src/java/org/apache/cassandra/service/StorageProxy.java index 6e55030e3b..595d8ea5c2 100644 --- a/src/java/org/apache/cassandra/service/StorageProxy.java +++ b/src/java/org/apache/cassandra/service/StorageProxy.java @@ -41,6 +41,8 @@ import org.apache.cassandra.concurrent.StageManager; import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.*; +import org.apache.cassandra.db.marshal.AbstractType; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; import org.apache.cassandra.dht.*; import org.apache.cassandra.gms.Gossiper; import org.apache.cassandra.locator.AbstractReplicationStrategy; @@ -117,6 +119,10 @@ public class StorageProxy implements StorageProxyMBean responseHandlers.add(responseHandler); Message unhintedMessage = null; + + //XXX: if commutative value, only allow CL.ONE write + updateDestinationForCommutativeTypes(consistency_level, rm, hintedEndpoints); + for (Map.Entry> entry : hintedEndpoints.asMap().entrySet()) { InetAddress destination = entry.getKey(); @@ -124,6 +130,9 @@ public class StorageProxy implements StorageProxyMBean if (targets.size() == 1 && targets.iterator().next().equals(destination)) { + // only non-hinted writes are supported + rm.updateCommutativeTypes(destination); + // unhinted writes if (destination.equals(FBUtilities.getLocalAddress())) { @@ -180,6 +189,40 @@ public class StorageProxy implements StorageProxyMBean } + /** + * Update destination endpoints depending on the clock type. + */ + private static void updateDestinationForCommutativeTypes(ConsistencyLevel consistency_level, RowMutation rm, + Multimap destinationEndpoints) + { + AbstractType defaultValidator = rm.getColumnFamilies().iterator().next().metadata().getDefaultValidator(); + if (!defaultValidator.isCommutative()) + return; + + InetAddress randomDestination = pickRandomDestination(destinationEndpoints); + destinationEndpoints.clear(); + destinationEndpoints.put(randomDestination, randomDestination); + } + + /** + * @param endpoints potential destinations. + * @return one destination randomly chosen from the endpoints unless localhost is in the map, then that is returned. + */ + private static InetAddress pickRandomDestination(Multimap endpoints) + { + Set destinationSet = endpoints.keySet(); + + if (destinationSet.contains(FBUtilities.getLocalAddress())) + { + return FBUtilities.getLocalAddress(); + } + else + { + InetAddress[] destinations = destinationSet.toArray(new InetAddress[0]); + return destinations[random.nextInt(destinations.length)]; + } + } + private static void addHintHeader(Message message, InetAddress target) throws IOException { ByteArrayOutputStream bos = new ByteArrayOutputStream(); @@ -203,6 +246,10 @@ public class StorageProxy implements StorageProxyMBean { rm.deepCopy().apply(); responseHandler.response(null); + + // repair-on-write (local message) + ReplicateOnWriteTask replicateOnWriteTask = new ReplicateOnWriteTask(rm); + StageManager.getStage(Stage.REPLICATE_ON_WRITE).execute(replicateOnWriteTask); } }; StageManager.getStage(Stage.MUTATION).execute(runnable); diff --git a/src/java/org/apache/cassandra/service/StorageService.java b/src/java/org/apache/cassandra/service/StorageService.java index a8929dd80d..1f58de5786 100644 --- a/src/java/org/apache/cassandra/service/StorageService.java +++ b/src/java/org/apache/cassandra/service/StorageService.java @@ -69,6 +69,7 @@ import org.apache.cassandra.db.HintedHandOffManager; import org.apache.cassandra.db.ReadCommand; import org.apache.cassandra.db.ReadRepairVerbHandler; import org.apache.cassandra.db.ReadVerbHandler; +import org.apache.cassandra.db.ReplicateOnWriteVerbHandler; import org.apache.cassandra.db.Row; import org.apache.cassandra.db.RowMutationVerbHandler; import org.apache.cassandra.db.SchemaCheckVerbHandler; @@ -101,6 +102,7 @@ import org.apache.cassandra.net.Message; import org.apache.cassandra.net.MessagingService; import org.apache.cassandra.net.ResponseVerbHandler; import org.apache.cassandra.service.AntiEntropyService.TreeRequestVerbHandler; +import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.streaming.ReplicationFinishedVerbHandler; import org.apache.cassandra.streaming.StreamIn; import org.apache.cassandra.streaming.StreamOut; @@ -165,6 +167,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe INDEX_SCAN, REPLICATION_FINISHED, INTERNAL_RESPONSE, // responses to internal calls + REPLICATE_ON_WRITE, ; // remember to add new verbs at the end, since we serialize by ordinal } @@ -193,6 +196,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe put(Verb.INDEX_SCAN, Stage.READ); put(Verb.REPLICATION_FINISHED, Stage.MISC); put(Verb.INTERNAL_RESPONSE, Stage.INTERNAL_RESPONSE); + put(Verb.REPLICATE_ON_WRITE, Stage.REPLICATE_ON_WRITE); }}; @@ -278,6 +282,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe MessagingService.instance.registerVerbHandlers(Verb.MUTATION, new RowMutationVerbHandler()); MessagingService.instance.registerVerbHandlers(Verb.READ_REPAIR, new ReadRepairVerbHandler()); MessagingService.instance.registerVerbHandlers(Verb.READ, new ReadVerbHandler()); + MessagingService.instance.registerVerbHandlers(Verb.REPLICATE_ON_WRITE, new ReplicateOnWriteVerbHandler()); MessagingService.instance.registerVerbHandlers(Verb.RANGE_SLICE, new RangeSliceVerbHandler()); MessagingService.instance.registerVerbHandlers(Verb.INDEX_SCAN, new IndexScanVerbHandler()); // see BootStrapper for a summary of how the bootstrap verbs interact @@ -1004,7 +1009,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe }; if (logger_.isDebugEnabled()) logger_.debug("Requesting from " + source + " ranges " + StringUtils.join(ranges, ", ")); - StreamIn.requestRanges(source, table, ranges, callback); + StreamIn.requestRanges(source, table, ranges, callback, OperationType.RESTORE_REPLICA_COUNT); } } } @@ -1608,7 +1613,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe public void run() { // TODO each call to transferRanges re-flushes, this is potentially a lot of waste - StreamOut.transferRanges(newEndpoint, table, Arrays.asList(range), callback); + StreamOut.transferRanges(newEndpoint, table, Arrays.asList(range), callback, OperationType.UNBOOTSTRAP); } }); } @@ -1979,6 +1984,7 @@ public class StorageService implements IEndpointStateChangeSubscriber, StorageSe rcf.comment = cfm.getComment(); rcf.keys_cached = cfm.getKeyCacheSize(); rcf.read_repair_chance = cfm.getReadRepairChance(); + rcf.replicate_on_write = cfm.getReplicateOnWrite(); rcf.gc_grace_seconds = cfm.getGcGraceSeconds(); rcf.rows_cached = cfm.getRowCacheSize(); rcf.column_metadata = new RawColumnDefinition[cfm.getColumn_metadata().size()]; diff --git a/src/java/org/apache/cassandra/streaming/OperationType.java b/src/java/org/apache/cassandra/streaming/OperationType.java new file mode 100644 index 0000000000..86a3953478 --- /dev/null +++ b/src/java/org/apache/cassandra/streaming/OperationType.java @@ -0,0 +1,31 @@ +/** + * 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.streaming; + +/** + * Streaming operation type. + */ +public enum OperationType +{ + AES, + BOOTSTRAP, + UNBOOTSTRAP, + RESTORE_REPLICA_COUNT; +} + diff --git a/src/java/org/apache/cassandra/streaming/PendingFile.java b/src/java/org/apache/cassandra/streaming/PendingFile.java index 0b7299fad7..cc0f2ff6ff 100644 --- a/src/java/org/apache/cassandra/streaming/PendingFile.java +++ b/src/java/org/apache/cassandra/streaming/PendingFile.java @@ -52,20 +52,23 @@ public class PendingFile public final Descriptor desc; public final String component; public final List> sections; + public final OperationType type; public final long size; public long progress; public PendingFile(Descriptor desc, PendingFile pf) { - this(null, desc, pf.component, pf.sections); + this(null, desc, pf.component, pf.sections, pf.type); } - public PendingFile(SSTable sstable, Descriptor desc, String component, List> sections) + public PendingFile(SSTable sstable, Descriptor desc, String component, List> sections, OperationType type) { this.sstable = sstable; this.desc = desc; this.component = component; this.sections = sections; + this.type = type; + long tempSize = 0; for(Pair section : sections) { @@ -115,6 +118,7 @@ public class PendingFile { dos.writeLong(section.left); dos.writeLong(section.right); } + dos.writeUTF(sc.type.name()); } public PendingFile deserialize(DataInputStream dis) throws IOException @@ -129,7 +133,8 @@ public class PendingFile List> sections = new ArrayList>(count); for (int i = 0; i < count; i++) sections.add(new Pair(Long.valueOf(dis.readLong()), Long.valueOf(dis.readLong()))); - return new PendingFile(null, desc, component, sections); + OperationType type = OperationType.valueOf(dis.readUTF()); + return new PendingFile(null, desc, component, sections, type); } } } diff --git a/src/java/org/apache/cassandra/streaming/StreamIn.java b/src/java/org/apache/cassandra/streaming/StreamIn.java index 2b835e90f7..4a0326c221 100644 --- a/src/java/org/apache/cassandra/streaming/StreamIn.java +++ b/src/java/org/apache/cassandra/streaming/StreamIn.java @@ -49,19 +49,19 @@ public class StreamIn /** * Request ranges to be transferred from source to local node */ - public static void requestRanges(InetAddress source, String tableName, Collection ranges) + public static void requestRanges(InetAddress source, String tableName, Collection ranges, OperationType type) { - requestRanges(source, tableName, ranges, null); + requestRanges(source, tableName, ranges, null, type); } - public static void requestRanges(InetAddress source, String tableName, Collection ranges, Runnable callback) + public static void requestRanges(InetAddress source, String tableName, Collection ranges, Runnable callback, OperationType type) { assert ranges.size() > 0; if (logger.isDebugEnabled()) logger.debug("Requesting from {} ranges {}", source, StringUtils.join(ranges, ", ")); StreamInSession session = StreamInSession.create(source, callback); - Message message = new StreamRequestMessage(FBUtilities.getLocalAddress(), ranges, tableName, session.getSessionId()).makeMessage(); + Message message = new StreamRequestMessage(FBUtilities.getLocalAddress(), ranges, tableName, session.getSessionId(), type).makeMessage(); MessagingService.instance.sendOneWay(message, source); } diff --git a/src/java/org/apache/cassandra/streaming/StreamInSession.java b/src/java/org/apache/cassandra/streaming/StreamInSession.java index 5243a9a843..5d6d745373 100644 --- a/src/java/org/apache/cassandra/streaming/StreamInSession.java +++ b/src/java/org/apache/cassandra/streaming/StreamInSession.java @@ -107,7 +107,7 @@ public class StreamInSession if (logger.isDebugEnabled()) logger.debug("Finished {}. Sending ack to {}", remoteFile, this); - Future future = CompactionManager.instance.submitSSTableBuild(localFile.desc); + Future future = CompactionManager.instance.submitSSTableBuild(localFile.desc, remoteFile.type); buildFutures.add(future); files.remove(remoteFile); diff --git a/src/java/org/apache/cassandra/streaming/StreamOut.java b/src/java/org/apache/cassandra/streaming/StreamOut.java index e9bd761c23..ecced13be1 100644 --- a/src/java/org/apache/cassandra/streaming/StreamOut.java +++ b/src/java/org/apache/cassandra/streaming/StreamOut.java @@ -65,7 +65,7 @@ public class StreamOut /** * Split out files for all tables on disk locally for each range and then stream them to the target endpoint. */ - public static void transferRanges(InetAddress target, String tableName, Collection ranges, Runnable callback) + public static void transferRanges(InetAddress target, String tableName, Collection ranges, Runnable callback, OperationType type) { assert ranges.size() > 0; @@ -79,7 +79,7 @@ public class StreamOut { Table table = flushSSTable(tableName); // send the matching portion of every sstable in the keyspace - transferSSTables(session, table.getAllSSTables(), ranges); + transferSSTables(session, table.getAllSSTables(), ranges, type); } catch (IOException e) { @@ -117,7 +117,7 @@ public class StreamOut /** * Split out files for all tables on disk locally for each range and then stream them to the target endpoint. */ - public static void transferRangesForRequest(StreamOutSession session, Collection ranges) + public static void transferRangesForRequest(StreamOutSession session, Collection ranges, OperationType type) { assert ranges.size() > 0; @@ -128,7 +128,7 @@ public class StreamOut { Table table = flushSSTable(session.table); // send the matching portion of every sstable in the keyspace - List pending = createPendingFiles(table.getAllSSTables(), ranges); + List pending = createPendingFiles(table.getAllSSTables(), ranges, type); session.addFilesToStream(pending); session.begin(); } @@ -141,9 +141,9 @@ public class StreamOut /** * Transfers matching portions of a group of sstables from a single table to the target endpoint. */ - public static void transferSSTables(StreamOutSession session, Collection sstables, Collection ranges) throws IOException + public static void transferSSTables(StreamOutSession session, Collection sstables, Collection ranges, OperationType type) throws IOException { - List pending = createPendingFiles(sstables, ranges); + List pending = createPendingFiles(sstables, ranges, type); if (pending.size() > 0) { @@ -157,7 +157,7 @@ public class StreamOut } // called prior to sending anything. - private static List createPendingFiles(Collection sstables, Collection ranges) + private static List createPendingFiles(Collection sstables, Collection ranges, OperationType type) { List pending = new ArrayList(); for (SSTableReader sstable : sstables) @@ -166,7 +166,7 @@ public class StreamOut List> sections = sstable.getPositionsForRanges(ranges); if (sections.isEmpty()) continue; - pending.add(new PendingFile(sstable, desc, SSTable.COMPONENT_DATA, sections)); + pending.add(new PendingFile(sstable, desc, SSTable.COMPONENT_DATA, sections, type)); } logger.info("Stream context metadata {}, {} sstables.", pending, sstables.size()); return pending; diff --git a/src/java/org/apache/cassandra/streaming/StreamRequestMessage.java b/src/java/org/apache/cassandra/streaming/StreamRequestMessage.java index 094bce7e7b..5cc82f1835 100644 --- a/src/java/org/apache/cassandra/streaming/StreamRequestMessage.java +++ b/src/java/org/apache/cassandra/streaming/StreamRequestMessage.java @@ -66,13 +66,15 @@ class StreamRequestMessage // if these are specified, file shoud not be. protected final Collection ranges; protected final String table; + protected final OperationType type; - StreamRequestMessage(InetAddress target, Collection ranges, String table, long sessionId) + StreamRequestMessage(InetAddress target, Collection ranges, String table, long sessionId, OperationType type) { this.target = target; this.ranges = ranges; this.table = table; this.sessionId = sessionId; + this.type = type; file = null; } @@ -81,6 +83,7 @@ class StreamRequestMessage this.target = target; this.file = file; this.sessionId = sessionId; + this.type = file.type; ranges = null; table = null; } @@ -114,6 +117,7 @@ class StreamRequestMessage sb.append(range); sb.append(" "); } + sb.append(type); } else { @@ -142,6 +146,7 @@ class StreamRequestMessage { AbstractBounds.serializer().serialize(range, dos); } + dos.writeUTF(srm.type.name()); } } @@ -164,7 +169,8 @@ class StreamRequestMessage { ranges.add((Range) AbstractBounds.serializer().deserialize(dis)); } - return new StreamRequestMessage(target, ranges, table, sessionId); + OperationType type = OperationType.valueOf(dis.readUTF()); + return new StreamRequestMessage(target, ranges, table, sessionId, type); } } } diff --git a/src/java/org/apache/cassandra/streaming/StreamRequestVerbHandler.java b/src/java/org/apache/cassandra/streaming/StreamRequestVerbHandler.java index a9fea6dcd1..67aea4b577 100644 --- a/src/java/org/apache/cassandra/streaming/StreamRequestVerbHandler.java +++ b/src/java/org/apache/cassandra/streaming/StreamRequestVerbHandler.java @@ -52,7 +52,7 @@ public class StreamRequestVerbHandler implements IVerbHandler logger.debug(srm.toString()); StreamOutSession session = StreamOutSession.create(srm.table, message.getFrom(), srm.sessionId); - StreamOut.transferRangesForRequest(session, srm.ranges); + StreamOut.transferRangesForRequest(session, srm.ranges, srm.type); } catch (IOException ex) { diff --git a/src/java/org/apache/cassandra/thrift/CassandraServer.java b/src/java/org/apache/cassandra/thrift/CassandraServer.java index 1e6d75de68..24d7ff970a 100644 --- a/src/java/org/apache/cassandra/thrift/CassandraServer.java +++ b/src/java/org/apache/cassandra/thrift/CassandraServer.java @@ -28,6 +28,7 @@ import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.Map.Entry; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.Future; @@ -72,6 +73,7 @@ import org.apache.cassandra.scheduler.IRequestScheduler; import org.apache.cassandra.service.ClientState; import org.apache.cassandra.service.StorageProxy; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.utils.FBUtilities; import org.apache.thrift.TException; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -269,7 +271,6 @@ public class CassandraServer implements Cassandra.Iface logger.debug("multiget_slice"); state().hasColumnFamilyAccess(column_parent.column_family, Permission.READ); - return multigetSliceInternal(state().getKeyspace(), keys, column_parent, predicate, consistency_level); } @@ -301,11 +302,9 @@ public class CassandraServer implements Cassandra.Iface return getSlice(commands, consistency_level); } - public ColumnOrSuperColumn get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) + private ColumnOrSuperColumn internal_get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException { - logger.debug("get"); - state().hasColumnFamilyAccess(column_path.column_family, Permission.READ); String keyspace = state().getKeyspace(); @@ -329,6 +328,14 @@ public class CassandraServer implements Cassandra.Iface return tcolumns.get(0); } + public ColumnOrSuperColumn get(ByteBuffer key, ColumnPath column_path, ConsistencyLevel consistency_level) + throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException + { + logger.debug("get"); + + return internal_get(key, column_path, consistency_level); + } + public int get_count(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException { @@ -356,11 +363,9 @@ public class CassandraServer implements Cassandra.Iface return counts; } - public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) + private void internal_insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException { - logger.debug("insert"); - state().hasColumnFamilyAccess(column_parent.column_family, Permission.WRITE); ThriftValidation.validateKey(key); @@ -379,11 +384,17 @@ public class CassandraServer implements Cassandra.Iface doInsert(consistency_level, Arrays.asList(rm)); } - public void batch_mutate(Map>> mutation_map, ConsistencyLevel consistency_level) + public void insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException + { + logger.debug("insert"); + + internal_insert(key, column_parent, column, consistency_level); + } + + private void internal_batch_mutate(Map>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException { - logger.debug("batch_mutate"); - List cfamsSeen = new ArrayList(); List rowMutations = new ArrayList(); @@ -415,11 +426,17 @@ public class CassandraServer implements Cassandra.Iface doInsert(consistency_level, rowMutations); } - public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) + public void batch_mutate(Map>> mutation_map, ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException { - logger.debug("remove"); + logger.debug("batch_mutate"); + internal_batch_mutate(mutation_map, consistency_level); + } + + private void internal_remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException + { state().hasColumnFamilyAccess(column_path.column_family, Permission.WRITE); ThriftValidation.validateKey(key); @@ -431,6 +448,14 @@ public class CassandraServer implements Cassandra.Iface doInsert(consistency_level, Arrays.asList(rm)); } + public void remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException + { + logger.debug("remove"); + + internal_remove(key, column_path, timestamp, consistency_level); + } + private void doInsert(ConsistencyLevel consistency_level, List mutations) throws UnavailableException, TimedOutException { try @@ -898,6 +923,7 @@ public class CassandraServer implements Cassandra.Iface cf_def.row_cache_size, cf_def.key_cache_size, cf_def.read_repair_chance, + cf_def.replicate_on_write, cf_def.isSetGc_grace_seconds() ? cf_def.gc_grace_seconds : CFMetaData.DEFAULT_GC_GRACE_SECONDS, DatabaseDescriptor.getComparator(cf_def.default_validation_class), cf_def.isSetMin_compaction_threshold() ? cf_def.min_compaction_threshold : CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD, @@ -946,5 +972,190 @@ public class CassandraServer implements Cassandra.Iface return StorageProxy.describeSchemaVersions(); } + // counter methods + + private Column getCounterColumn(CounterColumn column) + { + return new Column(column.name, FBUtilities.toByteBuffer(column.value), System.currentTimeMillis()); + } + + public void add(ByteBuffer key, ColumnParent column_parent, CounterColumn column, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + logger.debug("add"); + + if (ConsistencyLevel.ONE != consistency_level) + { + throw new InvalidRequestException("Commutative CFs only support ConsistencyLevel.ONE"); + } + + String keyspace = state().getKeyspace(); + ThriftValidation.validateCommutative(keyspace, column_parent.column_family); + + internal_insert(key, column_parent, getCounterColumn(column), consistency_level); + } + + private Mutation getMutation(CounterMutation counterMutation) + { + Mutation mutation = new Mutation(); + + if (counterMutation.isSetCounter()) + { + Counter counter = counterMutation.counter; + ColumnOrSuperColumn cosc = new ColumnOrSuperColumn(); + if (counter.isSetColumn()) + { + Column c = new Column(counter.column.name, FBUtilities.toByteBuffer(counter.column.value), System.currentTimeMillis()); + cosc.setColumn(c); + } + + if (counter.isSetSuper_column()) + { + List subcolumns = new ArrayList(counter.super_column.columns.size()); + for (CounterColumn subcol : counter.super_column.columns) + { + subcolumns.add(new Column(subcol.name, FBUtilities.toByteBuffer(subcol.value), System.currentTimeMillis())); + } + SuperColumn sc = new SuperColumn(counter.super_column.name, subcolumns); + cosc.setSuper_column(sc); + } + mutation.setColumn_or_supercolumn(cosc); + } + + if (counterMutation.isSetDeletion()) + { + Deletion deletion = new Deletion(System.currentTimeMillis()); + if (counterMutation.deletion.isSetSuper_column()) + deletion.setSuper_column(counterMutation.deletion.super_column); + if (counterMutation.deletion.isSetPredicate()) + deletion.setPredicate(counterMutation.deletion.predicate); + mutation.setDeletion(deletion); + } + + return mutation; + } + + public void batch_add(Map>> updateMap, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + logger.debug("batch_add"); + + if (ConsistencyLevel.ONE != consistency_level) + { + throw new InvalidRequestException("Commutative CFs only support ConsistencyLevel.ONE"); + } + + String keyspace = state().getKeyspace(); + + Map>> mutation_map = new HashMap>>(); + + for (Entry>> entry : updateMap.entrySet()) + { + Map> valueMap = new HashMap>(entry.getValue().size()); + + for (Entry> innerEntry : entry.getValue().entrySet()) + { + ThriftValidation.validateCommutative(keyspace, innerEntry.getKey()); + + List mutations = new ArrayList(innerEntry.getValue().size()); + for (CounterMutation cm : innerEntry.getValue()) + { + mutations.add(getMutation(cm)); + } + valueMap.put(innerEntry.getKey(), mutations); + } + + mutation_map.put(entry.getKey(), valueMap); + } + + internal_batch_mutate(mutation_map, consistency_level); + } + + private Counter getCounter(ColumnOrSuperColumn cosc) + { + if (cosc.isSetColumn()) { + return new Counter().setColumn(new CounterColumn(cosc.column.name, cosc.column.value.getLong(cosc.column.value.arrayOffset()))); + } else if(cosc.isSetSuper_column()) { + List cc = new ArrayList(cosc.super_column.columns.size()); + for (Column col : cosc.super_column.columns) + { + cc.add(new CounterColumn(col.name, col.value.getLong(col.value.arrayOffset()))); + } + return new Counter().setSuper_column(new CounterSuperColumn(cosc.super_column.name, cc)); + } + return null; + } + + public Counter get_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) + throws InvalidRequestException, NotFoundException, UnavailableException, TimedOutException, TException + { + logger.debug("get_counter"); + + String keyspace = state().getKeyspace(); + ThriftValidation.validateCommutative(keyspace, path.column_family); + + return getCounter(internal_get(key, path, consistency_level)); + } + + private List getCounters(List cosc) + { + List rv = new ArrayList(cosc.size()); + for (ColumnOrSuperColumn columnOrSuperColumn : cosc) + { + Counter c = getCounter(columnOrSuperColumn); + if (c != null) { + rv.add(c); + } + } + return rv; + } + + public List get_counter_slice(ByteBuffer key, ColumnParent column_parent, SlicePredicate predicate, + ConsistencyLevel consistency_level) throws InvalidRequestException, UnavailableException, TimedOutException, + TException + { + if (logger.isDebugEnabled()) + logger.debug("get_counter_slice"); + + String keyspace = state().getKeyspace(); + ThriftValidation.validateCommutative(keyspace, column_parent.column_family); + + state().hasColumnFamilyAccess(column_parent.column_family, Permission.READ); + List cosc = multigetSliceInternal(state().getKeyspace(), Collections.singletonList(key), column_parent, predicate, consistency_level).get(key); + return getCounters(cosc); + } + + public Map> multiget_counter_slice(List keys, ColumnParent column_parent, + SlicePredicate predicate, ConsistencyLevel consistency_level) throws InvalidRequestException, + UnavailableException, TimedOutException, TException + { + if (logger.isDebugEnabled()) + logger.debug("multiget_counter_slice"); + + String keyspace = state().getKeyspace(); + ThriftValidation.validateCommutative(keyspace, column_parent.column_family); + + state().hasColumnFamilyAccess(column_parent.column_family, Permission.READ); + Map> slices = multigetSliceInternal(state().getKeyspace(), keys, column_parent, predicate, consistency_level); + Map> rv = new HashMap>(slices.size()); + for (Entry> entry : slices.entrySet()) + { + rv.put(entry.getKey(), getCounters(entry.getValue())); + } + return rv; + } + + public void remove_counter(ByteBuffer key, ColumnPath path, ConsistencyLevel consistency_level) + throws InvalidRequestException, UnavailableException, TimedOutException, TException + { + if (logger.isDebugEnabled()) + logger.debug("remove_counter"); + + String keyspace = state().getKeyspace(); + ThriftValidation.validateCommutative(keyspace, path.column_family); + + internal_remove(key, path, System.currentTimeMillis(), consistency_level); + } + // main method moved to CassandraDaemon } diff --git a/src/java/org/apache/cassandra/thrift/ThriftValidation.java b/src/java/org/apache/cassandra/thrift/ThriftValidation.java index 9e383ab810..04cc77d779 100644 --- a/src/java/org/apache/cassandra/thrift/ThriftValidation.java +++ b/src/java/org/apache/cassandra/thrift/ThriftValidation.java @@ -25,6 +25,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.Set; +import org.apache.cassandra.config.CFMetaData; import org.apache.cassandra.config.ConfigurationException; import org.apache.cassandra.config.DatabaseDescriptor; import org.apache.cassandra.db.ColumnFamily; @@ -432,4 +433,28 @@ public class ThriftValidation throw new InvalidRequestException(e.getMessage()); } } + + public static CFMetaData validateCFMetaData(String tablename, String cfName) throws InvalidRequestException + { + if (cfName.isEmpty()) + { + throw new InvalidRequestException("non-empty columnfamily is required"); + } + CFMetaData metadata = DatabaseDescriptor.getCFMetaData(tablename, cfName); + if (metadata == null) + { + throw new InvalidRequestException("unconfigured columnfamily " + cfName); + } + return metadata; + } + + static void validateCommutative(String tablename, String cfName) throws InvalidRequestException + { + validateTable(tablename); + CFMetaData metadata = validateCFMetaData(tablename, cfName); + if (!metadata.getDefaultValidator().isCommutative()) + { + throw new InvalidRequestException("not commutative columnfamily " + cfName); + } + } } diff --git a/src/java/org/apache/cassandra/utils/FBUtilities.java b/src/java/org/apache/cassandra/utils/FBUtilities.java index be2bc73424..91ee290eb8 100644 --- a/src/java/org/apache/cassandra/utils/FBUtilities.java +++ b/src/java/org/apache/cassandra/utils/FBUtilities.java @@ -152,6 +152,70 @@ public class FBUtilities return new Pair(midpoint, remainder); } + /** + * Copy bytes from int into bytes starting from offset. + * @param bytes Target array + * @param offset Offset into the array + * @param i Value to write + */ + public static void copyIntoBytes(byte[] bytes, int offset, int i) + { + bytes[offset] = (byte)( ( i >>> 24 ) & 0xFF ); + bytes[offset+1] = (byte)( ( i >>> 16 ) & 0xFF ); + bytes[offset+2] = (byte)( ( i >>> 8 ) & 0xFF ); + bytes[offset+3] = (byte)( i & 0xFF ); + } + + /** + * @param i Write this int to an array + * @return 4-byte array containing the int + */ + public static byte[] toByteArray(int i) + { + byte[] bytes = new byte[4]; + copyIntoBytes(bytes, 0, i); + return bytes; + } + + /** + * @param bytes A byte array containing a serialized integer. + * @param offset Start position of the integer in the array. + * @return The integer value contained in the byte array. + */ + public static int byteArrayToInt(byte[] bytes, int offset) + { + if (bytes.length - offset < 4) + { + throw new IllegalArgumentException("An integer must be 4 bytes in size."); + } + int n = 0; + for ( int i = 0; i < 4; ++i ) + { + n <<= 8; + n |= bytes[offset + i] & 0xFF; + } + return n; + } + + /** + * Convert a byte buffer to an integer. + * Does not change the byte buffer position. + */ + public static int byteBufferToInt(ByteBuffer bytes) + { + if (bytes.remaining() < 4) + { + throw new IllegalArgumentException("An integer must be 4 bytes in size."); + } + int n = 0; + for (int i = 0; i < 4; ++i) + { + n <<= 8; + n |= bytes.array()[bytes.position() + bytes.arrayOffset() + i] & 0xFF; + } + return n; + } + public static ByteBuffer toByteBuffer(int i) { byte[] bytes = new byte[4]; @@ -162,21 +226,71 @@ public class FBUtilities return ByteBuffer.wrap(bytes); } - public static int byteBufferToInt(ByteBuffer bytes) + /** + * Copy bytes from long into bytes starting from offset. + * @param bytes Target array + * @param offset Offset into the array + * @param l Value to write + */ + public static void copyIntoBytes(byte[] bytes, int offset, long l) { - if (bytes.remaining() < 4 ) + bytes[offset] = (byte)( ( l >>> 56 ) & 0xFF ); + bytes[offset+1] = (byte)( ( l >>> 48 ) & 0xFF ); + bytes[offset+2] = (byte)( ( l >>> 40 ) & 0xFF ); + bytes[offset+3] = (byte)( ( l >>> 32 ) & 0xFF ); + bytes[offset+4] = (byte)( ( l >>> 24 ) & 0xFF ); + bytes[offset+5] = (byte)( ( l >>> 16 ) & 0xFF ); + bytes[offset+6] = (byte)( ( l >>> 8 ) & 0xFF ); + bytes[offset+7] = (byte)( l & 0xFF ); + } + + /** + * @param l Write this long to an array + * @return 8-byte array containing the long + */ + public static byte[] toByteArray(long l) + { + byte[] bytes = new byte[8]; + copyIntoBytes(bytes, 0, l); + return bytes; + } + + /** + * @param bytes A byte array containing a serialized long. + * @return The long value contained in the byte array. + */ + public static long byteArrayToLong(byte[] bytes) + { + return byteArrayToLong(bytes, 0); + } + + /** + * @param bytes A byte array containing a serialized long. + * @param offset Start position of the long in the array. + * @return The long value contained in the byte array. + */ + public static long byteArrayToLong(byte[] bytes, int offset) + { + if (bytes.length - offset < 8) { - throw new IllegalArgumentException("An integer must be 4 bytes in size."); + throw new IllegalArgumentException("A long must be 8 bytes in size."); } - int n = 0; - for ( int i = 0; i < 4; ++i ) + long n = 0; + for ( int i = 0; i < 8; ++i ) { n <<= 8; - n |= bytes.array()[bytes.position() + bytes.arrayOffset() + i] & 0xFF; + n |= bytes[offset + i] & 0xFF; } return n; } + public static ByteBuffer toByteBuffer(long n) + { + byte[] bytes = new byte[8]; + ByteBuffer bb = ByteBuffer.wrap(bytes).putLong(0, n); + return bb; + } + public static int compareUnsigned(byte[] bytes1, byte[] bytes2, int offset1, int offset2, int len1, int len2) { if (bytes1 == null) @@ -196,6 +310,38 @@ public class FBUtilities if ((len1 - offset1) == (len2 - offset2)) return 0; else return ((len1 - offset1) < (len2 - offset2)) ? -1 : 1; } + + /** + * Compare two byte[] at specified offsets for length. Compares the non equal bytes as unsigned. + * @param bytes1 First array to compare. + * @param offset1 Position to start the comparison at in the first array. + * @param bytes2 Second array to compare. + * @param offset2 Position to start the comparison at in the second array. + * @param length How many bytes to compare? + * @return -1 if byte1 is less than byte2, 1 if byte2 is less than byte1 or 0 if equal. + */ + public static int compareByteSubArrays(byte[] bytes1, int offset1, byte[] bytes2, int offset2, int length) + { + if ( null == bytes1 ) + { + if ( null == bytes2) return 0; + else return -1; + } + if (null == bytes2 ) return 1; + + assert bytes1.length >= (offset1 + length) : "The first byte array isn't long enough for the specified offset and length."; + assert bytes2.length >= (offset2 + length) : "The second byte array isn't long enough for the specified offset and length."; + for ( int i = 0; i < length; i++ ) + { + byte byte1 = bytes1[offset1+i]; + byte byte2 = bytes2[offset2+i]; + if ( byte1 == byte2 ) + continue; + // compare non-equal bytes as unsigned + return (byte1 & 0xFF) < (byte2 & 0xFF) ? -1 : 1; + } + return 0; + } /** * @return The bitwise XOR of the inputs. The output will be the same length as the @@ -496,12 +642,41 @@ public class FBUtilities return decoded; } - public static ByteBuffer toByteBuffer(long n) + /** + * Thin wrapper around byte[] to provide meaningful equals() and hashCode() operations + * caveat: assumed that wrapped byte[] will not be modified + */ + public static final class ByteArrayWrapper { - byte[] bytes = new byte[8]; - ByteBuffer bb = ByteBuffer.wrap(bytes).putLong(n); - bb.rewind(); - return bb; + public final byte[] data; + + public ByteArrayWrapper(byte[] data) + { + if ( null == data ) + { + throw new NullPointerException(); + } + this.data = data; + } + + public boolean equals(Object other) + { + if ( !( other instanceof ByteArrayWrapper ) ) + { + return false; + } + return Arrays.equals(data, ((ByteArrayWrapper)other).data); + } + + public int hashCode() + { + return Arrays.hashCode(data); + } + + public String toString() + { + return ArrayUtils.toString(data); + } } public static String resourceToFile(String filename) throws ConfigurationException @@ -519,6 +694,10 @@ public class FBUtilities try { InputStream in = FBUtilities.class.getClassLoader().getResourceAsStream("org/apache/cassandra/config/version.properties"); + if (in == null) + { + return "Unknown"; + } Properties props = new Properties(); props.load(in); return props.getProperty("CassandraVersion"); diff --git a/test/conf/cassandra.yaml b/test/conf/cassandra.yaml index 2d619ec085..96b3f0abe7 100644 --- a/test/conf/cassandra.yaml +++ b/test/conf/cassandra.yaml @@ -70,6 +70,14 @@ keyspaces: column_type: Super compare_subcolumns_with: UTF8Type + - name: Counter1 + column_type: Standard + default_validation_class: CounterColumnType + + - name: SuperCounter1 + column_type: Super + default_validation_class: CounterColumnType + - name: Indexed1 column_metadata: - name: birthdate @@ -135,3 +143,7 @@ keyspaces: replication_factor: 2 column_families: - name: Standard1 + + - name: Counter1 + column_type: Standard + default_validation_class: CounterColumnType diff --git a/test/system/__init__.py b/test/system/__init__.py index 246afbbac5..36118becf8 100644 --- a/test/system/__init__.py +++ b/test/system/__init__.py @@ -170,6 +170,8 @@ class ThriftTester(BaseTester): Cassandra.CfDef('Keyspace1', 'Super2', column_type='Super', subcomparator_type='LongType'), Cassandra.CfDef('Keyspace1', 'Super3', column_type='Super', subcomparator_type='LongType'), Cassandra.CfDef('Keyspace1', 'Super4', column_type='Super', subcomparator_type='UTF8Type'), + Cassandra.CfDef('Keyspace1', 'Counter1', default_validation_class='CounterColumnType'), + Cassandra.CfDef('Keyspace1', 'SuperCounter1', column_type='Super', default_validation_class='CounterColumnType'), Cassandra.CfDef('Keyspace1', 'Indexed1', column_metadata=[Cassandra.ColumnDef('birthdate', 'LongType', Cassandra.IndexType.KEYS, 'birthdate')]), ]) diff --git a/test/system/test_thrift_server.py b/test/system/test_thrift_server.py index 3ca9792914..ab82d77300 100644 --- a/test/system/test_thrift_server.py +++ b/test/system/test_thrift_server.py @@ -1467,6 +1467,255 @@ class TestMutations(ThriftTester): client.describe_ring('system') _expect_exception(req, InvalidRequestException) + def test_incr_decr_standard_add(self): + _set_keyspace('Keyspace1') + + d1 = 12 + d2 = -21 + d3 = 35 + # insert positive and negative values and check the counts + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(0.1) + rv1 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1 + + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d2), ConsistencyLevel.ONE) + time.sleep(0.1) + rv2 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == (d1+d2) + + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d3), ConsistencyLevel.ONE) + time.sleep(0.1) + rv3 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv3.column.value == (d1+d2+d3) + + def test_incr_decr_super_add(self): + _set_keyspace('Keyspace1') + + d1 = -234 + d2 = 52345 + d3 = 3123 + + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c2', d2), ConsistencyLevel.ONE) + time.sleep(0.1) + rv1 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1'), ConsistencyLevel.ONE) + assert rv1.super_column.columns[0].value == d1 + assert rv1.super_column.columns[1].value == d2 + + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d2), ConsistencyLevel.ONE) + time.sleep(0.1) + rv2 = client.get_counter('key1', ColumnPath('SuperCounter1', 'sc1', 'c1'), ConsistencyLevel.ONE) + assert rv2.column.value == (d1+d2) + + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d3), ConsistencyLevel.ONE) + time.sleep(0.1) + rv3 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + assert rv3.column.value == (d1+d2+d3) + + def test_incr_standard_remove(self): + _set_keyspace('Keyspace1') + + d1 = 124 + + # insert value and check it exists + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv1 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1 + + # remove the previous column and check that it is gone + client.remove_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + # insert again and this time delete the whole row, check that it is gone + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv2 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == d1 + client.remove_counter('key1', ColumnPath(column_family='Counter1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + def test_incr_super_remove(self): + _set_keyspace('Keyspace1') + + d1 = 52345 + + # insert value and check it exists + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv1 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1 + + # remove the previous column and check that it is gone + client.remove_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1')) + + # insert again and this time delete the whole row, check that it is gone + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv2 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == d1 + client.remove_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1')) + + def test_incr_decr_standard_remove(self): + _set_keyspace('Keyspace1') + + d1 = 124 + + # insert value and check it exists + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv1 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1 + + # remove the previous column and check that it is gone + client.remove_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + # insert again and this time delete the whole row, check that it is gone + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv2 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == d1 + client.remove_counter('key1', ColumnPath(column_family='Counter1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + def test_incr_decr_super_remove(self): + _set_keyspace('Keyspace1') + + d1 = 52345 + + # insert value and check it exists + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv1 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1 + + # remove the previous column and check that it is gone + client.remove_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1')) + + # insert again and this time delete the whole row, check that it is gone + client.add('key1', ColumnParent(column_family='SuperCounter1', super_column='sc1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + time.sleep(5) + rv2 = client.get_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == d1 + client.remove_counter('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1'), ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='SuperCounter1', super_column='sc1', column='c1')) + + def test_incr_decr_standard_batch_add(self): + _set_keyspace('Keyspace1') + + d1 = 12 + d2 = -21 + update_map = {'key1': {'Counter1': [ + CounterMutation(counter=Counter(column=CounterColumn('c1', d1))), + CounterMutation(counter=Counter(column=CounterColumn('c1', d2))), + ]}} + + # insert positive and negative values and check the counts + client.batch_add(update_map, ConsistencyLevel.ONE) + time.sleep(0.1) + rv1 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1+d2 + + def test_incr_decr_standard_batch_remove(self): + _set_keyspace('Keyspace1') + + d1 = 12 + d2 = -21 + + # insert positive and negative values and check the counts + update_map = {'key1': {'Counter1': [ + CounterMutation(counter=Counter(column=CounterColumn('c1', d1))), + CounterMutation(counter=Counter(column=CounterColumn('c1', d2))), + ]}} + client.batch_add(update_map, ConsistencyLevel.ONE) + time.sleep(5) + rv1 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv1.column.value == d1+d2 + + # remove the previous column and check that it is gone + update_map = {'key1': {'Counter1': [ + CounterMutation(deletion=CounterDeletion(predicate=SlicePredicate(column_names=['c1']))), + ]}} + client.batch_add(update_map, ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + # insert again and this time delete the whole row, check that it is gone + update_map = {'key1': {'Counter1': [ + CounterMutation(counter=Counter(column=CounterColumn('c1', d1))), + CounterMutation(counter=Counter(column=CounterColumn('c1', d2))), + ]}} + client.batch_add(update_map, ConsistencyLevel.ONE) + time.sleep(5) + rv2 = client.get_counter('key1', ColumnPath(column_family='Counter1', column='c1'), ConsistencyLevel.ONE) + assert rv2.column.value == d1+d2 + + update_map = {'key1': {'Counter1': [ + CounterMutation(deletion=CounterDeletion()), + ]}} + client.batch_add(update_map, ConsistencyLevel.ONE) + time.sleep(5) + _assert_no_columnpath('key1', ColumnPath(column_family='Counter1', column='c1')) + + def test_incr_decr_standard_slice(self): + _set_keyspace('Keyspace1') + + d1 = 12 + d2 = -21 + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c1', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c2', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c3', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c3', d2), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c4', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c5', d1), ConsistencyLevel.ONE) + + time.sleep(0.1) + # insert positive and negative values and check the counts + counters = client.get_counter_slice('key1', ColumnParent('Counter1'), SlicePredicate(['c3', 'c4']), ConsistencyLevel.ONE) + + assert counters[0].column.value == d1+d2 + assert counters[1].column.value == d1 + + def test_incr_decr_standard_muliget_slice(self): + _set_keyspace('Keyspace1') + + d1 = 12 + d2 = -21 + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c2', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c3', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c3', d2), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c4', d1), ConsistencyLevel.ONE) + client.add('key1', ColumnParent(column_family='Counter1'), CounterColumn('c5', d1), ConsistencyLevel.ONE) + + client.add('key2', ColumnParent(column_family='Counter1'), CounterColumn('c2', d1), ConsistencyLevel.ONE) + client.add('key2', ColumnParent(column_family='Counter1'), CounterColumn('c3', d1), ConsistencyLevel.ONE) + client.add('key2', ColumnParent(column_family='Counter1'), CounterColumn('c3', d2), ConsistencyLevel.ONE) + client.add('key2', ColumnParent(column_family='Counter1'), CounterColumn('c4', d1), ConsistencyLevel.ONE) + client.add('key2', ColumnParent(column_family='Counter1'), CounterColumn('c5', d1), ConsistencyLevel.ONE) + + + time.sleep(0.1) + # insert positive and negative values and check the counts + counters = client.multiget_counter_slice(['key1', 'key2'], ColumnParent('Counter1'), SlicePredicate(['c3', 'c4']), ConsistencyLevel.ONE) + + assert counters['key1'][0].column.value == d1+d2 + assert counters['key1'][1].column.value == d1 + assert counters['key2'][0].column.value == d1+d2 + assert counters['key2'][1].column.value == d1 + def test_index_scan(self): _set_keyspace('Keyspace1') client.insert('key1', ColumnParent('Indexed1'), Column('birthdate', _i64(1), 0), ConsistencyLevel.ONE) diff --git a/test/unit/org/apache/cassandra/Util.java b/test/unit/org/apache/cassandra/Util.java index 006d5f802d..66a62ff34f 100644 --- a/test/unit/org/apache/cassandra/Util.java +++ b/test/unit/org/apache/cassandra/Util.java @@ -128,6 +128,27 @@ public class Util return cfStore.getColumnFamily(QueryFilter.getIdentityFilter(key, new QueryPath(cfName))); } + public static byte[] concatByteArrays(byte[] first, byte[]... remaining) + { + int length = first.length; + for (byte[] array : remaining) + { + length += array.length; + } + + byte[] result = new byte[length]; + System.arraycopy(first, 0, result, 0, first.length); + int offset = first.length; + + for (byte[] array : remaining) + { + System.arraycopy(array, 0, result, offset, array.length); + offset += array.length; + } + + return result; + } + public static ColumnFamily cloneAndRemoveDeleted(ColumnFamily cf, int gcBefore) { return ColumnFamilyStore.removeDeleted(cf.cloneMe(), gcBefore); diff --git a/test/unit/org/apache/cassandra/db/CounterColumnTest.java b/test/unit/org/apache/cassandra/db/CounterColumnTest.java new file mode 100644 index 0000000000..f41ae6adac --- /dev/null +++ b/test/unit/org/apache/cassandra/db/CounterColumnTest.java @@ -0,0 +1,346 @@ +/* +* 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.db; + +import static org.junit.Assert.*; + +import java.io.ByteArrayInputStream; +import java.io.DataInputStream; +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; + +import org.apache.commons.lang.ArrayUtils; + +import org.junit.Test; + +import org.apache.cassandra.Util; +import org.apache.cassandra.db.context.CounterContext; +import org.apache.cassandra.db.marshal.AbstractCommutativeType; +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.io.util.DataOutputBuffer; +import org.apache.cassandra.utils.ByteBufferUtil; +import org.apache.cassandra.utils.FBUtilities; + +public class CounterColumnTest +{ + private static final CounterContext cc = new CounterContext(); + + private static final int idLength; + private static final int clockLength; + private static final int countLength; + + private static final int stepLength; + + static + { + idLength = 4; // size of int + clockLength = 8; // size of long + countLength = 8; // size of long + + stepLength = idLength + clockLength + countLength; + } + + @Test + public void testCreate() throws UnknownHostException + { + AbstractCommutativeType type = CounterColumnType.instance; + long delta = 3L; + CounterColumn column = (CounterColumn)type.createColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(delta), 1L); + assert delta == column.value().getLong(column.value().arrayOffset()); + assert 0 == column.partitionedCounter().length; + + InetAddress node = InetAddress.getByAddress(FBUtilities.toByteArray(1)); + column.update(node); + assert delta == column.value().getLong(column.value().arrayOffset()); + assert 1 == FBUtilities.byteArrayToInt( column.partitionedCounter(), 0*stepLength); + assert 1L == FBUtilities.byteArrayToLong(column.partitionedCounter(), 0*stepLength + idLength); + assert 3L == FBUtilities.byteArrayToLong(column.partitionedCounter(), 0*stepLength + idLength + clockLength); + } + + @Test + public void testUpdate() throws UnknownHostException + { + CounterColumn c = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 0L); + assert 0L == c.value().getLong(c.value().arrayOffset()); + + assert c.partitionedCounter().length == 0 : "badly formatted initial context"; + + c.value = FBUtilities.toByteBuffer(1L); + c.update(InetAddress.getByAddress(FBUtilities.toByteArray(1))); + assert 1L == c.value().getLong(c.value().arrayOffset()); + + assert c.partitionedCounter().length == stepLength; + + assert 1 == FBUtilities.byteArrayToInt( c.partitionedCounter(), 0*stepLength); + assert 1L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 0*stepLength + idLength); + assert 1L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 0*stepLength + idLength + clockLength); + + c.value = FBUtilities.toByteBuffer(3L); + c.update(InetAddress.getByAddress(FBUtilities.toByteArray(2))); + + c.value = FBUtilities.toByteBuffer(2L); + c.update(InetAddress.getByAddress(FBUtilities.toByteArray(2))); + + c.value = FBUtilities.toByteBuffer(9L); + c.update(InetAddress.getByAddress(FBUtilities.toByteArray(2))); + + assert 15L == c.value().getLong(c.value().arrayOffset()); + + assert c.partitionedCounter().length == (2 * stepLength); + + assert 2 == FBUtilities.byteArrayToInt(c.partitionedCounter(), 0*stepLength); + assert 3L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 0*stepLength + idLength); + assert 14L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 0*stepLength + idLength + clockLength); + + assert 1 == FBUtilities.byteArrayToInt(c.partitionedCounter(), 1*stepLength); + assert 1L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 1*stepLength + idLength); + assert 1L == FBUtilities.byteArrayToLong(c.partitionedCounter(), 1*stepLength + idLength + clockLength); + } + + @Test + public void testReconcile() throws UnknownHostException + { + IColumn left; + IColumn right; + IColumn reconciled; + + // tombstone + tombstone + left = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 1L); + right = new DeletedColumn(ByteBufferUtil.bytes("x"), 2, 2L); + + assert left.reconcile(right).timestamp() == right.timestamp(); + assert right.reconcile(left).timestamp() == right.timestamp(); + + // tombstone > live + left = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 2L); + right = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 1L); + + assert left.reconcile(right) == left; + + // tombstone < live last delete + left = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 1L); + right = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 4L, new byte[0], 2L); + + assert left.reconcile(right) == right; + + // tombstone == live last delete + left = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 2L); + right = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 4L, new byte[0], 2L); + + assert left.reconcile(right) == right; + + // tombstone > live last delete + left = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 4L); + right = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 9L, new byte[0], 1L); + + reconciled = left.reconcile(right); + assert reconciled.name() == right.name(); + assert reconciled.value() == right.value(); + assert reconciled.timestamp() == right.timestamp(); + assert ((CounterColumn)reconciled).partitionedCounter() == ((CounterColumn)right).partitionedCounter(); + assert ((CounterColumn)reconciled).timestampOfLastDelete() == left.timestamp(); + + // live < tombstone + left = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 1L); + right = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 2L); + + assert left.reconcile(right) == right; + + // live last delete > tombstone + left = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 4L, new byte[0], 2L); + right = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 1L); + + assert left.reconcile(right) == left; + + // live last delete == tombstone + left = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 4L, new byte[0], 2L); + right = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 2L); + + assert left.reconcile(right) == left; + + // live last delete < tombstone + left = new CounterColumn(ByteBufferUtil.bytes("x"), FBUtilities.toByteBuffer(0L), 9L, new byte[0], 1L); + right = new DeletedColumn(ByteBufferUtil.bytes("x"), 1, 4L); + + reconciled = left.reconcile(right); + assert reconciled.name() == left.name(); + assert reconciled.value() == left.value(); + assert reconciled.timestamp() == left.timestamp(); + assert ((CounterColumn)reconciled).partitionedCounter() == ((CounterColumn)left).partitionedCounter(); + assert ((CounterColumn)reconciled).timestampOfLastDelete() == right.timestamp(); + + // live + live + byte[] context; + + context = new byte[0]; + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(1)), 1L); + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(1)), 0L); + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(1)), 1L); + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(2)), 0L); + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(2)), 5L); + left = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(context)), 9L, context, 1L); + + context = new byte[0]; + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(2)), 4L); + context = cc.update(context, InetAddress.getByAddress(FBUtilities.toByteArray(3)), 2L); + right = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(context)), 3L, context, 4L); + + reconciled = left.reconcile(right); + assert reconciled.name() == left.name(); + assert 9L == reconciled.value().getLong(reconciled.value().arrayOffset()); + assert reconciled.timestamp() == 9L; + + context = ((CounterColumn)reconciled).partitionedCounter(); + assert 3 * stepLength == context.length; + + assert 1 == FBUtilities.byteArrayToInt(context, 0*stepLength); + assert 3L == FBUtilities.byteArrayToLong(context, 0*stepLength + idLength); + assert 2L == FBUtilities.byteArrayToLong(context, 0*stepLength + idLength + clockLength); + + assert 2 == FBUtilities.byteArrayToInt(context, 1*stepLength); + assert 2L == FBUtilities.byteArrayToLong(context, 1*stepLength + idLength); + assert 5L == FBUtilities.byteArrayToLong(context, 1*stepLength + idLength + clockLength); + + assert 3 == FBUtilities.byteArrayToInt(context, 2*stepLength); + assert 1L == FBUtilities.byteArrayToLong(context, 2*stepLength + idLength); + assert 2L == FBUtilities.byteArrayToLong(context, 2*stepLength + idLength + clockLength); + + assert ((CounterColumn)reconciled).timestampOfLastDelete() == 4L; + } + + @Test + public void testDiff() throws UnknownHostException + { + byte[] left; + byte[] right; + + CounterColumn leftCol; + CounterColumn rightCol; + + // timestamp + left = new byte[0]; + leftCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(left)), 1L, left); + + right = new byte[0]; + rightCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(right)), 2L, right); + + assert rightCol == leftCol.diff(rightCol); + assert null == rightCol.diff(leftCol); + + // timestampOfLastDelete + left = new byte[0]; + leftCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(left)), 1L, left, 1L); + + right = new byte[0]; + rightCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(right)), 1L, right, 2L); + + assert rightCol == leftCol.diff(rightCol); + assert null == rightCol.diff(leftCol); + + // equality: equal nodes, all counts same + left = Util.concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(6), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + left = cc.update(left, InetAddress.getByAddress(FBUtilities.toByteArray(3)), 0L); + right = ArrayUtils.clone(left); + + leftCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(left)), 1L, left); + rightCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(right)), 1L, right); + assert null == leftCol.diff(rightCol); + + // greater than: left has superset of nodes (counts equal) + left = Util.concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(6), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(12), FBUtilities.toByteArray(0L), FBUtilities.toByteArray(0L) + ); + right = Util.concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(6), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + + leftCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(left)), 1L, left); + rightCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(right)), 1L, right); + assert null == leftCol.diff(rightCol); + + // less than: right has subset of nodes (counts equal) + assert leftCol == rightCol.diff(leftCol); + + // disjoint: right and left have disjoint node sets + left = Util.concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + right = Util.concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(6), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + + leftCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(left)), 1L, left); + rightCol = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(right)), 1L, right); + assert rightCol == leftCol.diff(rightCol); + assert leftCol == rightCol.diff(leftCol); + } + + @Test + public void testCleanNodeCounts() throws UnknownHostException + { + byte[] context = Util.concatByteArrays( + FBUtilities.toByteArray(1), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(1L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(2L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(4L) + ); + CounterColumn c = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(context)), 1L, context); + + CounterColumn d = c.cleanNodeCounts(InetAddress.getByAddress(FBUtilities.toByteArray(4))); + + assertEquals(7L, d.value().getLong(d.value().arrayOffset())); + } + + @Test + public void testSerializeDeserialize() throws IOException + { + ColumnFamily cf; + + byte[] context = Util.concatByteArrays( + FBUtilities.toByteArray(1), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(1L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(2L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(4L) + ); + CounterColumn original = new CounterColumn(ByteBufferUtil.bytes("x"), ByteBuffer.wrap(cc.total(context)), 1L, context); + + DataOutputBuffer bufOut = new DataOutputBuffer(); + Column.serializer().serialize(original, bufOut); + + ByteArrayInputStream bufIn = new ByteArrayInputStream(bufOut.getData(), 0, bufOut.getLength()); + CounterColumn deserialized = (CounterColumn)Column.serializer().deserialize(new DataInputStream(bufIn)); + + assert original.equals(deserialized); + } +} diff --git a/test/unit/org/apache/cassandra/db/DefsTest.java b/test/unit/org/apache/cassandra/db/DefsTest.java index 05bcaf4963..7ae7d7b97c 100644 --- a/test/unit/org/apache/cassandra/db/DefsTest.java +++ b/test/unit/org/apache/cassandra/db/DefsTest.java @@ -115,6 +115,7 @@ public class DefsTest extends CleanupHelper 1.0, 1.0, 0.5, + false, 100000, null, 500, @@ -766,6 +767,7 @@ public class DefsTest extends CleanupHelper 0, 1.0, 0, + false, CFMetaData.DEFAULT_GC_GRACE_SECONDS, BytesType.instance, CFMetaData.DEFAULT_MIN_COMPACTION_THRESHOLD, diff --git a/test/unit/org/apache/cassandra/db/SuperColumnTest.java b/test/unit/org/apache/cassandra/db/SuperColumnTest.java index cbaf61ba4a..8e4f549c8b 100644 --- a/test/unit/org/apache/cassandra/db/SuperColumnTest.java +++ b/test/unit/org/apache/cassandra/db/SuperColumnTest.java @@ -24,12 +24,16 @@ import org.junit.Test; import static junit.framework.Assert.assertNotNull; import static junit.framework.Assert.assertNull; import static org.apache.cassandra.Util.getBytes; +import static org.apache.cassandra.Util.concatByteArrays; +import org.apache.cassandra.db.context.CounterContext; import org.apache.cassandra.db.marshal.LongType; import org.apache.cassandra.utils.ByteBufferUtil; - +import org.apache.cassandra.utils.FBUtilities; public class SuperColumnTest { + private static final CounterContext cc = new CounterContext(); + @Test public void testMissingSubcolumn() { SuperColumn sc = new SuperColumn(ByteBufferUtil.bytes("sc1"), LongType.instance); @@ -37,4 +41,69 @@ public class SuperColumnTest assertNotNull(sc.getSubColumn(getBytes(1))); assertNull(sc.getSubColumn(getBytes(2))); } + + @Test + public void testAddColumnIncrementCounter() + { + byte[] context; + + SuperColumn sc = new SuperColumn(ByteBufferUtil.bytes("sc1"), LongType.instance); + + context = concatByteArrays( + FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(1), FBUtilities.toByteArray(7L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(5L), FBUtilities.toByteArray(7L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(9L) + ); + sc.addColumn(new CounterColumn(getBytes(1), ByteBuffer.wrap(cc.total(context)), 3L, context, 0L)); + context = concatByteArrays( + FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(5L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(1L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(4L) + ); + sc.addColumn(new CounterColumn(getBytes(1), ByteBuffer.wrap(cc.total(context)), 10L, context, 0L)); + + context = concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(6L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(7), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + sc.addColumn(new CounterColumn(getBytes(2), ByteBuffer.wrap(cc.total(context)), 9L, context, 0L)); + + assertNotNull(sc.getSubColumn(getBytes(1))); + assertNull(sc.getSubColumn(getBytes(3))); + + // column: 1 + byte[] c1 = concatByteArrays( + FBUtilities.getLocalAddress().getAddress(), FBUtilities.toByteArray(12L), FBUtilities.toByteArray(8L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(9L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(1), FBUtilities.toByteArray(7L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(5L), FBUtilities.toByteArray(7L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(1L) + ); + assert 0 == FBUtilities.compareByteSubArrays( + ((CounterColumn)sc.getSubColumn(getBytes(1))).partitionedCounter(), + 0, + c1, + 0, + c1.length); + + // column: 2 + byte[] c2 = concatByteArrays( + FBUtilities.toByteArray(3), FBUtilities.toByteArray(6L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(7), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(0L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(0L) + ); + assert 0 == FBUtilities.compareByteSubArrays( + ((CounterColumn)sc.getSubColumn(getBytes(2))).partitionedCounter(), + 0, + c2, + 0, + c2.length); + + assertNotNull(sc.getSubColumn(getBytes(1))); + assertNotNull(sc.getSubColumn(getBytes(2))); + assertNull(sc.getSubColumn(getBytes(3))); + } } diff --git a/test/unit/org/apache/cassandra/db/context/CounterContextTest.java b/test/unit/org/apache/cassandra/db/context/CounterContextTest.java new file mode 100644 index 0000000000..82dd3215da --- /dev/null +++ b/test/unit/org/apache/cassandra/db/context/CounterContextTest.java @@ -0,0 +1,536 @@ +/* + * + * 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.db.context; + +import static org.junit.Assert.*; + +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.util.*; + +import org.apache.commons.lang.ArrayUtils; + +import org.junit.Test; + +import org.apache.cassandra.Util; +import org.apache.cassandra.db.context.IContext.ContextRelationship; +import org.apache.cassandra.utils.FBUtilities; + +/** + * Note: these tests assume IPv4 (4 bytes) is used for id. + * if IPv6 (16 bytes) is used, tests will fail (but the code will work). + * however, it might be pragmatic to modify the code to just use + * the IPv4 portion of the IPv6 address-space. + */ +public class CounterContextTest +{ + private static final CounterContext cc = new CounterContext(); + + private static final InetAddress idAddress; + private static final byte[] id; + private static final int idLength; + private static final int clockLength; + private static final int countLength; + + private static final int stepLength; + private static final int defaultEntries; + + static + { + idAddress = FBUtilities.getLocalAddress(); + id = idAddress.getAddress(); + idLength = 4; // size of int + clockLength = 8; // size of long + countLength = 8; // size of long + stepLength = idLength + clockLength + countLength; + + defaultEntries = 10; + } + + @Test + public void testCreate() + { + byte[] context = cc.create(); + assert context.length == 0; + } + + @Test + public void testUpdatePresentReorder() throws UnknownHostException + { + byte[] context; + + context = new byte[stepLength * defaultEntries]; + + for (int i = 0; i < defaultEntries - 1; i++) + { + cc.writeElementAtStepOffset( + context, + i, + FBUtilities.toByteArray(i), + 1L, + 1L); + } + cc.writeElementAtStepOffset( + context, + (defaultEntries - 1), + id, + 2L, + 3L); + + context = cc.update(context, idAddress, 10L); + + assertEquals(context.length, stepLength * defaultEntries); + assertEquals( 3L, FBUtilities.byteArrayToLong(context, idLength)); + assertEquals( 13L, FBUtilities.byteArrayToLong(context, idLength + clockLength)); + for (int i = 1; i < defaultEntries; i++) + { + int offset = i * stepLength; + assertEquals( i-1, FBUtilities.byteArrayToInt(context, offset)); + assertEquals(1L, FBUtilities.byteArrayToLong(context, offset + idLength)); + assertEquals(1L, FBUtilities.byteArrayToLong(context, offset + idLength + clockLength)); + } + } + + @Test + public void testUpdateNotPresent() + { + byte[] context = new byte[stepLength * 2]; + + for (int i = 0; i < 2; i++) + { + cc.writeElementAtStepOffset( + context, + i, + FBUtilities.toByteArray(i), + 1L, + 1L); + } + + context = cc.update(context, idAddress, 328L); + + assert context.length == stepLength * 3; + assert 1L == FBUtilities.byteArrayToLong(context, idLength); + assert 328L == FBUtilities.byteArrayToLong(context, idLength + clockLength); + for (int i = 1; i < 3; i++) + { + int offset = i * stepLength; + assert i-1 == FBUtilities.byteArrayToInt(context, offset); + assert 1L == FBUtilities.byteArrayToLong(context, offset + idLength); + assert 1L == FBUtilities.byteArrayToLong(context, offset + idLength + clockLength); + } + } + + @Test + public void testSwapElement() + { + byte[] context = new byte[stepLength * 3]; + + for (int i = 0; i < 3; i++) + { + cc.writeElementAtStepOffset( + context, + i, + FBUtilities.toByteArray(i), + 1L, + 1L); + } + cc.swapElement(context, 0, 2*stepLength); + + assert 2 == FBUtilities.byteArrayToInt(context, 0); + assert 0 == FBUtilities.byteArrayToInt(context, 2*stepLength); + + cc.swapElement(context, 0, 1*stepLength); + + assert 1 == FBUtilities.byteArrayToInt(context, 0); + assert 2 == FBUtilities.byteArrayToInt(context, 1*stepLength); + } + + @Test + public void testPartitionElements() + { + byte[] context = new byte[stepLength * 10]; + + cc.writeElementAtStepOffset(context, 0, FBUtilities.toByteArray(5), 1L, 1L); + cc.writeElementAtStepOffset(context, 1, FBUtilities.toByteArray(3), 1L, 1L); + cc.writeElementAtStepOffset(context, 2, FBUtilities.toByteArray(6), 1L, 1L); + cc.writeElementAtStepOffset(context, 3, FBUtilities.toByteArray(7), 1L, 1L); + cc.writeElementAtStepOffset(context, 4, FBUtilities.toByteArray(8), 1L, 1L); + cc.writeElementAtStepOffset(context, 5, FBUtilities.toByteArray(9), 1L, 1L); + cc.writeElementAtStepOffset(context, 6, FBUtilities.toByteArray(2), 1L, 1L); + cc.writeElementAtStepOffset(context, 7, FBUtilities.toByteArray(4), 1L, 1L); + cc.writeElementAtStepOffset(context, 8, FBUtilities.toByteArray(1), 1L, 1L); + cc.writeElementAtStepOffset(context, 9, FBUtilities.toByteArray(3), 1L, 1L); + + cc.partitionElements( + context, + 0, // left + 9, // right (inclusive) + 2 // pivot + ); + + assert 5 == FBUtilities.byteArrayToInt(context, 0*stepLength); + assert 3 == FBUtilities.byteArrayToInt(context, 1*stepLength); + assert 3 == FBUtilities.byteArrayToInt(context, 2*stepLength); + assert 2 == FBUtilities.byteArrayToInt(context, 3*stepLength); + assert 4 == FBUtilities.byteArrayToInt(context, 4*stepLength); + assert 1 == FBUtilities.byteArrayToInt(context, 5*stepLength); + assert 6 == FBUtilities.byteArrayToInt(context, 6*stepLength); + assert 8 == FBUtilities.byteArrayToInt(context, 7*stepLength); + assert 9 == FBUtilities.byteArrayToInt(context, 8*stepLength); + assert 7 == FBUtilities.byteArrayToInt(context, 9*stepLength); + } + + @Test + public void testSortElementsById() + { + byte[] context = new byte[stepLength * 10]; + + cc.writeElementAtStepOffset(context, 0, FBUtilities.toByteArray(5), 1L, 1L); + cc.writeElementAtStepOffset(context, 1, FBUtilities.toByteArray(3), 1L, 1L); + cc.writeElementAtStepOffset(context, 2, FBUtilities.toByteArray(6), 1L, 1L); + cc.writeElementAtStepOffset(context, 3, FBUtilities.toByteArray(7), 1L, 1L); + cc.writeElementAtStepOffset(context, 4, FBUtilities.toByteArray(8), 1L, 1L); + cc.writeElementAtStepOffset(context, 5, FBUtilities.toByteArray(9), 1L, 1L); + cc.writeElementAtStepOffset(context, 6, FBUtilities.toByteArray(2), 1L, 1L); + cc.writeElementAtStepOffset(context, 7, FBUtilities.toByteArray(4), 1L, 1L); + cc.writeElementAtStepOffset(context, 8, FBUtilities.toByteArray(1), 1L, 1L); + cc.writeElementAtStepOffset(context, 9, FBUtilities.toByteArray(3), 1L, 1L); + + byte[] sorted = cc.sortElementsById(context); + + assertEquals( 1, FBUtilities.byteArrayToInt(sorted, 0*stepLength)); + assertEquals( 2, FBUtilities.byteArrayToInt(sorted, 1*stepLength)); + assertEquals( 3, FBUtilities.byteArrayToInt(sorted, 2*stepLength)); + assertEquals( 3, FBUtilities.byteArrayToInt(sorted, 3*stepLength)); + assertEquals( 4, FBUtilities.byteArrayToInt(sorted, 4*stepLength)); + assertEquals( 5, FBUtilities.byteArrayToInt(sorted, 5*stepLength)); + assertEquals( 6, FBUtilities.byteArrayToInt(sorted, 6*stepLength)); + assertEquals( 7, FBUtilities.byteArrayToInt(sorted, 7*stepLength)); + assertEquals( 8, FBUtilities.byteArrayToInt(sorted, 8*stepLength)); + assertEquals( 9, FBUtilities.byteArrayToInt(sorted, 9*stepLength)); + } + + @Test + public void testDiff() + { + byte[] left = new byte[3 * stepLength]; + byte[] right; + + // equality: equal nodes, all counts same + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + right = ArrayUtils.clone(left); + + assert ContextRelationship.EQUAL == + cc.diff(left, right); + + // greater than: left has superset of nodes (counts equal) + left = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + cc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(12), 0L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L, 0L); + + assert ContextRelationship.GREATER_THAN == + cc.diff(left, right); + + // less than: left has subset of nodes (counts equal) + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + + right = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L, 0L); + cc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 0L, 0L); + + assert ContextRelationship.LESS_THAN == + cc.diff(left, right); + + // greater than: equal nodes, but left has higher counts + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 3L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L, 0L); + + assert ContextRelationship.GREATER_THAN == + cc.diff(left, right); + + // less than: equal nodes, but right has higher counts + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 3L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 3L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 3L, 0L); + + assert ContextRelationship.LESS_THAN == + cc.diff(left, right); + + // disjoint: right and left have disjoint node sets + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(4), 1L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 1L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(4), 1L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(2), 1L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(12), 1L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + // disjoint: equal nodes, but right and left have higher counts in differing nodes + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 1L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 2L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 1L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + // disjoint: left has more nodes, but lower counts + left = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 2L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 1L, 0L); + cc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(12), 1L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 9L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 5L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + // disjoint: left has less nodes, but higher counts + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 2L, 0L); + + right = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L, 0L); + cc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 1L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + // disjoint: mixed nodes and counts + left = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(9), 2L, 0L); + + right = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L, 0L); + cc.writeElementAtStepOffset(right, 3, FBUtilities.toByteArray(12), 1L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + + left = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(3), 5L, 0L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(6), 2L, 0L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(7), 2L, 0L); + cc.writeElementAtStepOffset(left, 3, FBUtilities.toByteArray(9), 2L, 0L); + + right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 0, FBUtilities.toByteArray(3), 4L, 0L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(6), 3L, 0L); + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(9), 2L, 0L); + + assert ContextRelationship.DISJOINT == + cc.diff(left, right); + } + + @Test + public void testMerge() + { + // note: local counts aggregated; remote counts are reconciled (i.e. take max) + byte[] left = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(1), 1L, 1L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(2), 2L, 2L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(4), 6L, 3L); + cc.writeElementAtStepOffset( + left, + 3, + FBUtilities.getLocalAddress().getAddress(), + 7L, + 3L); + + byte[] right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(5), 5L, 5L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(4), 4L, 4L); + cc.writeElementAtStepOffset( + right, + 0, + FBUtilities.getLocalAddress().getAddress(), + 2L, + 9L); + + byte[] merged = cc.merge(left, right); + + // local node id's counts are aggregated + assertEquals(0, FBUtilities.compareUnsigned( + FBUtilities.getLocalAddress().getAddress(), + merged, + 0, + 0*stepLength, + 4, + 4)); + assertEquals( 9L, FBUtilities.byteArrayToLong(merged, 0*stepLength + idLength)); + assertEquals(12L, FBUtilities.byteArrayToLong(merged, 0*stepLength + idLength + clockLength)); + + // remote node id counts are reconciled (i.e. take max) + assertEquals( 4, FBUtilities.byteArrayToInt(merged, 1*stepLength)); + assertEquals( 6L, FBUtilities.byteArrayToLong(merged, 1*stepLength + idLength)); + assertEquals( 3L, FBUtilities.byteArrayToLong(merged, 1*stepLength + idLength + clockLength)); + + assertEquals( 5, FBUtilities.byteArrayToInt(merged, 2*stepLength)); + assertEquals( 5L, FBUtilities.byteArrayToLong(merged, 2*stepLength + idLength)); + assertEquals( 5L, FBUtilities.byteArrayToLong(merged, 2*stepLength + idLength + clockLength)); + + assertEquals( 2, FBUtilities.byteArrayToInt(merged, 3*stepLength)); + assertEquals( 2L, FBUtilities.byteArrayToLong(merged, 3*stepLength + idLength)); + assertEquals( 2L, FBUtilities.byteArrayToLong(merged, 3*stepLength + idLength + clockLength)); + + assertEquals( 1, FBUtilities.byteArrayToInt(merged, 4*stepLength)); + assertEquals( 1L, FBUtilities.byteArrayToLong(merged, 4*stepLength + idLength)); + assertEquals( 1L, FBUtilities.byteArrayToLong(merged, 4*stepLength + idLength + clockLength)); + } + + @Test + public void testTotal() + { + byte[] left = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(left, 0, FBUtilities.toByteArray(1), 1L, 1L); + cc.writeElementAtStepOffset(left, 1, FBUtilities.toByteArray(2), 2L, 2L); + cc.writeElementAtStepOffset(left, 2, FBUtilities.toByteArray(4), 3L, 3L); + cc.writeElementAtStepOffset( + left, + 3, + FBUtilities.getLocalAddress().getAddress(), + 3L, + 3L); + + byte[] right = new byte[3 * stepLength]; + cc.writeElementAtStepOffset(right, 2, FBUtilities.toByteArray(5), 5L, 5L); + cc.writeElementAtStepOffset(right, 1, FBUtilities.toByteArray(4), 4L, 4L); + cc.writeElementAtStepOffset( + right, + 0, + FBUtilities.getLocalAddress().getAddress(), + 9L, + 9L); + + byte[] merged = cc.merge(left, right); + + // 127.0.0.1: 12 (3+9) + // 0.0.0.1: 1 + // 0.0.0.2: 2 + // 0.0.0.4: 4 + // 0.0.0.5: 5 + + assertEquals(24L, FBUtilities.byteArrayToLong(cc.total(merged))); + } + + @Test + public void testCleanNodeCounts() throws UnknownHostException + { + byte[] bytes = new byte[4 * stepLength]; + cc.writeElementAtStepOffset(bytes, 0, FBUtilities.toByteArray(1), 1L, 1L); + cc.writeElementAtStepOffset(bytes, 1, FBUtilities.toByteArray(2), 2L, 2L); + cc.writeElementAtStepOffset(bytes, 2, FBUtilities.toByteArray(4), 3L, 3L); + cc.writeElementAtStepOffset(bytes, 3, FBUtilities.toByteArray(8), 4L, 4L); + + assertEquals(4, FBUtilities.byteArrayToInt(bytes, 2*stepLength)); + assertEquals(3L, FBUtilities.byteArrayToLong(bytes, 2*stepLength + idLength)); + + bytes = cc.cleanNodeCounts(bytes, InetAddress.getByAddress(FBUtilities.toByteArray(4))); + + // node: 0.0.0.4 should be removed + assertEquals(3 * stepLength, bytes.length); + + // other nodes should be unaffected + assertEquals(1, FBUtilities.byteArrayToInt(bytes, 0*stepLength)); + assertEquals(1L, FBUtilities.byteArrayToLong(bytes, 0*stepLength + idLength)); + + assertEquals(2, FBUtilities.byteArrayToInt(bytes, 1*stepLength)); + assertEquals(2L, FBUtilities.byteArrayToLong(bytes, 1*stepLength + idLength)); + + assertEquals(8, FBUtilities.byteArrayToInt(bytes, 2*stepLength)); + assertEquals(4L, FBUtilities.byteArrayToLong(bytes, 2*stepLength + idLength)); + } +} diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java b/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java index 866dd0d250..518a87f4a5 100644 --- a/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java +++ b/test/unit/org/apache/cassandra/io/sstable/SSTableUtils.java @@ -51,6 +51,11 @@ public class SSTableUtils } public static File tempSSTableFile(String tablename, String cfname) throws IOException + { + return tempSSTableFile(tablename, cfname, 0); + } + + public static File tempSSTableFile(String tablename, String cfname, int generation) throws IOException { File tempdir = File.createTempFile(tablename, cfname); if(!tempdir.delete() || !tempdir.mkdir()) @@ -59,7 +64,7 @@ public class SSTableUtils File tabledir = new File(tempdir, tablename); tabledir.mkdir(); tabledir.deleteOnExit(); - File datafile = new File(new Descriptor(tabledir, tablename, cfname, 0, false).filenameFor("Data.db")); + File datafile = new File(new Descriptor(tabledir, tablename, cfname, generation, false).filenameFor("Data.db")); if (!datafile.createNewFile()) throw new IOException("unable to create file " + datafile); datafile.deleteOnExit(); @@ -92,7 +97,12 @@ public class SSTableUtils public static SSTableReader writeRawSSTable(String tablename, String cfname, Map entries) throws IOException { - File datafile = tempSSTableFile(tablename, cfname); + return writeRawSSTable(tablename, cfname, entries, 0); + } + + public static SSTableReader writeRawSSTable(String tablename, String cfname, Map entries, int generation) throws IOException + { + File datafile = tempSSTableFile(tablename, cfname, generation); SSTableWriter writer = new SSTableWriter(datafile.getAbsolutePath(), entries.size()); SortedMap sortedEntries = new TreeMap(); for (Map.Entry entry : entries.entrySet()) diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableWriterAESCommutativeTest.java b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterAESCommutativeTest.java new file mode 100644 index 0000000000..66083abbb1 --- /dev/null +++ b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterAESCommutativeTest.java @@ -0,0 +1,186 @@ +/* + * + * 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.io.sstable; + +import static org.junit.Assert.*; + +import java.io.IOException; +import java.net.InetAddress; +import java.net.UnknownHostException; +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ExecutionException; + +import org.apache.cassandra.CleanupHelper; +import org.apache.cassandra.Util; +import org.apache.cassandra.db.*; +import org.apache.cassandra.db.context.CounterContext; +import org.apache.cassandra.db.marshal.CounterColumnType; +import org.apache.cassandra.io.util.BufferedRandomAccessFile; +import org.apache.cassandra.io.util.DataOutputBuffer; +import org.apache.cassandra.io.util.FileUtils; +import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.streaming.OperationType; +import org.apache.cassandra.utils.FBUtilities; +import org.junit.Test; +import org.apache.cassandra.utils.ByteBufferUtil; + +public class SSTableWriterAESCommutativeTest extends CleanupHelper +{ + private static final CounterContext cc = new CounterContext(); + private static final CounterColumnType ctype = CounterColumnType.instance; + + @Test + public void testRecoverAndOpenAESCommutative() throws IOException, ExecutionException, InterruptedException, UnknownHostException + { + String keyspace = "Keyspace1"; + String cfname = "Counter1"; + + Map entries = new HashMap(); + Map cleanedEntries = new HashMap(); + + DataOutputBuffer buffer; + + ColumnFamily cf = ColumnFamily.create(keyspace, cfname); + byte[] context; + + // key: k + context = Util.concatByteArrays( + FBUtilities.getLocalAddress().getAddress(), + FBUtilities.toByteArray(9L), + FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(2L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(4L) + ); + cf.addColumn(new CounterColumn( + ByteBufferUtil.bytes("x"), + ByteBuffer.wrap(cc.total(context)), + 0L, + context + )); + context = Util.concatByteArrays( + FBUtilities.toByteArray(1), FBUtilities.toByteArray(7L), FBUtilities.toByteArray(12L), + FBUtilities.getLocalAddress().getAddress(), + FBUtilities.toByteArray(5L), + FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(33L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(24L) + ); + cf.addColumn(new CounterColumn( + ByteBufferUtil.bytes("y"), + ByteBuffer.wrap(cc.total(context)), + 0L, + context + )); + + buffer = new DataOutputBuffer(); + ColumnFamily.serializer().serializeWithIndexes(cf, buffer); + entries.put( + ByteBufferUtil.bytes("k"), + ByteBuffer.wrap(Arrays.copyOf(buffer.getData(), buffer.getLength())) + ); + + ctype.cleanContext(cf, FBUtilities.getLocalAddress()); + buffer = new DataOutputBuffer(); + ColumnFamily.serializer().serializeWithIndexes(cf, buffer); + cleanedEntries.put( + ByteBufferUtil.bytes("k"), + ByteBuffer.wrap(Arrays.copyOf(buffer.getData(), buffer.getLength())) + ); + + cf.clear(); + + // key: l + context = Util.concatByteArrays( + FBUtilities.getLocalAddress().getAddress(), + FBUtilities.toByteArray(9L), + FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(2), FBUtilities.toByteArray(4L), FBUtilities.toByteArray(2L), + FBUtilities.toByteArray(4), FBUtilities.toByteArray(3L), FBUtilities.toByteArray(3L), + FBUtilities.toByteArray(8), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(4L) + ); + cf.addColumn(new CounterColumn( + ByteBufferUtil.bytes("x"), + ByteBuffer.wrap(cc.total(context)), + 0L, + context + )); + context = Util.concatByteArrays( + FBUtilities.toByteArray(1), FBUtilities.toByteArray(7L), FBUtilities.toByteArray(12L), + FBUtilities.toByteArray(3), FBUtilities.toByteArray(2L), FBUtilities.toByteArray(33L), + FBUtilities.toByteArray(9), FBUtilities.toByteArray(1L), FBUtilities.toByteArray(24L) + ); + cf.addColumn(new CounterColumn( + ByteBufferUtil.bytes("y"), + ByteBuffer.wrap(cc.total(context)), + 0L, + context + )); + + buffer = new DataOutputBuffer(); + ColumnFamily.serializer().serializeWithIndexes(cf, buffer); + entries.put( + ByteBufferUtil.bytes("l"), + ByteBuffer.wrap(Arrays.copyOf(buffer.getData(), buffer.getLength())) + ); + + ctype.cleanContext(cf, FBUtilities.getLocalAddress()); + buffer = new DataOutputBuffer(); + ColumnFamily.serializer().serializeWithIndexes(cf, buffer); + cleanedEntries.put( + ByteBufferUtil.bytes("l"), + ByteBuffer.wrap(Arrays.copyOf(buffer.getData(), buffer.getLength())) + ); + + cf.clear(); + + // write out unmodified CF + SSTableReader orig = SSTableUtils.writeRawSSTable(keyspace, cfname, entries, 0); + + // whack the index to trigger the recover + FileUtils.deleteWithConfirm(orig.descriptor.filenameFor(Component.PRIMARY_INDEX)); + FileUtils.deleteWithConfirm(orig.descriptor.filenameFor(Component.FILTER)); + + // re-build inline + SSTableReader rebuilt = CompactionManager.instance.submitSSTableBuild( + orig.descriptor, + OperationType.AES + ).get(); + + // write out cleaned CF + SSTableReader cleaned = SSTableUtils.writeRawSSTable(keyspace, cfname, cleanedEntries, 0); + + // verify + BufferedRandomAccessFile origFile = new BufferedRandomAccessFile(orig.descriptor.filenameFor(SSTable.COMPONENT_DATA), "r", 8 * 1024 * 1024); + BufferedRandomAccessFile cleanedFile = new BufferedRandomAccessFile(cleaned.descriptor.filenameFor(SSTable.COMPONENT_DATA), "r", 8 * 1024 * 1024); + + while(origFile.getFilePointer() < origFile.length() && cleanedFile.getFilePointer() < cleanedFile.length()) + { + assert origFile.readByte() == cleanedFile.readByte(); + } + assert origFile.getFilePointer() == origFile.length(); + assert cleanedFile.getFilePointer() == cleanedFile.length(); + } +} diff --git a/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java index 5878c3629f..3a80804767 100644 --- a/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java +++ b/test/unit/org/apache/cassandra/io/sstable/SSTableWriterTest.java @@ -41,6 +41,7 @@ import org.apache.cassandra.dht.Range; import org.apache.cassandra.io.util.DataOutputBuffer; import org.apache.cassandra.io.util.FileUtils; import org.apache.cassandra.service.StorageService; +import org.apache.cassandra.streaming.OperationType; import org.apache.cassandra.thrift.IndexClause; import org.apache.cassandra.thrift.IndexExpression; import org.apache.cassandra.thrift.IndexOperator; @@ -80,7 +81,7 @@ public class SSTableWriterTest extends CleanupHelper { FileUtils.deleteWithConfirm(orig.descriptor.filenameFor(Component.PRIMARY_INDEX)); FileUtils.deleteWithConfirm(orig.descriptor.filenameFor(Component.FILTER)); - SSTableReader sstr = CompactionManager.instance.submitSSTableBuild(orig.descriptor).get(); + SSTableReader sstr = CompactionManager.instance.submitSSTableBuild(orig.descriptor, OperationType.AES).get(); assert sstr != null; ColumnFamilyStore cfs = Table.open("Keyspace1").getColumnFamilyStore("Indexed1"); cfs.addSSTable(sstr); diff --git a/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java b/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java new file mode 100644 index 0000000000..f7869b0431 --- /dev/null +++ b/test/unit/org/apache/cassandra/service/AntiEntropyServiceCounterTest.java @@ -0,0 +1,10 @@ +package org.apache.cassandra.service; + +public class AntiEntropyServiceCounterTest extends AntiEntropyServiceTestAbstract +{ + public void init() + { + tablename = "Keyspace5"; + cfname = "Counter1"; + } +} diff --git a/test/unit/org/apache/cassandra/service/AntiEntropyServiceStandardTest.java b/test/unit/org/apache/cassandra/service/AntiEntropyServiceStandardTest.java new file mode 100644 index 0000000000..f27c0deef5 --- /dev/null +++ b/test/unit/org/apache/cassandra/service/AntiEntropyServiceStandardTest.java @@ -0,0 +1,10 @@ +package org.apache.cassandra.service; + +public class AntiEntropyServiceStandardTest extends AntiEntropyServiceTestAbstract +{ + public void init() + { + tablename = "Keyspace5"; + cfname = "Standard1"; + } +} diff --git a/test/unit/org/apache/cassandra/service/AntiEntropyServiceTestAbstract.java b/test/unit/org/apache/cassandra/service/AntiEntropyServiceTestAbstract.java new file mode 100644 index 0000000000..b6fba5ac30 --- /dev/null +++ b/test/unit/org/apache/cassandra/service/AntiEntropyServiceTestAbstract.java @@ -0,0 +1,273 @@ +/* +* 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.service; + +import java.net.InetAddress; +import java.util.*; +import java.util.concurrent.Callable; +import java.util.concurrent.TimeUnit; +import java.util.concurrent.ThreadPoolExecutor; + +import org.junit.After; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; + +import org.apache.cassandra.CleanupHelper; +import org.apache.cassandra.Util; +import org.apache.cassandra.concurrent.Stage; +import org.apache.cassandra.concurrent.StageManager; +import org.apache.cassandra.config.DatabaseDescriptor; +import org.apache.cassandra.db.*; +import org.apache.cassandra.db.filter.QueryPath; +import org.apache.cassandra.dht.IPartitioner; +import org.apache.cassandra.dht.Range; +import org.apache.cassandra.dht.Token; +import org.apache.cassandra.io.PrecompactedRow; +import org.apache.cassandra.io.util.DataOutputBuffer; +import org.apache.cassandra.locator.AbstractReplicationStrategy; +import org.apache.cassandra.locator.TokenMetadata; +import org.apache.cassandra.utils.FBUtilities; +import org.apache.cassandra.utils.MerkleTree; + +import static org.apache.cassandra.service.AntiEntropyService.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import org.apache.cassandra.utils.ByteBufferUtil; + +public abstract class AntiEntropyServiceTestAbstract extends CleanupHelper +{ + // table and column family to test against + public AntiEntropyService aes; + + public String tablename; + public String cfname; + public TreeRequest request; + public ColumnFamilyStore store; + public InetAddress LOCAL, REMOTE; + + private boolean initialized; + + public abstract void init(); + + @Before + public void prepare() throws Exception + { + if (!initialized) + { + initialized = true; + + init(); + + LOCAL = FBUtilities.getLocalAddress(); + StorageService.instance.initServer(); + // generate a fake endpoint for which we can spoof receiving/sending trees + REMOTE = InetAddress.getByName("127.0.0.2"); + store = null; + for (ColumnFamilyStore cfs : Table.open(tablename).getColumnFamilyStores()) + { + if (cfs.columnFamily.equals(cfname)) + { + store = cfs; + break; + } + } + assert store != null : "CF not found: " + cfname; + } + + aes = AntiEntropyService.instance; + TokenMetadata tmd = StorageService.instance.getTokenMetadata(); + tmd.clearUnsafe(); + StorageService.instance.setToken(StorageService.getPartitioner().getRandomToken()); + tmd.updateNormalToken(StorageService.getPartitioner().getMinimumToken(), REMOTE); + assert tmd.isMember(REMOTE); + + // random session id for each test + request = new TreeRequest(UUID.randomUUID().toString(), LOCAL, new CFPair(tablename, cfname)); + } + + @After + public void teardown() throws Exception + { + flushAES(); + } + + @Test + public void testValidatorPrepare() throws Throwable + { + Validator validator; + + // write + List rms = new LinkedList(); + RowMutation rm; + rm = new RowMutation(tablename, ByteBufferUtil.bytes("key1")); + rm.add(new QueryPath(cfname, null, ByteBufferUtil.bytes("Column1")), ByteBufferUtil.bytes("asdf"), 0); + rms.add(rm); + Util.writeColumnFamily(rms); + + // sample + validator = new Validator(request); + validator.prepare(store); + + // and confirm that the tree was split + assertTrue(validator.tree.size() > 1); + } + + @Test + public void testValidatorComplete() throws Throwable + { + Validator validator = new Validator(request); + validator.prepare(store); + validator.complete(); + + // confirm that the tree was validated + Token min = validator.tree.partitioner().getMinimumToken(); + assert null != validator.tree.hash(new Range(min, min)); + } + + @Test + public void testValidatorAdd() throws Throwable + { + Validator validator = new Validator(request); + IPartitioner part = validator.tree.partitioner(); + Token min = part.getMinimumToken(); + Token mid = part.midpoint(min, min); + validator.prepare(store); + + // add a row with the minimum token + validator.add(new PrecompactedRow(new DecoratedKey(min, ByteBufferUtil.bytes("nonsense!")), + new DataOutputBuffer())); + + // and a row after it + validator.add(new PrecompactedRow(new DecoratedKey(mid, ByteBufferUtil.bytes("inconceivable!")), + new DataOutputBuffer())); + validator.complete(); + + // confirm that the tree was validated + assert null != validator.tree.hash(new Range(min, min)); + } + + @Test + public void testManualRepair() throws Throwable + { + AntiEntropyService.RepairSession sess = AntiEntropyService.instance.getRepairSession(tablename, cfname); + sess.start(); + sess.blockUntilRunning(); + + // ensure that the session doesn't end without a response from REMOTE + sess.join(100); + assert sess.isAlive(); + + // deliver a fake response from REMOTE + AntiEntropyService.instance.completedRequest(new TreeRequest(sess.getName(), REMOTE, request.cf)); + + // block until the repair has completed + sess.join(); + } + + @Test + public void testGetNeighborsPlusOne() throws Throwable + { + // generate rf+1 nodes, and ensure that all nodes are returned + Set expected = addTokens(1 + Table.open(tablename).getReplicationStrategy().getReplicationFactor()); + expected.remove(FBUtilities.getLocalAddress()); + assertEquals(expected, AntiEntropyService.getNeighbors(tablename)); + } + + @Test + public void testGetNeighborsTimesTwo() throws Throwable + { + TokenMetadata tmd = StorageService.instance.getTokenMetadata(); + + // generate rf*2 nodes, and ensure that only neighbors specified by the ARS are returned + addTokens(2 * Table.open(tablename).getReplicationStrategy().getReplicationFactor()); + AbstractReplicationStrategy ars = Table.open(tablename).getReplicationStrategy(); + Set expected = new HashSet(); + for (Range replicaRange : ars.getAddressRanges().get(FBUtilities.getLocalAddress())) + { + expected.addAll(ars.getRangeAddresses(tmd).get(replicaRange)); + } + expected.remove(FBUtilities.getLocalAddress()); + assertEquals(expected, AntiEntropyService.getNeighbors(tablename)); + } + + @Test + public void testDifferencer() throws Throwable + { + // generate a tree + Validator validator = new Validator(request); + validator.prepare(store); + validator.complete(); + MerkleTree ltree = validator.tree; + + // and a clone + validator = new Validator(request); + validator.prepare(store); + validator.complete(); + MerkleTree rtree = validator.tree; + + // change a range we own in one of the trees + Token ltoken = StorageService.instance.getLocalToken(); + ltree.invalidate(ltoken); + MerkleTree.TreeRange changed = ltree.invalids(StorageService.instance.getLocalPrimaryRange()).next(); + changed.hash("non-empty hash!".getBytes()); + // the changed range has two halves, split on our local token: both will be repaired + // (since this keyspace has RF > N, so every node is responsible for the entire ring) + Set interesting = new HashSet(); + interesting.add(new Range(changed.left, ltoken)); + interesting.add(new Range(ltoken, changed.right)); + + // difference the trees + Differencer diff = new Differencer(request, ltree, rtree); + diff.run(); + + // ensure that the changed range was recorded + assertEquals("Wrong differing ranges", interesting, new HashSet(diff.differences)); + } + + Set addTokens(int max) throws Throwable + { + TokenMetadata tmd = StorageService.instance.getTokenMetadata(); + Set endpoints = new HashSet(); + for (int i = 1; i <= max; i++) + { + InetAddress endpoint = InetAddress.getByName("127.0.0." + i); + tmd.updateNormalToken(StorageService.getPartitioner().getRandomToken(), endpoint); + endpoints.add(endpoint); + } + return endpoints; + } + + void flushAES() throws Exception + { + final ThreadPoolExecutor stage = StageManager.getStage(Stage.ANTI_ENTROPY); + final Callable noop = new Callable() + { + public Boolean call() + { + return true; + } + }; + + // send two tasks through the stage: one to follow existing tasks and a second to follow tasks created by + // those existing tasks: tasks won't recursively create more tasks + stage.submit(noop).get(5000, TimeUnit.MILLISECONDS); + stage.submit(noop).get(5000, TimeUnit.MILLISECONDS); + } +} diff --git a/test/unit/org/apache/cassandra/streaming/BootstrapTest.java b/test/unit/org/apache/cassandra/streaming/BootstrapTest.java index 87d5db6fec..0974a89fda 100644 --- a/test/unit/org/apache/cassandra/streaming/BootstrapTest.java +++ b/test/unit/org/apache/cassandra/streaming/BootstrapTest.java @@ -37,7 +37,7 @@ public class BootstrapTest extends SchemaLoader public void testGetNewNames() throws IOException { Descriptor desc = Descriptor.fromFilename(new File("Keyspace1", "Standard1-500-Data.db").toString()); - PendingFile inContext = new PendingFile(null, desc, "Data.db", Arrays.asList(new Pair(0L, 1L))); + PendingFile inContext = new PendingFile(null, desc, "Data.db", Arrays.asList(new Pair(0L, 1L)), OperationType.BOOTSTRAP); PendingFile outContext = StreamIn.getContextMapping(inContext); // filename and generation are expected to have changed diff --git a/test/unit/org/apache/cassandra/streaming/StreamingTransferTest.java b/test/unit/org/apache/cassandra/streaming/StreamingTransferTest.java index f352c195b6..83b3e32efd 100644 --- a/test/unit/org/apache/cassandra/streaming/StreamingTransferTest.java +++ b/test/unit/org/apache/cassandra/streaming/StreamingTransferTest.java @@ -85,7 +85,7 @@ public class StreamingTransferTest extends CleanupHelper ranges.add(new Range(p.getMinimumToken(), p.getToken(ByteBufferUtil.bytes("key1")))); ranges.add(new Range(p.getToken(ByteBufferUtil.bytes("key2")), p.getMinimumToken())); StreamOutSession session = StreamOutSession.create(table.name, LOCAL, null); - StreamOut.transferSSTables(session, Arrays.asList(sstable), ranges); + StreamOut.transferSSTables(session, Arrays.asList(sstable), ranges, OperationType.BOOTSTRAP); session.await(); // confirm that the SSTable was transferred and registered @@ -135,7 +135,7 @@ public class StreamingTransferTest extends CleanupHelper ranges.add(new Range(p.getMinimumToken(), p.getToken(ByteBufferUtil.bytes("transfer1")))); ranges.add(new Range(p.getToken(ByteBufferUtil.bytes("test2")), p.getMinimumToken())); StreamOutSession session = StreamOutSession.create(tablename, LOCAL, null); - StreamOut.transferSSTables(session, Arrays.asList(sstable, sstable2), ranges); + StreamOut.transferSSTables(session, Arrays.asList(sstable, sstable2), ranges, OperationType.BOOTSTRAP); session.await(); // confirm that the SSTable was transferred and registered diff --git a/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java new file mode 100644 index 0000000000..b5c0206525 --- /dev/null +++ b/test/unit/org/apache/cassandra/thrift/ThriftValidationTest.java @@ -0,0 +1,20 @@ +package org.apache.cassandra.thrift; + +import org.junit.Test; + +import org.apache.cassandra.CleanupHelper; + +public class ThriftValidationTest extends CleanupHelper +{ + @Test(expected=InvalidRequestException.class) + public void testValidateCommutativeWithStandard() throws InvalidRequestException + { + ThriftValidation.validateCommutative("Keyspace1", "Standard1"); + } + + @Test + public void testValidateCommutativeWithCounter() throws InvalidRequestException + { + ThriftValidation.validateCommutative("Keyspace1", "Counter1"); + } +} diff --git a/test/unit/org/apache/cassandra/utils/FBUtilitiesTest.java b/test/unit/org/apache/cassandra/utils/FBUtilitiesTest.java index 2d15fbf4b3..c4c1841f84 100644 --- a/test/unit/org/apache/cassandra/utils/FBUtilitiesTest.java +++ b/test/unit/org/apache/cassandra/utils/FBUtilitiesTest.java @@ -20,6 +20,7 @@ package org.apache.cassandra.utils; import static org.junit.Assert.assertArrayEquals; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.fail; import java.io.IOException; import java.nio.ByteBuffer; @@ -85,6 +86,78 @@ public class FBUtilitiesTest } } + @Test + public void testCopyIntoBytes() + { + int i = 300; + long l = 1000; + byte[] b = new byte[20]; + FBUtilities.copyIntoBytes(b, 0, i); + FBUtilities.copyIntoBytes(b, 4, l); + assertEquals(i, FBUtilities.byteArrayToInt(b, 0)); + assertEquals(l, FBUtilities.byteArrayToLong(b, 4)); + } + + @Test + public void testLongBytesConversions() + { + // positive, negative, 1 and 2 byte cases, including + // a few edges that would foul things up unless you're careful + // about masking away sign extension. + long[] longs = new long[] + { + -20L, -127L, -128L, 0L, 1L, 127L, 128L, 65534L, 65535L, -65534L, -65535L, + 4294967294L, 4294967295L, -4294967294L, -4294967295L + }; + + for (long l : longs) { + byte[] ba = FBUtilities.toByteArray(l); + long actual = FBUtilities.byteArrayToLong(ba); + assertEquals(l, actual); + } + } + + @Test + public void testCompareByteSubArrays() + { + byte[] bytes = new byte[16]; + + // handle null + assert FBUtilities.compareByteSubArrays( + null, 0, null, 0, 0) == 0; + assert FBUtilities.compareByteSubArrays( + null, 0, FBUtilities.toByteArray(524255231), 0, 4) == -1; + assert FBUtilities.compareByteSubArrays( + FBUtilities.toByteArray(524255231), 0, null, 0, 4) == 1; + + // handle comparisons + FBUtilities.copyIntoBytes(bytes, 3, 524255231); + assert FBUtilities.compareByteSubArrays( + bytes, 3, FBUtilities.toByteArray(524255231), 0, 4) == 0; + assert FBUtilities.compareByteSubArrays( + bytes, 3, FBUtilities.toByteArray(524255232), 0, 4) == -1; + assert FBUtilities.compareByteSubArrays( + bytes, 3, FBUtilities.toByteArray(524255230), 0, 4) == 1; + + // check that incorrect length throws exception + try + { + assert FBUtilities.compareByteSubArrays( + bytes, 3, FBUtilities.toByteArray(524255231), 0, 24) == 0; + fail("Should raise an AssertionError."); + } catch (AssertionError ae) + { + } + try + { + assert FBUtilities.compareByteSubArrays( + bytes, 3, FBUtilities.toByteArray(524255231), 0, 12) == 0; + fail("Should raise an AssertionError."); + } catch (AssertionError ae) + { + } + } + @Test(expected=CharacterCodingException.class) public void testDecode() throws IOException {