package ezdb;
import java.nio.ByteBuffer;
import java.util.Map.Entry;
import ezdb.serde.Serde;
public class RawTableRow<H, R, V> implements TableRow<H, R, V> {
private final LazyGetter<H> hashKey;
private final LazyGetter<R> rangeKey;
private final LazyGetter<V> value;
public RawTableRow(final H hashKey, final R rangeKey, final V value) {
this.hashKey = new LazyGetter<H>() {
@Override
protected H internalGet() {
return hashKey;
}
};
this.rangeKey = new LazyGetter<R>() {
@Override
protected R internalGet() {
return rangeKey;
}
};
;
this.value = new LazyGetter<V>() {
@Override
protected V internalGet() {
return value;
}
};
;
}
public RawTableRow(final Entry<byte[], byte[]> rawRow,
final Serde<H> hashKeySerde, final Serde<R> rangeKeySerde,
final Serde<V> valueSerde) {
//extract hashKeyBytes/rangeKeyBytes only if needed
final LazyGetter<Entry<byte[], byte[]>> hashKeyBytes_rangeKeyBytes = new LazyGetter<Entry<byte[], byte[]>>() {
@Override
protected Entry<byte[], byte[]> internalGet() {
final byte[] compoundKeyBytes = rawRow.getKey();
final ByteBuffer keyBuffer = ByteBuffer.wrap(compoundKeyBytes);
final int hashKeyBytesLength = keyBuffer.getInt();
final byte[] hashKeyBytes = new byte[hashKeyBytesLength];
keyBuffer.get(hashKeyBytes);
final int rangeKeyBytesLength = keyBuffer.getInt();
final byte[] rangeKeyBytes;
if (rangeKeyBytesLength > 0) {
rangeKeyBytes = new byte[rangeKeyBytesLength];
keyBuffer.get(rangeKeyBytes);
} else {
rangeKeyBytes = null;
}
return new Entry<byte[], byte[]>() {
@Override
public byte[] setValue(byte[] value) {
throw new UnsupportedOperationException();
}
@Override
public byte[] getValue() {
return rangeKeyBytes;
}
@Override
public byte[] getKey() {
return hashKeyBytes;
}
};
}
};
rangeKey = new LazyGetter<R>() {
@Override
protected R internalGet() {
byte[] rangeKeyBytes = hashKeyBytes_rangeKeyBytes.get()
.getValue();
if (rangeKeyBytes == null) {
return null;
} else {
return rangeKeySerde.fromBytes(rangeKeyBytes);
}
}
};
hashKey = new LazyGetter<H>() {
@Override
protected H internalGet() {
byte[] hashKeyBytes = hashKeyBytes_rangeKeyBytes.get().getKey();
return hashKeySerde.fromBytes(hashKeyBytes);
}
};
value = new LazyGetter<V>() {
@Override
protected V internalGet() {
return valueSerde.fromBytes(rawRow.getValue());
}
};
}
@Override
public H getHashKey() {
return hashKey.get();
}
@Override
public R getRangeKey() {
return rangeKey.get();
}
@Override
public V getValue() {
return value.get();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((getHashKey() == null) ? 0 : getHashKey().hashCode());
result = prime * result
+ ((getRangeKey() == null) ? 0 : getRangeKey().hashCode());
result = prime * result
+ ((getValue() == null) ? 0 : getValue().hashCode());
return result;
}
@SuppressWarnings("rawtypes")
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
RawTableRow other = (RawTableRow) obj;
if (getHashKey() == null) {
if (other.getHashKey() != null)
return false;
} else if (!getHashKey().equals(other.getHashKey()))
return false;
if (getRangeKey() == null) {
if (other.getRangeKey() != null)
return false;
} else if (!getRangeKey().equals(other.getRangeKey()))
return false;
if (getValue() == null) {
if (other.getValue() != null)
return false;
} else if (!getValue().equals(other.getValue()))
return false;
return true;
}
@Override
public String toString() {
return getClass().getSimpleName() + " [hashKey=" + getHashKey()
+ ", rangeKey=" + getRangeKey() + ", value=" + getValue() + "]";
}
}