Merge Mutation and CounterMutation thrift structure

patch by slebresne; reviewed by jbellis for CASSANDRA-2384


git-svn-id: https://svn.apache.org/repos/asf/cassandra/trunk@1089517 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Sylvain Lebresne 2011-04-06 16:19:55 +00:00
parent 9c9e79b357
commit 3bbfb06957
15 changed files with 382 additions and 2253 deletions

View File

@ -321,35 +321,25 @@ struct KeyCount {
2: required i32 count
}
/**
* Note that the timestamp is only optional in case of counter deletion.
*/
struct Deletion {
1: required i64 timestamp,
1: optional i64 timestamp,
2: optional binary super_column,
3: optional SlicePredicate predicate,
}
/**
A Mutation is either an insert, represented by filling column_or_supercolumn, or a deletion, represented by filling the deletion attribute.
A Mutation is either an insert (represented by filling column_or_supercolumn), a deletion (represented by filling the deletion attribute),
a counter addition (represented by filling counter), or a counter deletion (represented by filling counter_deletion).
@param column_or_supercolumn. An insert to a column or supercolumn
@param deletion. A deletion of a column or supercolumn
*/
struct Mutation {
1: optional ColumnOrSuperColumn column_or_supercolumn,
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,
3: optional Counter counter,
}
struct TokenRange {
@ -568,12 +558,6 @@ service Cassandra {
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<binary, map<string, list<CounterMutation>>> 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.

View File

@ -1,443 +0,0 @@
/**
* 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<CounterDeletion, CounterDeletion._Fields>, 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<String, _Fields> byName = new HashMap<String, _Fields>();
static {
for (_Fields field : EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // 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 <i>other</i>.
*/
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
}
}

View File

@ -1,438 +0,0 @@
/**
* 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<CounterMutation, CounterMutation._Fields>, 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<String, _Fields> byName = new HashMap<String, _Fields>();
static {
for (_Fields field : EnumSet.allOf(_Fields.class)) {
byName.put(field.getFieldName(), field);
}
}
/**
* Find the _Fields constant that matches fieldId, or null if its not found.
*/
public static _Fields findByThriftId(int fieldId) {
switch(fieldId) {
case 1: // 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 <i>other</i>.
*/
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
}
}

View File

@ -48,6 +48,9 @@ import org.apache.thrift.meta_data.*;
import org.apache.thrift.transport.*;
import org.apache.thrift.protocol.*;
/**
* Note that the timestamp is only optional in case of counter deletion.
*/
public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Serializable, Cloneable {
private static final TStruct STRUCT_DESC = new TStruct("Deletion");
@ -130,7 +133,7 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
public static final Map<_Fields, FieldMetaData> metaDataMap;
static {
Map<_Fields, FieldMetaData> tmpMap = new EnumMap<_Fields, FieldMetaData>(_Fields.class);
tmpMap.put(_Fields.TIMESTAMP, new FieldMetaData("timestamp", TFieldRequirementType.REQUIRED,
tmpMap.put(_Fields.TIMESTAMP, new FieldMetaData("timestamp", TFieldRequirementType.OPTIONAL,
new FieldValueMetaData(TType.I64)));
tmpMap.put(_Fields.SUPER_COLUMN, new FieldMetaData("super_column", TFieldRequirementType.OPTIONAL,
new FieldValueMetaData(TType.STRING)));
@ -143,14 +146,6 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
public Deletion() {
}
public Deletion(
long timestamp)
{
this();
this.timestamp = timestamp;
setTimestampIsSet(true);
}
/**
* Performs a deep copy on <i>other</i>.
*/
@ -334,8 +329,8 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
if (that == null)
return false;
boolean this_present_timestamp = true;
boolean that_present_timestamp = true;
boolean this_present_timestamp = true && this.isSetTimestamp();
boolean that_present_timestamp = true && that.isSetTimestamp();
if (this_present_timestamp || that_present_timestamp) {
if (!(this_present_timestamp && that_present_timestamp))
return false;
@ -368,7 +363,7 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
public int hashCode() {
HashCodeBuilder builder = new HashCodeBuilder();
boolean present_timestamp = true;
boolean present_timestamp = true && (isSetTimestamp());
builder.append(present_timestamp);
if (present_timestamp)
builder.append(timestamp);
@ -472,9 +467,6 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
iprot.readStructEnd();
// check for required fields of primitive type, which can't be checked in the validate method
if (!isSetTimestamp()) {
throw new TProtocolException("Required field 'timestamp' was not found in serialized data! Struct: " + toString());
}
validate();
}
@ -482,9 +474,11 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
validate();
oprot.writeStructBegin(STRUCT_DESC);
oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
oprot.writeI64(this.timestamp);
oprot.writeFieldEnd();
if (isSetTimestamp()) {
oprot.writeFieldBegin(TIMESTAMP_FIELD_DESC);
oprot.writeI64(this.timestamp);
oprot.writeFieldEnd();
}
if (this.super_column != null) {
if (isSetSuper_column()) {
oprot.writeFieldBegin(SUPER_COLUMN_FIELD_DESC);
@ -508,9 +502,11 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
StringBuilder sb = new StringBuilder("Deletion(");
boolean first = true;
sb.append("timestamp:");
sb.append(this.timestamp);
first = false;
if (isSetTimestamp()) {
sb.append("timestamp:");
sb.append(this.timestamp);
first = false;
}
if (isSetSuper_column()) {
if (!first) sb.append(", ");
sb.append("super_column:");
@ -537,7 +533,6 @@ public class Deletion implements TBase<Deletion, Deletion._Fields>, java.io.Seri
public void validate() throws TException {
// check for required fields
// alas, we cannot check 'timestamp' because it's a primitive and you chose the non-beans generator.
}
}

View File

@ -49,7 +49,8 @@ import org.apache.thrift.transport.*;
import org.apache.thrift.protocol.*;
/**
* A Mutation is either an insert, represented by filling column_or_supercolumn, or a deletion, represented by filling the deletion attribute.
* A Mutation is either an insert (represented by filling column_or_supercolumn), a deletion (represented by filling the deletion attribute),
* a counter addition (represented by filling counter), or a counter deletion (represented by filling counter_deletion).
* @param column_or_supercolumn. An insert to a column or supercolumn
* @param deletion. A deletion of a column or supercolumn
*/
@ -58,14 +59,17 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
private static final TField COLUMN_OR_SUPERCOLUMN_FIELD_DESC = new TField("column_or_supercolumn", TType.STRUCT, (short)1);
private static final TField DELETION_FIELD_DESC = new TField("deletion", TType.STRUCT, (short)2);
private static final TField COUNTER_FIELD_DESC = new TField("counter", TType.STRUCT, (short)3);
public ColumnOrSuperColumn column_or_supercolumn;
public Deletion deletion;
public Counter counter;
/** The set of fields this struct contains, along with convenience methods for finding and manipulating them. */
public enum _Fields implements TFieldIdEnum {
COLUMN_OR_SUPERCOLUMN((short)1, "column_or_supercolumn"),
DELETION((short)2, "deletion");
DELETION((short)2, "deletion"),
COUNTER((short)3, "counter");
private static final Map<String, _Fields> byName = new HashMap<String, _Fields>();
@ -84,6 +88,8 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
return COLUMN_OR_SUPERCOLUMN;
case 2: // DELETION
return DELETION;
case 3: // COUNTER
return COUNTER;
default:
return null;
}
@ -132,6 +138,8 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
new StructMetaData(TType.STRUCT, ColumnOrSuperColumn.class)));
tmpMap.put(_Fields.DELETION, new FieldMetaData("deletion", TFieldRequirementType.OPTIONAL,
new StructMetaData(TType.STRUCT, Deletion.class)));
tmpMap.put(_Fields.COUNTER, new FieldMetaData("counter", TFieldRequirementType.OPTIONAL,
new StructMetaData(TType.STRUCT, Counter.class)));
metaDataMap = Collections.unmodifiableMap(tmpMap);
FieldMetaData.addStructMetaDataMap(Mutation.class, metaDataMap);
}
@ -149,6 +157,9 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
if (other.isSetDeletion()) {
this.deletion = new Deletion(other.deletion);
}
if (other.isSetCounter()) {
this.counter = new Counter(other.counter);
}
}
public Mutation deepCopy() {
@ -159,6 +170,7 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
public void clear() {
this.column_or_supercolumn = null;
this.deletion = null;
this.counter = null;
}
public ColumnOrSuperColumn getColumn_or_supercolumn() {
@ -209,6 +221,30 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
}
}
public Counter getCounter() {
return this.counter;
}
public Mutation 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 void setFieldValue(_Fields field, Object value) {
switch (field) {
case COLUMN_OR_SUPERCOLUMN:
@ -227,6 +263,14 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
}
break;
case COUNTER:
if (value == null) {
unsetCounter();
} else {
setCounter((Counter)value);
}
break;
}
}
@ -238,6 +282,9 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
case DELETION:
return getDeletion();
case COUNTER:
return getCounter();
}
throw new IllegalStateException();
}
@ -253,6 +300,8 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
return isSetColumn_or_supercolumn();
case DELETION:
return isSetDeletion();
case COUNTER:
return isSetCounter();
}
throw new IllegalStateException();
}
@ -288,6 +337,15 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
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;
}
return true;
}
@ -305,6 +363,11 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
if (present_deletion)
builder.append(deletion);
boolean present_counter = true && (isSetCounter());
builder.append(present_counter);
if (present_counter)
builder.append(counter);
return builder.toHashCode();
}
@ -336,6 +399,16 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
return lastComparison;
}
}
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;
}
}
return 0;
}
@ -369,6 +442,14 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
TProtocolUtil.skip(iprot, field.type);
}
break;
case 3: // COUNTER
if (field.type == TType.STRUCT) {
this.counter = new Counter();
this.counter.read(iprot);
} else {
TProtocolUtil.skip(iprot, field.type);
}
break;
default:
TProtocolUtil.skip(iprot, field.type);
}
@ -398,6 +479,13 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
oprot.writeFieldEnd();
}
}
if (this.counter != null) {
if (isSetCounter()) {
oprot.writeFieldBegin(COUNTER_FIELD_DESC);
this.counter.write(oprot);
oprot.writeFieldEnd();
}
}
oprot.writeFieldStop();
oprot.writeStructEnd();
}
@ -426,6 +514,16 @@ public class Mutation implements TBase<Mutation, Mutation._Fields>, java.io.Seri
}
first = false;
}
if (isSetCounter()) {
if (!first) sb.append(", ");
sb.append("counter:");
if (this.counter == null) {
sb.append("null");
} else {
sb.append(this.counter);
}
first = false;
}
sb.append(")");
return sb.toString();
}

View File

@ -158,22 +158,21 @@ public class ColumnFamily implements IColumnContainer, IIterableColumns
public void addColumn(QueryPath path, ByteBuffer value, long timestamp, int timeToLive)
{
assert path.columnName != null : path;
assert !metadata().getDefaultValidator().isCommutative();
Column column;
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);
}
if (timeToLive > 0)
column = new ExpiringColumn(path.columnName, value, timestamp, timeToLive);
else
{
column = ((AbstractCommutativeType)defaultValidator).createColumn(path.columnName, value, timestamp);
}
column = new Column(path.columnName, value, timestamp);
addColumn(path.superColumnName, column);
}
public void addCounter(QueryPath path, long value)
{
assert path.columnName != null : path;
addColumn(path.superColumnName, new CounterUpdateColumn(path.columnName, value, System.currentTimeMillis()));
}
public void addTombstone(QueryPath path, ByteBuffer localDeletionTime, long timestamp)
{
assert path.columnName != null : path;

View File

@ -33,8 +33,9 @@ import org.apache.cassandra.io.ICompactSerializer;
import org.apache.cassandra.net.Message;
import org.apache.cassandra.service.StorageService;
import org.apache.cassandra.thrift.ColumnOrSuperColumn;
import org.apache.cassandra.thrift.Deletion;
import org.apache.cassandra.thrift.Mutation;
import org.apache.cassandra.thrift.Counter;
import org.apache.cassandra.thrift.SlicePredicate;
import org.apache.cassandra.utils.ByteBufferUtil;
import org.apache.cassandra.utils.FBUtilities;
@ -146,6 +147,18 @@ public class RowMutation implements IMutation, MessageProducer
columnFamily.addColumn(path, value, timestamp, timeToLive);
}
public void addCounter(QueryPath path, long value)
{
Integer id = CFMetaData.getId(table_, path.columnFamilyName);
ColumnFamily columnFamily = modifications_.get(id);
if (columnFamily == null)
{
columnFamily = ColumnFamily.create(table_, path.columnFamilyName);
modifications_.put(id, columnFamily);
}
columnFamily.addCounter(path, value);
}
public void add(QueryPath path, ByteBuffer value, long timestamp)
{
add(path, value, timestamp, 0);
@ -223,12 +236,16 @@ public class RowMutation implements IMutation, MessageProducer
{
if (mutation.deletion != null)
{
deleteColumnOrSuperColumnToRowMutation(rm, cfName, mutation.deletion);
deleteColumnOrSuperColumnToRowMutation(rm, cfName, mutation.deletion.predicate, mutation.deletion.super_column, mutation.deletion.timestamp);
}
else
if (mutation.column_or_supercolumn != null)
{
addColumnOrSuperColumnToRowMutation(rm, cfName, mutation.column_or_supercolumn);
}
if (mutation.counter != null)
{
addCounterToRowMutation(rm, cfName, mutation.counter);
}
}
}
return rm;
@ -290,21 +307,33 @@ public class RowMutation implements IMutation, MessageProducer
}
}
private static void deleteColumnOrSuperColumnToRowMutation(RowMutation rm, String cfName, Deletion del)
private static void addCounterToRowMutation(RowMutation rm, String cfName, Counter counter)
{
if (del.predicate != null && del.predicate.column_names != null)
if (counter.column == null)
{
for(ByteBuffer c : del.predicate.column_names)
for (org.apache.cassandra.thrift.CounterColumn column : counter.super_column.columns)
{
if (del.super_column == null && DatabaseDescriptor.getColumnFamilyType(rm.table_, cfName) == ColumnFamilyType.Super)
rm.delete(new QueryPath(cfName, c), del.timestamp);
else
rm.delete(new QueryPath(cfName, del.super_column, c), del.timestamp);
rm.addCounter(new QueryPath(cfName, counter.super_column.name, column.name), column.value);
}
}
else
{
rm.delete(new QueryPath(cfName, del.super_column), del.timestamp);
rm.addCounter(new QueryPath(cfName, null, counter.column.name), counter.column.value);
}
}
private static void deleteColumnOrSuperColumnToRowMutation(RowMutation rm, String cfName, SlicePredicate predicate, ByteBuffer scName, long timestamp)
{
if (predicate != null && predicate.column_names != null)
{
for (ByteBuffer c : predicate.column_names)
{
rm.delete(new QueryPath(cfName, scName, c), timestamp);
}
}
else
{
rm.delete(new QueryPath(cfName, scName), timestamp);
}
}

View File

@ -151,7 +151,7 @@ implements org.apache.hadoop.mapred.RecordWriter<ByteBuffer,List<org.apache.cass
{
// deletion
assert amut.deletion != null;
Deletion deletion = new Deletion(amut.deletion.timestamp);
Deletion deletion = new Deletion().setTimestamp(amut.deletion.timestamp);
mutation.setDeletion(deletion);
org.apache.cassandra.hadoop.avro.SlicePredicate apred = amut.deletion.predicate;

View File

@ -344,15 +344,12 @@ public class CassandraServer implements Cassandra.Iface
return counts;
}
private void internal_insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level, boolean isCommutativeOp)
private void internal_insert(ByteBuffer key, ColumnParent column_parent, Column column, ConsistencyLevel consistency_level)
throws InvalidRequestException, UnavailableException, TimedOutException
{
state().hasColumnFamilyAccess(column_parent.column_family, Permission.WRITE);
CFMetaData metadata = ThriftValidation.validateColumnFamily(state().getKeyspace(), column_parent.column_family, isCommutativeOp);
ThriftValidation.validateKey(metadata, key);
if (isCommutativeOp)
ThriftValidation.validateCommutativeForWrite(metadata, consistency_level);
CFMetaData metadata = ThriftValidation.validateColumnFamily(state().getKeyspace(), column_parent.column_family, false);
ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name));
ThriftValidation.validateColumnData(metadata, column);
@ -373,15 +370,16 @@ public class CassandraServer implements Cassandra.Iface
{
logger.debug("insert");
internal_insert(key, column_parent, column, consistency_level, false);
internal_insert(key, column_parent, column, consistency_level);
}
private void internal_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level, boolean isCommutativeOp)
private void internal_batch_mutate(Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map, ConsistencyLevel consistency_level)
throws InvalidRequestException, UnavailableException, TimedOutException
{
List<String> cfamsSeen = new ArrayList<String>();
List<RowMutation> rowMutations = new ArrayList<RowMutation>();
String keyspace = state().getKeyspace();
for (Map.Entry<ByteBuffer, Map<String, List<Mutation>>> mutationEntry: mutation_map.entrySet())
{
ByteBuffer key = mutationEntry.getKey();
@ -390,8 +388,6 @@ public class CassandraServer implements Cassandra.Iface
for (Map.Entry<String, List<Mutation>> columnFamilyMutations : columnFamilyToMutations.entrySet())
{
String cfName = columnFamilyMutations.getKey();
CFMetaData metadata = ThriftValidation.validateColumnFamily(state().getKeyspace(), cfName, isCommutativeOp);
ThriftValidation.validateKey(metadata, key);
// Avoid unneeded authorizations
if (!(cfamsSeen.contains(cfName)))
@ -400,7 +396,12 @@ public class CassandraServer implements Cassandra.Iface
cfamsSeen.add(cfName);
}
if (isCommutativeOp)
boolean isCommutativeOp = false;
boolean isOnlyDeletion = true;
CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, cfName);
ThriftValidation.validateKey(metadata, key);
if (metadata.getDefaultValidator().isCommutative())
ThriftValidation.validateCommutativeForWrite(metadata, consistency_level);
for (Mutation mutation : columnFamilyMutations.getValue())
@ -408,7 +409,7 @@ public class CassandraServer implements Cassandra.Iface
ThriftValidation.validateMutation(metadata, mutation);
}
}
RowMutation rm = RowMutation.getRowMutationFromMutations(state().getKeyspace(), key, columnFamilyToMutations);
RowMutation rm = RowMutation.getRowMutationFromMutations(keyspace, key, columnFamilyToMutations);
if (!rm.isEmpty())
rowMutations.add(rm);
}
@ -421,7 +422,7 @@ public class CassandraServer implements Cassandra.Iface
{
logger.debug("batch_mutate");
internal_batch_mutate(mutation_map, consistency_level, false);
internal_batch_mutate(mutation_map, consistency_level);
}
private void internal_remove(ByteBuffer key, ColumnPath column_path, long timestamp, ConsistencyLevel consistency_level, boolean isCommutativeOp)
@ -999,86 +1000,30 @@ public class CassandraServer implements Cassandra.Iface
// counter methods
private Column getCounterColumn(CounterColumn column)
{
return new Column(column.name, ByteBufferUtil.bytes(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");
internal_insert(key, column_parent, getCounterColumn(column), consistency_level, true);
}
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, ByteBufferUtil.bytes(counter.column.value), System.currentTimeMillis());
cosc.setColumn(c);
}
if (counter.isSetSuper_column())
{
List<Column> subcolumns = new ArrayList<Column>(counter.super_column.columns.size());
for (CounterColumn subcol : counter.super_column.columns)
{
subcolumns.add(new Column(subcol.name, ByteBufferUtil.bytes(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<ByteBuffer, Map<String, List<CounterMutation>>> updateMap, ConsistencyLevel consistency_level)
throws InvalidRequestException, UnavailableException, TimedOutException, TException
{
logger.debug("batch_add");
state().hasColumnFamilyAccess(column_parent.column_family, Permission.WRITE);
String keyspace = state().getKeyspace();
Map<ByteBuffer,Map<String,List<Mutation>>> mutation_map = new HashMap<ByteBuffer,Map<String,List<Mutation>>>();
for (Entry<ByteBuffer, Map<String, List<CounterMutation>>> entry : updateMap.entrySet())
CFMetaData metadata = ThriftValidation.validateColumnFamily(keyspace, column_parent.column_family, true);
ThriftValidation.validateKey(metadata, key);
ThriftValidation.validateCommutativeForWrite(metadata, consistency_level);
ThriftValidation.validateColumnParent(metadata, column_parent);
ThriftValidation.validateColumnNames(metadata, column_parent, Arrays.asList(column.name));
RowMutation rm = new RowMutation(keyspace, key);
try
{
Map<String, List<Mutation>> valueMap = new HashMap<String, List<Mutation>>(entry.getValue().size());
for (Entry<String, List<CounterMutation>> innerEntry : entry.getValue().entrySet())
{
List<Mutation> mutations = new ArrayList<Mutation>(innerEntry.getValue().size());
for (CounterMutation cm : innerEntry.getValue())
{
mutations.add(getMutation(cm));
}
valueMap.put(innerEntry.getKey(), mutations);
}
mutation_map.put(entry.getKey(), valueMap);
rm.addCounter(new QueryPath(column_parent.column_family, column_parent.super_column, column.name), column.value);
}
internal_batch_mutate(mutation_map, consistency_level, true);
catch (MarshalException e)
{
throw new InvalidRequestException(e.getMessage());
}
doInsert(consistency_level, Arrays.asList(rm));
}
private Counter getCounter(ColumnOrSuperColumn cosc)

View File

@ -81,13 +81,7 @@ public class ThriftValidation
public static CFMetaData validateColumnFamily(String tablename, String cfName, boolean isCommutativeOp) throws InvalidRequestException
{
validateTable(tablename);
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);
CFMetaData metadata = validateColumnFamily(tablename, cfName);
if (isCommutativeOp)
{
@ -102,6 +96,20 @@ public class ThriftValidation
return metadata;
}
// This should only be used when the operation should be authorized whether this is a counter CF or not
public static CFMetaData validateColumnFamily(String tablename, String cfName) throws InvalidRequestException
{
validateTable(tablename);
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;
}
/**
* validates all parts of the path to the column, including the column name
*/
@ -261,6 +269,22 @@ public class ThriftValidation
throw new InvalidRequestException("ColumnOrSuperColumn must have one or both of Column or SuperColumn");
}
public static void validateCounter(CFMetaData metadata, Counter counter)
throws InvalidRequestException
{
if (counter.column != null)
validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column((ByteBuffer)null).setColumn(counter.column.name));
if (counter.super_column != null)
{
for (CounterColumn c : counter.super_column.columns)
validateColumnPath(metadata, new ColumnPath(metadata.cfName).setSuper_column(counter.super_column.name).setColumn(c.name));
}
if (counter.column == null && counter.super_column == null)
throw new InvalidRequestException("Counter must have one or both of column or super_column");
}
private static void validateTtl(Column column) throws InvalidRequestException
{
if (column.isSetTtl() && column.ttl <= 0)
@ -276,22 +300,33 @@ public class ThriftValidation
{
ColumnOrSuperColumn cosc = mut.column_or_supercolumn;
Deletion del = mut.deletion;
Counter counter = mut.counter;
if (cosc != null && del != null)
throw new InvalidRequestException("Mutation may have either a ColumnOrSuperColumn or a Deletion, but not both");
boolean isCommutative = metadata.getDefaultValidator().isCommutative();
if (cosc == null && del == null && counter == null)
{
throw new InvalidRequestException("Mutation must have at least one of column_or_superColumn, deletion, counter or counter_deletion");
}
if (cosc != null)
{
if (isCommutative)
throw new InvalidRequestException("invalid operation for commutative columnfamily " + metadata.cfName);
validateColumnOrSuperColumn(metadata, cosc);
}
else if (del != null)
if (counter != null)
{
if (!isCommutative)
throw new InvalidRequestException("invalid operation for non commutative columnfamily " + metadata.cfName);
validateCounter(metadata, counter);
}
if (del != null)
{
validateDeletion(metadata, del);
}
else
{
throw new InvalidRequestException("Mutation must have one ColumnOrSuperColumn or one Deletion");
}
}
public static void validateDeletion(CFMetaData metadata, Deletion del) throws InvalidRequestException
@ -305,9 +340,19 @@ public class ThriftValidation
if (metadata.cfType == ColumnFamilyType.Standard && del.super_column != null)
{
String msg = String.format("deletion of super_column is not possible on a standard ColumnFamily (KeySpace=%s ColumnFamily=%s Deletion=%s)", metadata.ksName, metadata.cfName, del);
String msg = String.format("Deletion of super columns is not possible on a standard ColumnFamily (KeySpace=%s ColumnFamily=%s Deletion=%s)", metadata.ksName, metadata.cfName, del);
throw new InvalidRequestException(msg);
}
if (metadata.getDefaultValidator().isCommutative())
{
// forcing server timestamp even if a timestamp was set for coherence with other counter operation
del.timestamp = System.currentTimeMillis();
}
else if (!del.isSetTimestamp())
{
throw new InvalidRequestException("Deletion timestamp is not optional for non commutative column family " + metadata.cfName);
}
}
public static void validateSlicePredicate(CFMetaData metadata, ByteBuffer scName, SlicePredicate predicate) throws InvalidRequestException

View File

@ -20,6 +20,12 @@ package org.apache.cassandra.service;
*
*/
import java.util.List;
import java.util.LinkedList;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.filter.QueryPath;
import org.apache.cassandra.utils.ByteBufferUtil;
public class AntiEntropyServiceCounterTest extends AntiEntropyServiceTestAbstract
{
@ -28,4 +34,14 @@ public class AntiEntropyServiceCounterTest extends AntiEntropyServiceTestAbstrac
tablename = "Keyspace5";
cfname = "Counter1";
}
public List<RowMutation> getWriteData()
{
List<RowMutation> rms = new LinkedList<RowMutation>();
RowMutation rm;
rm = new RowMutation(tablename, ByteBufferUtil.bytes("key1"));
rm.addCounter(new QueryPath(cfname, null, ByteBufferUtil.bytes("Column1")), 42);
rms.add(rm);
return rms;
}
}

View File

@ -20,6 +20,12 @@ package org.apache.cassandra.service;
*
*/
import java.util.List;
import java.util.LinkedList;
import org.apache.cassandra.db.*;
import org.apache.cassandra.db.filter.QueryPath;
import org.apache.cassandra.utils.ByteBufferUtil;
public class AntiEntropyServiceStandardTest extends AntiEntropyServiceTestAbstract
{
@ -28,4 +34,14 @@ public class AntiEntropyServiceStandardTest extends AntiEntropyServiceTestAbstra
tablename = "Keyspace5";
cfname = "Standard1";
}
public List<RowMutation> getWriteData()
{
List<RowMutation> rms = new LinkedList<RowMutation>();
RowMutation rm;
rm = new RowMutation(tablename, ByteBufferUtil.bytes("key1"));
rm.add(new QueryPath(cfname, null, ByteBufferUtil.bytes("Column1")), ByteBufferUtil.bytes("asdfasdf"), 0);
rms.add(rm);
return rms;
}
}

View File

@ -68,8 +68,8 @@ public class AntiEntropyServiceTest extends CleanupHelper
StorageService.instance.initServer();
// generate a fake endpoint for which we can spoof receiving/sending trees
REMOTE = InetAddress.getByName("127.0.0.2");
store = Table.open(tablename).getColumnFamilyStores().iterator().next();
cfname = store.columnFamily;
cfname = "Standard1";
store = Table.open(tablename).getColumnFamilyStore(cfname);
}
@Before

View File

@ -66,6 +66,8 @@ public abstract class AntiEntropyServiceTestAbstract extends CleanupHelper
public abstract void init();
public abstract List<RowMutation> getWriteData();
@Before
public void prepare() throws Exception
{
@ -114,12 +116,7 @@ public abstract class AntiEntropyServiceTestAbstract extends CleanupHelper
Validator validator;
// write
List<RowMutation> rms = new LinkedList<RowMutation>();
RowMutation rm;
rm = new RowMutation(tablename, ByteBufferUtil.bytes("key1"));
rm.add(new QueryPath(cfname, null, ByteBufferUtil.bytes("Column1")), ByteBufferUtil.bytes("asdfasdf"), 0);
rms.add(rm);
Util.writeColumnFamily(rms);
Util.writeColumnFamily(getWriteData());
// sample
validator = new Validator(request);