/** * Implementation of {@link ORecordVersion} adapted to distributed environment. Opposite of {@link * OSimpleVersion} contains additional information about timestamp of last change and mac address of * server that made this change. * * @see OVersionFactory * @see ORecordVersion * @author <a href="mailto:[email protected]">Artem Orobets</a> */ public final class ODistributedVersion implements ORecordVersion { public static final int STREAMED_SIZE = OBinaryProtocol.SIZE_INT + OBinaryProtocol.SIZE_LONG + OBinaryProtocol.SIZE_LONG; public static final OBinaryConverter CONVERTER = OBinaryConverterFactory.getConverter(); private int counter; private long timestamp; private long macAddress; public ODistributedVersion() {} public ODistributedVersion(int counter) { this.counter = counter; this.timestamp = System.currentTimeMillis(); this.macAddress = OVersionFactory.instance().getMacAddress(); } public ODistributedVersion(int counter, long timestamp, long macAddress) { this.counter = counter; this.timestamp = timestamp; this.macAddress = macAddress; } @Override public void increment() { if (isTombstone()) throw new IllegalStateException("Record was deleted and can not be updated."); counter++; timestamp = System.currentTimeMillis(); macAddress = OVersionFactory.instance().getMacAddress(); } @Override public void decrement() { if (isTombstone()) throw new IllegalStateException("Record was deleted and can not be updated."); counter--; timestamp = System.currentTimeMillis(); macAddress = OVersionFactory.instance().getMacAddress(); } @Override public boolean isUntracked() { return counter == -1; } @Override public boolean isTemporary() { return counter < -1; } @Override public boolean isValid() { return counter > -1; } @Override public void setCounter(int iVersion) { counter = iVersion; } @Override public int getCounter() { return counter; } @Override public boolean isTombstone() { return counter < 0; } public void convertToTombstone() { if (isTombstone()) throw new IllegalStateException("Record was deleted and can not be updated."); counter++; counter = -counter; timestamp = System.currentTimeMillis(); macAddress = OVersionFactory.instance().getMacAddress(); } @Override public void copyFrom(ORecordVersion version) { ODistributedVersion other = (ODistributedVersion) version; update(other.counter, other.timestamp, other.macAddress); } public void update(int recordVersion, long timestamp, long macAddress) { this.counter = recordVersion; this.timestamp = timestamp; this.macAddress = macAddress; } @Override public void reset() { counter = 0; timestamp = System.currentTimeMillis(); macAddress = OVersionFactory.instance().getMacAddress(); } @Override public void setRollbackMode() { counter = Integer.MIN_VALUE + counter; } @Override public void clearRollbackMode() { counter = counter - Integer.MIN_VALUE; } @Override public void disable() { counter = -1; } @Override public void revive() { counter = -counter; } @Override public ORecordVersion copy() { ODistributedVersion copy = new ODistributedVersion(); copy.counter = counter; copy.timestamp = timestamp; copy.macAddress = macAddress; return copy; } @Override public ORecordVersionSerializer getSerializer() { return ODistributedVersionSerializer.INSTANCE; } @Override public boolean equals(Object other) { return other instanceof ODistributedVersion && ((ODistributedVersion) other).compareTo(this) == 0; } @Override public int hashCode() { int result = counter; result = 31 * result + (int) (timestamp ^ (timestamp >>> 32)); result = 31 * result + (int) (macAddress ^ (macAddress >>> 32)); return result; } @Override public String toString() { return ODistributedVersionSerializer.INSTANCE.toString(this); } @Override public int compareTo(ORecordVersion o) { ODistributedVersion other = (ODistributedVersion) o; final int myCounter; if (isTombstone()) myCounter = -counter; else myCounter = counter; final int otherCounter; if (o.isTombstone()) otherCounter = -o.getCounter(); else otherCounter = o.getCounter(); if (myCounter != otherCounter) return myCounter > otherCounter ? 1 : -1; if (timestamp != other.timestamp) return (timestamp > other.timestamp) ? 1 : -1; if (macAddress > other.macAddress) return 1; else if (macAddress < other.macAddress) return -1; else return 0; } public long getTimestamp() { return timestamp; } public long getMacAddress() { return macAddress; } @Override public void writeExternal(ObjectOutput out) throws IOException { ODistributedVersionSerializer.INSTANCE.writeTo(out, this); } @Override public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException { ODistributedVersionSerializer.INSTANCE.readFrom(in, this); } private static final class ODistributedVersionSerializer implements ORecordVersionSerializer { private static final ODistributedVersionSerializer INSTANCE = new ODistributedVersionSerializer(); @Override public void writeTo(DataOutput out, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; out.writeInt(distributedVersion.counter); out.writeLong(distributedVersion.timestamp); out.writeLong(distributedVersion.macAddress); } @Override public void readFrom(DataInput in, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; distributedVersion.counter = in.readInt(); distributedVersion.timestamp = in.readLong(); distributedVersion.macAddress = in.readLong(); } @Override public void writeTo(OutputStream stream, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; OBinaryProtocol.int2bytes(distributedVersion.counter, stream); OBinaryProtocol.long2bytes(distributedVersion.timestamp, stream); OBinaryProtocol.long2bytes(distributedVersion.macAddress, stream); } @Override public void readFrom(InputStream stream, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; distributedVersion.counter = OBinaryProtocol.bytes2int(stream); distributedVersion.timestamp = OBinaryProtocol.bytes2long(stream); distributedVersion.macAddress = OBinaryProtocol.bytes2long(stream); } @Override public int writeTo(byte[] stream, int pos, ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; OBinaryProtocol.int2bytes(distributedVersion.counter, stream, pos + len); len += OBinaryProtocol.SIZE_INT; OBinaryProtocol.long2bytes(distributedVersion.timestamp, stream, pos + len); len += OBinaryProtocol.SIZE_LONG; OBinaryProtocol.long2bytes(distributedVersion.macAddress, stream, pos + len); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public int readFrom(byte[] iStream, int pos, ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; distributedVersion.counter = OBinaryProtocol.bytes2int(iStream, pos + len); len += OBinaryProtocol.SIZE_INT; distributedVersion.timestamp = OBinaryProtocol.bytes2long(iStream, pos + len); len += OBinaryProtocol.SIZE_LONG; distributedVersion.macAddress = OBinaryProtocol.bytes2long(iStream, pos + len); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public int writeTo(OFile file, long pos, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; file.writeInt(pos + len, distributedVersion.counter); len += OBinaryProtocol.SIZE_INT; file.writeLong(pos + len, distributedVersion.timestamp); len += OBinaryProtocol.SIZE_LONG; file.writeLong(pos + len, distributedVersion.macAddress); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public long readFrom(OFile file, long pos, ORecordVersion version) throws IOException { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; distributedVersion.counter = file.readInt(pos + len); len += OBinaryProtocol.SIZE_INT; distributedVersion.timestamp = file.readLong(pos + len); len += OBinaryProtocol.SIZE_LONG; distributedVersion.macAddress = file.readLong(pos + len); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public int fastWriteTo(byte[] iStream, int pos, ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; CONVERTER.putInt(iStream, pos + len, distributedVersion.counter); len += OBinaryProtocol.SIZE_INT; CONVERTER.putLong(iStream, pos + len, distributedVersion.timestamp); len += OBinaryProtocol.SIZE_LONG; CONVERTER.putLong(iStream, pos + len, distributedVersion.macAddress); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public int fastReadFrom(byte[] iStream, int pos, ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; int len = 0; distributedVersion.counter = CONVERTER.getInt(iStream, pos + len); len += OBinaryProtocol.SIZE_INT; distributedVersion.timestamp = CONVERTER.getLong(iStream, pos + len); len += OBinaryProtocol.SIZE_LONG; distributedVersion.macAddress = CONVERTER.getLong(iStream, pos + len); len += OBinaryProtocol.SIZE_LONG; return len; } @Override public byte[] toByteArray(ORecordVersion version) { int size = OBinaryProtocol.SIZE_INT + OBinaryProtocol.SIZE_LONG + OBinaryProtocol.SIZE_LONG; byte[] buffer = new byte[size]; fastWriteTo(buffer, 0, version); return buffer; } @Override public String toString(ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; return distributedVersion.counter + "." + distributedVersion.timestamp + "." + distributedVersion.macAddress; } @Override public void fromString(String string, ORecordVersion version) { final ODistributedVersion distributedVersion = (ODistributedVersion) version; String[] parts = string.split("\\."); if (parts.length != 3) throw new IllegalArgumentException( "Not correct format of distributed version. Expected <recordVersion>.<timestamp>.<macAddress>"); distributedVersion.counter = Integer.valueOf(parts[0]); distributedVersion.timestamp = Long.valueOf(parts[1]); distributedVersion.macAddress = Long.valueOf(parts[2]); } } }
/** * Serializer for {@link Double} * * @author ibershadskiy <a href="mailto:[email protected]">Ilya Bershadskiy</a> * @since 17.01.12 */ public class ODoubleSerializer implements OBinarySerializer<Double> { private static final OBinaryConverter CONVERTER = OBinaryConverterFactory.getConverter(); public static ODoubleSerializer INSTANCE = new ODoubleSerializer(); public static final byte ID = 6; /** size of double value in bytes */ public static final int DOUBLE_SIZE = 8; public int getObjectSize(Double object) { return DOUBLE_SIZE; } public void serialize(Double object, byte[] stream, int startPosition) { OLongSerializer.INSTANCE.serialize(Double.doubleToLongBits(object), stream, startPosition); } public Double deserialize(byte[] stream, int startPosition) { return Double.longBitsToDouble(OLongSerializer.INSTANCE.deserialize(stream, startPosition)); } public int getObjectSize(byte[] stream, int startPosition) { return DOUBLE_SIZE; } public byte getId() { return ID; } public int getObjectSizeNative(byte[] stream, int startPosition) { return DOUBLE_SIZE; } public void serializeNative(Double object, byte[] stream, int startPosition) { CONVERTER.putLong( stream, startPosition, Double.doubleToLongBits(object), ByteOrder.nativeOrder()); } public Double deserializeNative(byte[] stream, int startPosition) { return Double.longBitsToDouble( CONVERTER.getLong(stream, startPosition, ByteOrder.nativeOrder())); } @Override public void serializeInDirectMemory(Double object, ODirectMemory memory, long pointer) { memory.setLong(pointer, Double.doubleToLongBits(object)); } @Override public Double deserializeFromDirectMemory(ODirectMemory memory, long pointer) { return Double.longBitsToDouble(memory.getLong(pointer)); } @Override public int getObjectSizeInDirectMemory(ODirectMemory memory, long pointer) { return DOUBLE_SIZE; } public boolean isFixedLength() { return true; } public int getFixedLength() { return DOUBLE_SIZE; } }