com.aerospike.client.Value Maven / Gradle / Ivy
Show all versions of aerospike-client-bc-jdk21 Show documentation
/*
* Copyright 2012-2024 Aerospike, Inc.
*
* Portions may be licensed to Aerospike, Inc. under one or more contributor
* license agreements WHICH ARE COMPATIBLE WITH THE APACHE LICENSE, VERSION 2.0.
*
* Licensed 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 com.aerospike.client;
import java.nio.ByteBuffer;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.SortedMap;
import java.util.UUID;
import org.luaj.vm2.LuaBoolean;
import org.luaj.vm2.LuaDouble;
import org.luaj.vm2.LuaInteger;
import org.luaj.vm2.LuaNil;
import org.luaj.vm2.LuaString;
import org.luaj.vm2.LuaValue;
import com.aerospike.client.cdt.MapOrder;
import com.aerospike.client.command.Buffer;
import com.aerospike.client.command.ParticleType;
import com.aerospike.client.lua.LuaBytes;
import com.aerospike.client.lua.LuaInstance;
import com.aerospike.client.util.Packer;
/**
* Polymorphic value classes used to efficiently serialize objects into the wire protocol.
*/
public abstract class Value {
/**
* Should client send boolean particle type for a boolean bin. If false,
* an integer particle type (1 or 0) is sent instead. Must be false for server
* versions less than 5.6 which do not support boolean bins. Can set to true for
* server 5.6+.
*/
public static boolean UseBoolBin = true;
/**
* Should the client return a map when {@link com.aerospike.client.cdt.MapReturnType#KEY_VALUE}
* is specified in a map read operation and the server returns a list of key/value pairs.
*/
public static boolean ReturnMapForKeyValue = false;
/**
* Null value.
*/
public static final Value NULL = NullValue.INSTANCE;
/**
* Infinity value to be used in CDT range comparisons only.
*/
public static final Value INFINITY = new InfinityValue();
/**
* Wildcard value to be used in CDT range comparisons only.
*/
public static final Value WILDCARD = new WildcardValue();
/**
* Get string or null value instance.
*/
public static Value get(String value) {
return (value == null)? NullValue.INSTANCE : new StringValue(value);
}
/**
* Get byte array or null value instance.
*/
public static Value get(byte[] value) {
return (value == null)? NullValue.INSTANCE : new BytesValue(value);
}
/**
* Get byte array with type or null value instance.
*/
public static Value get(byte[] value, int type) {
return (value == null)? NullValue.INSTANCE : new BytesValue(value, type);
}
/**
* Get byte segment or null value instance.
*/
public static Value get(byte[] value, int offset, int length) {
return (value == null)? NullValue.INSTANCE : new ByteSegmentValue(value, offset, length);
}
/**
* Get byte segment or null value instance.
*/
public static Value get(ByteBuffer bb) {
return (bb == null)? NullValue.INSTANCE : new BytesValue(bb.array());
}
/**
* Get byte value instance.
*/
public static Value get(byte value) {
return new ByteValue(value);
}
/**
* Get short value instance.
*/
public static Value get(short value) {
return new ShortValue(value);
}
/**
* Get integer value instance.
*/
public static Value get(int value) {
return new IntegerValue(value);
}
/**
* Get long value instance.
*/
public static Value get(long value) {
return new LongValue(value);
}
/**
* Get double value instance.
*/
public static Value get(double value) {
return new DoubleValue(value);
}
/**
* Get float value instance.
*/
public static Value get(float value) {
return new FloatValue(value);
}
/**
* Get boolean value instance.
*/
public static Value get(boolean value) {
if (UseBoolBin) {
return new BooleanValue(value);
}
else {
return new BoolIntValue(value);
}
}
/**
* Get enum value string instance.
*/
public static Value get(Enum> value) {
return (value == null)? NullValue.INSTANCE : new StringValue(value.toString());
}
/**
* Get UUID value string instance.
*/
public static Value get(UUID value) {
return (value == null)? NullValue.INSTANCE : new StringValue(value.toString());
}
/**
* Get list or null value instance.
*/
public static Value get(List> value) {
return (value == null)? NullValue.INSTANCE : new ListValue(value);
}
/**
* Get map or null value instance.
*/
public static Value get(Map,?> value) {
return (value == null)? NullValue.INSTANCE : new MapValue(value);
}
/**
* Get sorted map or null value instance.
*/
public static Value get(SortedMap,?> value) {
return (value == null)? NullValue.INSTANCE : new MapValue(value, MapOrder.KEY_ORDERED);
}
/**
* This method is deprecated.
* Use {@link #get(Map)} if the map is unsorted (like HashMap).
* Use {@link #get(SortedMap)} if the map is sorted (like TreeMap).
*
* Get map or null value instance.
*/
@Deprecated
public static Value get(Map,?> value, MapOrder order) {
return (value == null)? NullValue.INSTANCE : new MapValue(value, order);
}
/**
* Get sorted map or null value instance.
*/
public static Value get(List extends Entry,?>> value, MapOrder mapOrder) {
return (value == null)? NullValue.INSTANCE : new SortedMapValue(value, mapOrder);
}
/**
* Get value array instance.
*/
public static Value get(Value[] value) {
return (value == null)? NullValue.INSTANCE : new ValueArray(value);
}
/**
* Get GeoJSON or null value instance.
*/
public static Value getAsGeoJSON(String value) {
return (value == null)? NullValue.INSTANCE : new GeoJSONValue(value);
}
/**
* Get HyperLogLog or null value instance.
*/
public static Value getAsHLL(byte[] value) {
return (value == null)? NullValue.INSTANCE : new HLLValue(value);
}
/**
* Get null value instance.
*/
public static Value getAsNull() {
return NullValue.INSTANCE;
}
/**
* Determine value given generic object.
* This is the slowest of the Value get() methods.
* Useful when copying records from one cluster to another.
*/
public static Value get(Object value) {
if (value == null) {
return NullValue.INSTANCE;
}
if (value instanceof Value) {
return (Value)value;
}
if (value instanceof byte[]) {
return new BytesValue((byte[])value);
}
if (value instanceof String) {
return new StringValue((String)value);
}
if (value instanceof Integer) {
return new IntegerValue((Integer)value);
}
if (value instanceof Long) {
return new LongValue((Long)value);
}
if (value instanceof List>) {
return new ListValue((List>)value);
}
if (value instanceof Map,?>) {
return new MapValue((Map,?>)value);
}
if (value instanceof Double) {
return new DoubleValue((Double)value);
}
if (value instanceof Float) {
return new FloatValue((Float)value);
}
if (value instanceof Short) {
return new ShortValue((Short)value);
}
if (value instanceof Boolean) {
if (UseBoolBin) {
return new BooleanValue((Boolean)value);
}
else {
return new BoolIntValue((Boolean)value);
}
}
if (value instanceof Byte) {
return new ByteValue((byte)value);
}
if (value instanceof Character) {
return Value.get(((Character)value).charValue());
}
if (value instanceof Enum) {
return new StringValue(value.toString());
}
if (value instanceof UUID) {
return new StringValue(value.toString());
}
if (value instanceof ByteBuffer) {
ByteBuffer bb = (ByteBuffer)value;
return new BytesValue(bb.array());
}
throw new AerospikeException("Unsupported type: " + value.getClass().getName());
}
/**
* Get value from Record object. Useful when copying records from one cluster to another.
* @deprecated
*
Use {@link Value#get(Object)} instead.
*/
@Deprecated
public static Value getFromRecordObject(Object value) {
return Value.get(value);
}
/**
* Calculate the approximate number of bytes necessary to serialize a key in the wire protocol.
* Size is not exact and may be greater than the actual bytes needed. Size must not be underestimated.
*/
public int estimateKeySize() {
// Return zero for invalid key types.
return 0;
}
/**
* Calculate number of bytes necessary to serialize the value in the wire protocol.
*/
public abstract int estimateSize() throws AerospikeException;
/**
* Serialize the value in the wire protocol.
*/
public abstract int write(byte[] buffer, int offset) throws AerospikeException;
/**
* Serialize the value using MessagePack.
*/
public abstract void pack(Packer packer);
/**
* Validate if value type can be used as a key.
* @throws AerospikeException if type can't be used as a key.
*/
public void validateKeyType() throws AerospikeException {
}
/**
* Get wire protocol value type.
*/
public abstract int getType();
/**
* Return original value as an Object.
*/
public abstract Object getObject();
/**
* Return value as an Object.
*/
public abstract LuaValue getLuaValue(LuaInstance instance);
/**
* Return value as an integer.
*/
public int toInteger() {
return 0;
}
/**
* Return value as a long.
*/
public long toLong() {
return 0;
}
/**
* Empty value.
*/
public static final class NullValue extends Value {
public static final NullValue INSTANCE = new NullValue();
@Override
public int estimateSize() {
return 0;
}
@Override
public int write(byte[] buffer, int offset) {
return 0;
}
@Override
public void pack(Packer packer) {
packer.packNil();
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: null");
}
@Override
public int getType() {
return ParticleType.NULL;
}
@Override
public Object getObject() {
return null;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaNil.NIL;
}
@Override
public String toString() {
return null;
}
@Override
public boolean equals(Object other) {
if (other == null) {
return true;
}
return this.getClass().equals(other.getClass());
}
@Override
public final int hashCode() {
return 0;
}
}
/**
* Byte array value.
*/
public static final class BytesValue extends Value {
private final byte[] bytes;
private final int type;
public BytesValue(byte[] bytes) {
this.bytes = bytes;
this.type = ParticleType.BLOB;
}
public BytesValue(byte[] bytes, int type) {
this.bytes = bytes;
this.type = type;
}
@Override
public int estimateKeySize() {
return bytes.length;
}
@Override
public int estimateSize() {
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packParticleBytes(bytes, type);
}
@Override
public int getType() {
return type;
}
@Override
public Object getObject() {
return bytes;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return new LuaBytes(instance, bytes, type);
}
@Override
public String toString() {
return Buffer.bytesToHexString(bytes);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
Arrays.equals(this.bytes, ((BytesValue)other).bytes));
}
@Override
public int hashCode() {
return Arrays.hashCode(bytes);
}
}
/**
* Byte segment value.
*/
public static final class ByteSegmentValue extends Value {
private final byte[] bytes;
private final int offset;
private final int length;
public ByteSegmentValue(byte[] bytes, int offset, int length) {
this.bytes = bytes;
this.offset = offset;
this.length = length;
}
@Override
public int estimateKeySize() {
return length;
}
@Override
public int estimateSize() {
return length;
}
@Override
public int write(byte[] buffer, int targetOffset) {
System.arraycopy(bytes, offset, buffer, targetOffset, length);
return length;
}
@Override
public void pack(Packer packer) {
packer.packParticleBytes(bytes, offset, length);
}
@Override
public int getType() {
return ParticleType.BLOB;
}
@Override
public Object getObject() {
return this;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaString.valueOf(bytes, offset, length);
}
@Override
public String toString() {
return Buffer.bytesToHexString(bytes, offset, length);
}
@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (! this.getClass().equals(obj.getClass())) {
return false;
}
ByteSegmentValue other = (ByteSegmentValue)obj;
if (this.length != other.length) {
return false;
}
for (int i = 0; i < length; i++) {
if (this.bytes[this.offset + i] != other.bytes[other.offset + i]) {
return false;
}
}
return true;
}
@Override
public int hashCode() {
int result = 1;
for (int i = 0; i < length; i++) {
result = 31 * result + bytes[offset+i];
}
return result;
}
public byte[] getBytes() {
return bytes;
}
public int getOffset() {
return offset;
}
public int getLength() {
return length;
}
}
/**
* Byte value.
*/
public static final class ByteValue extends Value {
private final byte value;
public ByteValue(byte value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.longToBytes(value & 0xff, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packInt(value & 0xff);
}
@Override
public int getType() {
// The server does not natively handle one byte, so store as long (8 byte integer).
return ParticleType.INTEGER;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaInteger.valueOf(value & 0xff);
}
@Override
public String toString() {
return Integer.toString(value & 0xff);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((ByteValue)other).value);
}
@Override
public int hashCode() {
return value & 0xff;
}
@Override
public int toInteger() {
return value & 0xff;
}
@Override
public long toLong() {
return value & 0xff;
}
}
/**
* String value.
*/
public static final class StringValue extends Value {
private final String value;
public StringValue(String value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return value.length() * 3;
}
@Override
public int estimateSize() {
return Buffer.estimateSizeUtf8(value);
}
@Override
public int write(byte[] buffer, int offset) {
return Buffer.stringToUtf8(value, buffer, offset);
}
@Override
public void pack(Packer packer) {
packer.packParticleString(value);
}
@Override
public int getType() {
return ParticleType.STRING;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaString.valueOf(value);
}
@Override
public String toString() {
return value;
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value.equals(((StringValue)other).value));
}
@Override
public int hashCode() {
return value.hashCode();
}
}
/**
* Short value.
*/
public static final class ShortValue extends Value {
private final short value;
public ShortValue(short value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.longToBytes(value, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packInt(value);
}
@Override
public int getType() {
return ParticleType.INTEGER;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaInteger.valueOf(value);
}
@Override
public String toString() {
return Short.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((ShortValue)other).value);
}
@Override
public int hashCode() {
return value;
}
@Override
public int toInteger() {
return value;
}
@Override
public long toLong() {
return value;
}
}
/**
* Integer value.
*/
public static final class IntegerValue extends Value {
private final int value;
public IntegerValue(int value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.longToBytes(value, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packInt(value);
}
@Override
public int getType() {
return ParticleType.INTEGER;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaInteger.valueOf(value);
}
@Override
public String toString() {
return Integer.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((IntegerValue)other).value);
}
@Override
public int hashCode() {
return value;
}
@Override
public int toInteger() {
return value;
}
@Override
public long toLong() {
return value;
}
}
/**
* Long value.
*/
public static final class LongValue extends Value {
private final long value;
public LongValue(long value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.longToBytes(value, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packLong(value);
}
@Override
public int getType() {
return ParticleType.INTEGER;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaInteger.valueOf(value);
}
@Override
public String toString() {
return Long.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((LongValue)other).value);
}
@Override
public int hashCode() {
return (int)(value ^ (value >>> 32));
}
@Override
public int toInteger() {
return (int)value;
}
@Override
public long toLong() {
return value;
}
}
/**
* Double value.
*/
public static final class DoubleValue extends Value {
private final double value;
public DoubleValue(double value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.doubleToBytes(value, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packDouble(value);
}
@Override
public int getType() {
return ParticleType.DOUBLE;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaDouble.valueOf(value);
}
@Override
public String toString() {
return Double.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((DoubleValue)other).value);
}
@Override
public int hashCode() {
long bits = Double.doubleToLongBits(value);
return (int)(bits ^ (bits >>> 32));
}
@Override
public int toInteger() {
return (int)value;
}
@Override
public long toLong() {
return (long)value;
}
}
/**
* Float value.
*/
public static final class FloatValue extends Value {
private final float value;
public FloatValue(float value) {
this.value = value;
}
@Override
public int estimateKeySize() {
return 8;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.doubleToBytes(value, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packFloat(value);
}
@Override
public int getType() {
return ParticleType.DOUBLE;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaDouble.valueOf(value);
}
@Override
public String toString() {
return Float.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((FloatValue)other).value);
}
@Override
public int hashCode() {
return Float.floatToIntBits(value);
}
@Override
public int toInteger() {
return (int)value;
}
@Override
public long toLong() {
return (long)value;
}
}
/**
* Boolean value.
*/
public static final class BooleanValue extends Value {
private final boolean value;
public BooleanValue(boolean value) {
this.value = value;
}
@Override
public int estimateSize() {
return 1;
}
@Override
public int write(byte[] buffer, int offset) {
buffer[offset] = value? (byte)1 : (byte)0;
return 1;
}
@Override
public void pack(Packer packer) {
packer.packBoolean(value);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: boolean");
}
@Override
public int getType() {
return ParticleType.BOOL;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaBoolean.valueOf(value);
}
@Override
public String toString() {
return Boolean.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((BooleanValue)other).value);
}
@Override
public int hashCode() {
return value ? 1231 : 1237;
}
@Override
public int toInteger() {
return value? 1 : 0;
}
@Override
public long toLong() {
return value? 1L : 0L;
}
}
/**
* Boolean value that converts to integer when sending a bin to the server.
* This class will be deleted once full conversion to boolean particle type
* is complete.
*/
public static final class BoolIntValue extends Value {
private final boolean value;
public BoolIntValue(boolean value) {
this.value = value;
}
@Override
public int estimateSize() {
return 8;
}
@Override
public int write(byte[] buffer, int offset) {
Buffer.longToBytes(value? 1L : 0L, buffer, offset);
return 8;
}
@Override
public void pack(Packer packer) {
packer.packBoolean(value);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: BoolIntValue");
}
@Override
public int getType() {
// The server does not natively handle boolean, so store as long (8 byte integer).
return ParticleType.INTEGER;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaBoolean.valueOf(value);
}
@Override
public String toString() {
return Boolean.toString(value);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value == ((BoolIntValue)other).value);
}
@Override
public int hashCode() {
return value ? 1231 : 1237;
}
@Override
public int toInteger() {
return value? 1 : 0;
}
@Override
public long toLong() {
return value? 1L : 0L;
}
}
/**
* GeoJSON value.
*/
public static final class GeoJSONValue extends Value {
private final String value;
public GeoJSONValue(String value) {
this.value = value;
}
@Override
public int estimateSize() {
// flags + ncells + jsonstr
return 1 + 2 + Buffer.estimateSizeUtf8(value);
}
@Override
public int write(byte[] buffer, int offset) {
buffer[offset] = 0; // flags
Buffer.shortToBytes(0, buffer, offset + 1); // ncells
return 1 + 2 + Buffer.stringToUtf8(value, buffer, offset + 3); // jsonstr
}
@Override
public void pack(Packer packer) {
packer.packGeoJSON(value);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: GeoJson");
}
@Override
public int getType() {
return ParticleType.GEOJSON;
}
@Override
public Object getObject() {
return value;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return LuaString.valueOf(value);
}
@Override
public String toString() {
return value;
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.value.equals(((GeoJSONValue)other).value));
}
@Override
public int hashCode() {
return value.hashCode();
}
}
/**
* HyperLogLog value.
*/
public static final class HLLValue extends Value {
private final byte[] bytes;
public HLLValue(byte[] bytes) {
this.bytes = bytes;
}
@Override
public int estimateSize() {
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packParticleBytes(bytes);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: HLL");
}
@Override
public int getType() {
return ParticleType.HLL;
}
@Override
public Object getObject() {
return bytes;
}
public byte[] getBytes() {
return bytes;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return new LuaBytes(instance, bytes);
}
@Override
public String toString() {
return Buffer.bytesToHexString(bytes);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
Arrays.equals(this.bytes, ((HLLValue)other).bytes));
}
@Override
public int hashCode() {
return Arrays.hashCode(bytes);
}
}
/**
* Value array.
*/
public static final class ValueArray extends Value {
private final Value[] array;
private byte[] bytes;
public ValueArray(Value[] array) {
this.array = array;
}
@Override
public int estimateSize() throws AerospikeException {
bytes = Packer.pack(array);
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packValueArray(array);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: value[]");
}
@Override
public int getType() {
return ParticleType.LIST;
}
@Override
public Object getObject() {
return array;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return instance.getLuaList(array);
}
@Override
public String toString() {
return Arrays.toString(array);
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
Arrays.equals(this.array, ((ValueArray)other).array));
}
@Override
public int hashCode() {
return Arrays.hashCode(array);
}
}
/**
* List value.
*/
public static final class ListValue extends Value {
private final List> list;
private byte[] bytes;
public ListValue(List> list) {
this.list = list;
}
@Override
public int estimateSize() throws AerospikeException {
bytes = Packer.pack(list);
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packList(list);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: list");
}
@Override
public int getType() {
return ParticleType.LIST;
}
@Override
public Object getObject() {
return list;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return instance.getLuaList(list);
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.list.equals(((ListValue)other).list));
}
@Override
public int hashCode() {
return list.hashCode();
}
}
/**
* Map value.
*/
public static final class MapValue extends Value {
private final Map,?> map;
private final MapOrder order;
private byte[] bytes;
public MapValue(Map,?> map) {
this.map = map;
this.order = getMapOrder(map);
}
public MapValue(Map,?> map, MapOrder order) {
this.map = map;
this.order = order;
}
public MapOrder getOrder() {
return order;
}
@Override
public int estimateSize() throws AerospikeException {
bytes = Packer.pack(map, order);
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packMap(map, order);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: map");
}
@Override
public int getType() {
return ParticleType.MAP;
}
@Override
public Object getObject() {
return map;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return instance.getLuaMap(map);
}
@Override
public String toString() {
return map.toString();
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()) &&
this.map.equals(((MapValue)other).map));
}
@Override
public int hashCode() {
return map.hashCode();
}
public static MapOrder getMapOrder(Map,?> map) {
return (map instanceof SortedMap,?>)? MapOrder.KEY_ORDERED : MapOrder.UNORDERED;
}
}
/**
* Sorted map value.
*/
public static final class SortedMapValue extends Value {
private final List extends Entry,?>> list;
private byte[] bytes;
private final MapOrder order;
public SortedMapValue(List extends Entry,?>> list, MapOrder order) {
this.list = list;
this.order = order;
}
@Override
public int estimateSize() throws AerospikeException {
bytes = Packer.pack(list, order);
return bytes.length;
}
@Override
public int write(byte[] buffer, int offset) {
System.arraycopy(bytes, 0, buffer, offset, bytes.length);
return bytes.length;
}
@Override
public void pack(Packer packer) {
packer.packMap(list, order);
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: map");
}
@Override
public int getType() {
return ParticleType.MAP;
}
@Override
public Object getObject() {
return list;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
return instance.getLuaList(list);
}
@Override
public String toString() {
return list.toString();
}
@Override
public boolean equals(Object other) {
if (other == null || ! this.getClass().equals(other.getClass())) {
return false;
}
SortedMapValue o = (SortedMapValue)other;
return this.order == o.order && this.list.equals(o.list);
}
@Override
public int hashCode() {
return list.hashCode();
}
}
/**
* Infinity value.
*/
public static final class InfinityValue extends Value {
@Override
public int estimateSize() {
return 0;
}
@Override
public int write(byte[] buffer, int offset) {
return 0;
}
@Override
public void pack(Packer packer) {
packer.packInfinity();
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: INF");
}
@Override
public int getType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid particle type: INF");
}
@Override
public Object getObject() {
return null;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid lua type: INF");
}
@Override
public String toString() {
return "INF";
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()));
}
@Override
public final int hashCode() {
return 0;
}
}
/**
* Wildcard value.
*/
public static final class WildcardValue extends Value {
@Override
public int estimateSize() {
return 0;
}
@Override
public int write(byte[] buffer, int offset) {
return 0;
}
@Override
public void pack(Packer packer) {
packer.packWildcard();
}
@Override
public void validateKeyType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid key type: wildcard");
}
@Override
public int getType() {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid particle type: wildcard");
}
@Override
public Object getObject() {
return null;
}
@Override
public LuaValue getLuaValue(LuaInstance instance) {
throw new AerospikeException(ResultCode.PARAMETER_ERROR, "Invalid lua type: wildcard");
}
@Override
public String toString() {
return "*";
}
@Override
public boolean equals(Object other) {
return (other != null &&
this.getClass().equals(other.getClass()));
}
@Override
public final int hashCode() {
return 0;
}
}
}