package me.prettyprint.cassandra.model; import static me.prettyprint.cassandra.utils.Assert.notNull; import java.nio.ByteBuffer; import me.prettyprint.cassandra.serializers.SerializerTypeInferer; import me.prettyprint.hector.api.Serializer; import me.prettyprint.hector.api.beans.HColumn; import org.apache.cassandra.thrift.Column; import org.apache.commons.lang.builder.EqualsBuilder; import org.apache.commons.lang.builder.HashCodeBuilder; /** * Hector Column definition. * * @param <N> The type of the column name * @param <V> The type of the column value * * @author Ran Tavory (rantav@gmail.com) * @author zznate */ public final class HColumnImpl<N,V> implements HColumn<N, V> { private Column column; private Serializer<N> nameSerializer; private Serializer<V> valueSerializer; private N cachedName; private V cachedValue; public HColumnImpl(N name, V value, long clock, Serializer<N> nameSerializer, Serializer<V> valueSerializer) { this(nameSerializer, valueSerializer); notNull(name, "name is null"); notNull(value, "value is null"); this.column = new Column(nameSerializer.toByteBuffer(name)); this.column.setValue(valueSerializer.toByteBuffer(value)); this.column.setTimestamp(clock); } public HColumnImpl(N name, V value, long clock, int ttl, Serializer<N> nameSerializer, Serializer<V> valueSerializer) { this(name, value, clock, nameSerializer, valueSerializer); setTtl(ttl); } public HColumnImpl(Column thriftColumn, Serializer<N> nameSerializer, Serializer<V> valueSerializer) { this(nameSerializer, valueSerializer); notNull(thriftColumn, "thriftColumn is null"); this.column = thriftColumn; } public HColumnImpl(Serializer<N> nameSerializer, Serializer<V> valueSerializer) { notNull(nameSerializer, "nameSerializer is null"); notNull(valueSerializer, "valueSerializer is null"); this.nameSerializer = nameSerializer; this.valueSerializer = valueSerializer; this.column = new Column(); } public HColumnImpl(N name, V value, long clock) { this(name, value, clock, SerializerTypeInferer.<N>getSerializer(name), SerializerTypeInferer.<V>getSerializer(value)); } @Override public HColumn<N,V> setName(N name) { notNull(name, "name is null"); this.column.setName(nameSerializer.toByteBuffer(name)); this.cachedName = null; return this; } @Override public HColumn<N, V> setValue(V value) { notNull(value, "value is null"); this.column.setValue(valueSerializer.toByteBuffer(value)); this.cachedValue = null; return this; } @Override public HColumn<N,V> setClock(long clock) { this.column.setTimestamp(clock); return this; } /** * Set the time-to-live value for this column in seconds. * The server will mark this column as deleted once the number of seconds has elapsed. */ @Override public HColumn<N,V> setTtl(int ttl) { this.column.setTtl(ttl); return this; } @Override public int getTtl() { return this.column.ttl; } @Override public N getName() { if ( column.isSetName() ) { if ( null == cachedName) { cachedName = nameSerializer.fromByteBuffer(column.name.duplicate()); } return cachedName; } else { return null; } } @Override public V getValue() { if ( column.isSetValue() ) { if ( null == cachedValue) { cachedValue = valueSerializer.fromByteBuffer(column.value.duplicate()); } return cachedValue; } else { return null; } } @Override public long getClock() { return column.timestamp; } public Column toThrift() { return column; } public HColumn<N, V> fromThrift(Column c) { notNull(c, "column is null"); this.column = c; return this; } @Override public Serializer<N> getNameSerializer() { return nameSerializer; } @Override public Serializer<V> getValueSerializer() { return valueSerializer; } @Override public ByteBuffer getNameBytes() { return column.isSetName() ? column.name.duplicate() : null; } @Override public ByteBuffer getValueBytes() { return column.isSetValue() ? column.value.duplicate() : null; } /** * Clear value, timestamp and ttl (the latter two set to '0') leaving only the column name */ @Override public HColumn<N,V> clear() { column.value = null; column.timestamp = 0; column.ttl = 0; column.setTimestampIsSet(false); column.setTtlIsSet(false); column.setValueIsSet(false); return this; } @Override public HColumn<N, V> apply(V value, long clock, int ttl) { setValue(value); column.setTimestamp(clock); column.setTtl(ttl); return this; } public HColumn<N, V> apply(Column c) { this.column = c; cachedName = null; cachedValue = null; return this; } @Override public String toString() { return String.format("HColumn(%s=%s)",getName(), getValue()); } @Override public int hashCode() { return new HashCodeBuilder().append(getName()).append(getValue()).append(getClock()).toHashCode(); } @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (obj == this) { return true; } if (obj.getClass() != getClass()) { return false; } @SuppressWarnings("unchecked") HColumnImpl<N,V> other = (HColumnImpl<N,V>) obj; return new EqualsBuilder().appendSuper(super.equals(obj)).append(getName(), other.getName()). append(getValue(), other.getValue()).append(getClock(), other.getClock()).isEquals(); } }