summaryrefslogtreecommitdiff
path: root/lang/src/main/java/net/openhft/lang/io/serialization/impl
diff options
context:
space:
mode:
Diffstat (limited to 'lang/src/main/java/net/openhft/lang/io/serialization/impl')
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/AllocateInstanceObjectFactory.java68
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferMarshaller.java71
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferZMarshaller.java103
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/BytesMarshallableMarshaller.java72
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java46
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/CollectionMarshaller.java72
-rwxr-xr-x[-rw-r--r--]lang/src/main/java/net/openhft/lang/io/serialization/impl/CompactEnumBytesMarshaller.java24
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java43
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java46
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ExternalizableMarshaller.java65
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java49
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ImmutableMarshaller.java29
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/ListMarshaller.java57
-rwxr-xr-xlang/src/main/java/net/openhft/lang/io/serialization/impl/MapMarshaller.java75
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/NewInstanceObjectFactory.java62
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java27
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/NoObjectFactory.java37
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/NullObjectFactory.java40
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/SetMarshaller.java55
-rwxr-xr-xlang/src/main/java/net/openhft/lang/io/serialization/impl/SnappyStringMarshaller.java208
-rwxr-xr-xlang/src/main/java/net/openhft/lang/io/serialization/impl/StringBuilderPool.java33
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java46
-rwxr-xr-xlang/src/main/java/net/openhft/lang/io/serialization/impl/StringZMapMarshaller.java121
-rw-r--r--lang/src/main/java/net/openhft/lang/io/serialization/impl/VanillaBytesMarshallerFactory.java85
24 files changed, 1354 insertions, 180 deletions
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/AllocateInstanceObjectFactory.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/AllocateInstanceObjectFactory.java
new file mode 100644
index 0000000..70ac6f7
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/AllocateInstanceObjectFactory.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.NativeBytes;
+import net.openhft.lang.io.serialization.ObjectFactory;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Object factory which creates an object by means of {@code Unsafe.allocateInstance()} call,
+ * i. e. without calling constructor.
+ *
+ * @param <E> type of created objects
+ */
+public final class AllocateInstanceObjectFactory<E> implements ObjectFactory<E> {
+ private static final long serialVersionUID = 0L;
+
+ private final Class<E> eClass;
+
+ public AllocateInstanceObjectFactory(Class<E> eClass) {
+ if (eClass.isInterface() || Modifier.isAbstract(eClass.getModifiers()) ||
+ eClass.isEnum()) {
+ throw new IllegalArgumentException(eClass + " should be a non-abstract non-enum class");
+ }
+ this.eClass = eClass;
+ }
+
+ public Class<E> allocatedClass() {
+ return eClass;
+ }
+
+ @SuppressWarnings("unchecked")
+ @Override
+ public E create() throws InstantiationException {
+ return (E) NativeBytes.UNSAFE.allocateInstance(eClass);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == getClass() &&
+ ((AllocateInstanceObjectFactory) obj).eClass == eClass;
+ }
+
+ @Override
+ public int hashCode() {
+ return eClass.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{eClass=" + eClass + "}";
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferMarshaller.java
new file mode 100644
index 0000000..ac4051f
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferMarshaller.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+import java.nio.ByteBuffer;
+
+public enum ByteBufferMarshaller implements CompactBytesMarshaller<ByteBuffer> {
+ INSTANCE;
+
+ @Override
+ public byte code() {
+ return BYTE_BUFFER_CODE;
+ }
+
+ @Override
+ public void write(Bytes bytes, ByteBuffer byteBuffer) {
+ int position = byteBuffer.position();
+ bytes.writeStopBit(byteBuffer.remaining());
+ bytes.write(byteBuffer);
+
+ // reset the position back as we found it
+ byteBuffer.position(position);
+ }
+
+ @Override
+ public ByteBuffer read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public ByteBuffer read(Bytes bytes, @Nullable ByteBuffer byteBuffer) {
+ long length = bytes.readStopBit();
+ assert length <= Integer.MAX_VALUE;
+ if (length < 0 || length > Integer.MAX_VALUE) {
+ throw new IllegalStateException("Invalid length: " + length);
+ }
+ if (byteBuffer == null || byteBuffer.capacity() < length) {
+ byteBuffer = newByteBuffer((int) length);
+
+ } else {
+ byteBuffer.position(0);
+ byteBuffer.limit((int) length);
+ }
+
+ bytes.read(byteBuffer);
+ byteBuffer.flip();
+ return byteBuffer;
+ }
+
+ protected ByteBuffer newByteBuffer(int length) {
+ return ByteBuffer.allocate(length);
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferZMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferZMarshaller.java
new file mode 100644
index 0000000..fe648e9
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ByteBufferZMarshaller.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.nio.ByteBuffer;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+public enum ByteBufferZMarshaller implements CompactBytesMarshaller<ByteBuffer> {
+ INSTANCE;
+
+ @Override
+ public byte code() {
+ return BYTE_BUFFER_CODE;
+ }
+
+ @Override
+ public void write(Bytes bytes, ByteBuffer byteBuffer) {
+ bytes.writeStopBit(byteBuffer.remaining());
+ long position = bytes.position();
+ bytes.clear();
+ bytes.position(position + 4);
+ DataOutputStream dos = new DataOutputStream(new DeflaterOutputStream(bytes.outputStream()));
+ try {
+ while (byteBuffer.remaining() >= 8)
+ dos.writeLong(byteBuffer.getLong());
+ while (byteBuffer.remaining() > 0)
+ dos.write(byteBuffer.get());
+ dos.close();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ bytes.writeUnsignedInt(position, bytes.position() - position - 4);
+
+ bytes.write(byteBuffer);
+ }
+
+ @Override
+ public ByteBuffer read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public ByteBuffer read(Bytes bytes, @Nullable ByteBuffer byteBuffer) {
+ long length = bytes.readStopBit();
+ if (length < 0 || length > Integer.MAX_VALUE) {
+ throw new IllegalStateException("Invalid length: " + length);
+ }
+ if (byteBuffer == null || byteBuffer.capacity() < length) {
+ byteBuffer = newByteBuffer((int) length);
+
+ } else {
+ byteBuffer.clear();
+ }
+ byteBuffer.limit((int) length);
+
+ long position = bytes.position();
+ long end = position + length;
+
+ long limit = bytes.limit();
+ bytes.limit(end);
+
+ DataInputStream dis = new DataInputStream(new InflaterInputStream(bytes.inputStream()));
+ try {
+ while (byteBuffer.remaining() >= 8)
+ byteBuffer.putLong(dis.readLong());
+ while (byteBuffer.remaining() >= 0)
+ byteBuffer.put(dis.readByte());
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ bytes.position(end);
+ bytes.limit(limit);
+
+ byteBuffer.flip();
+ return byteBuffer;
+ }
+
+ protected ByteBuffer newByteBuffer(int length) {
+ return ByteBuffer.allocate(length);
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/BytesMarshallableMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/BytesMarshallableMarshaller.java
index ebcb95f..59ea161 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/BytesMarshallableMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/BytesMarshallableMarshaller.java
@@ -1,31 +1,34 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.NativeBytes;
import net.openhft.lang.io.serialization.BytesMarshallable;
import net.openhft.lang.io.serialization.BytesMarshaller;
-import net.openhft.lang.io.NativeBytes;
-import org.jetbrains.annotations.NotNull;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
/**
* @author peter.lawrey
*/
-public class BytesMarshallableMarshaller<E extends BytesMarshallable> implements BytesMarshaller<E> {
+public class BytesMarshallableMarshaller<E extends BytesMarshallable>
+ implements BytesMarshaller<E> {
+ private static final long serialVersionUID = 0L;
@NotNull
private final Class<E> classMarshaled;
@@ -33,6 +36,10 @@ public class BytesMarshallableMarshaller<E extends BytesMarshallable> implements
this.classMarshaled = classMarshaled;
}
+ public final Class<E> marshaledClass() {
+ return classMarshaled;
+ }
+
@Override
public void write(@NotNull Bytes bytes, @NotNull E e) {
e.writeMarshallable(bytes);
@@ -40,13 +47,42 @@ public class BytesMarshallableMarshaller<E extends BytesMarshallable> implements
@Override
public E read(@NotNull Bytes bytes) {
- E e;
- try {
- e = (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled);
- } catch (Exception e2) {
- throw new IllegalStateException(e2);
+ return read(bytes, null);
+ }
+
+ @Nullable
+ @Override
+ public E read(Bytes bytes, @Nullable E e) {
+ if (e == null) {
+ try {
+ e = getInstance();
+ } catch (Exception e2) {
+ throw new IllegalStateException(e2);
+ }
}
e.readMarshallable(bytes);
return e;
}
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ protected E getInstance() throws Exception {
+ return (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == getClass() &&
+ ((BytesMarshallableMarshaller) obj).classMarshaled == classMarshaled;
+ }
+
+ @Override
+ public int hashCode() {
+ return classMarshaled.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{classMarshaled=" + classMarshaled + "}";
+ }
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java
index db36c37..92be9bd 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ClassMarshaller.java
@@ -1,17 +1,17 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
@@ -19,8 +19,9 @@ package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.Compare;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
+import net.openhft.lang.pool.StringInterner;
import java.lang.ref.WeakReference;
import java.math.BigDecimal;
@@ -32,7 +33,8 @@ import java.util.Map;
/**
* @author peter.lawrey
*/
-public class ClassMarshaller implements CompactBytesMarshaller<Class> {
+public class ClassMarshaller extends ImmutableMarshaller<Class>
+ implements CompactBytesMarshaller<Class> {
private static final int CACHE_SIZE = 1019;
private static final Map<String, Class> SC_SHORT_NAME = new LinkedHashMap<String, Class>();
private static final Map<Class, String> CS_SHORT_NAME = new LinkedHashMap<Class, String>();
@@ -48,7 +50,7 @@ public class ClassMarshaller implements CompactBytesMarshaller<Class> {
}
private final ClassLoader classLoader;
- private final StringBuilder className = new StringBuilder(40);
+ private static final StringBuilderPool sbp = new StringBuilderPool();
@Nullable
@SuppressWarnings("unchecked")
private WeakReference<Class>[] classWeakReference = null;
@@ -68,9 +70,9 @@ public class ClassMarshaller implements CompactBytesMarshaller<Class> {
@Nullable
@Override
public Class read(@NotNull Bytes bytes) {
- className.setLength(0);
- bytes.readUTFΔ(className);
- return load(className);
+ StringBuilder sb = sbp.acquireStringBuilder();
+ bytes.readUTFΔ(sb);
+ return load(sb);
}
@Nullable
@@ -82,15 +84,16 @@ public class ClassMarshaller implements CompactBytesMarshaller<Class> {
WeakReference<Class> ref = classWeakReference[hash];
if (ref != null) {
Class clazz = ref.get();
- if (clazz != null && clazz.getName().equals(name))
+ if (clazz != null && StringInterner.isEqual(clazz.getName(), name))
return clazz;
}
try {
- Class<?> clazz = SC_SHORT_NAME.get(name.toString());
+ String className = name.toString();
+ Class<?> clazz = SC_SHORT_NAME.get(className);
if (clazz != null)
return clazz;
- clazz = classLoader.loadClass(name.toString());
+ clazz = classLoader.loadClass(className);
classWeakReference[hash] = new WeakReference<Class>(clazz);
return clazz;
} catch (ClassNotFoundException e) {
@@ -100,6 +103,7 @@ public class ClassMarshaller implements CompactBytesMarshaller<Class> {
@Override
public byte code() {
- return 'C' & 31; // control C
+ return CLASS_CODE; // control C
}
}
+ \ No newline at end of file
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/CollectionMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/CollectionMarshaller.java
new file mode 100644
index 0000000..dbf8f53
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/CollectionMarshaller.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+import java.util.Collection;
+
+abstract class CollectionMarshaller<E, C extends Collection<E>> {
+
+ public static final int NULL_LENGTH = -1;
+ final BytesMarshaller<E> eBytesMarshaller;
+
+ protected CollectionMarshaller(BytesMarshaller<E> eBytesMarshaller) {
+ this.eBytesMarshaller = eBytesMarshaller;
+ }
+
+ public void write(Bytes bytes, C c) {
+ if (c == null) {
+ bytes.writeStopBit(NULL_LENGTH);
+ return;
+ }
+ bytes.writeStopBit(c.size());
+ for (E e : c) {
+ eBytesMarshaller.write(bytes, e);
+ }
+ }
+
+ public C read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ abstract C newCollection();
+
+ public C read(Bytes bytes, @Nullable C c) {
+ long length = bytes.readStopBit();
+
+ if (length == 0 && c != null) {
+ c.clear();
+ return c;
+ }
+
+ if (length < NULL_LENGTH || length > Integer.MAX_VALUE)
+ throw new IllegalStateException("Invalid length: " + length);
+
+ if (length == NULL_LENGTH)
+ return null;
+
+ if (c == null)
+ c = newCollection();
+
+ return readCollection(bytes, c, (int) length);
+ }
+
+ abstract C readCollection(Bytes bytes, C c, int length);
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/CompactEnumBytesMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/CompactEnumBytesMarshaller.java
index 08f66e4..676c86c 100644..100755
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/CompactEnumBytesMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/CompactEnumBytesMarshaller.java
@@ -1,26 +1,26 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
-import org.jetbrains.annotations.NotNull;
+import net.openhft.lang.model.constraints.NotNull;
/**
- * Created with IntelliJ IDEA. User: peter Date: 09/12/13 Time: 17:05 To change this template use File | Settings | File
+ * Created with IntelliJ IDEA. User: peter.lawrey Date: 09/12/13 Time: 17:05
* Templates.
*/
public class CompactEnumBytesMarshaller<E> extends GenericEnumMarshaller<E> implements CompactBytesMarshaller<E> {
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java
index 03f6bb1..1e949c5 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/DateMarshaller.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
import java.util.Date;
@@ -27,8 +27,8 @@ import java.util.Date;
* @author peter.lawrey
*/
public class DateMarshaller implements CompactBytesMarshaller<Date> {
- final int size1;
- private final StringBuilder sb = new StringBuilder();
+ private final int size1;
+ private static final StringBuilderPool sbp = new StringBuilderPool();
@Nullable
private Date[] interner = null;
@@ -65,12 +65,25 @@ public class DateMarshaller implements CompactBytesMarshaller<Date> {
@Nullable
@Override
public Date read(@NotNull Bytes bytes) {
+ StringBuilder sb = sbp.acquireStringBuilder();
bytes.readUTFΔ(sb);
long time = parseLong(sb);
return lookupDate(time);
}
@Nullable
+ @Override
+ public Date read(Bytes bytes, @Nullable Date date) {
+ if (date == null)
+ return read(bytes);
+ StringBuilder sb = sbp.acquireStringBuilder();
+ bytes.readUTFΔ(sb);
+ long time = parseLong(sb);
+ date.setTime(time);
+ return date;
+ }
+
+ @Nullable
private Date lookupDate(long time) {
int idx = hashFor(time);
if (interner == null)
@@ -90,6 +103,6 @@ public class DateMarshaller implements CompactBytesMarshaller<Date> {
@Override
public byte code() {
- return 'T' & 31; // Control T.
+ return DATE_CODE; // Control T.
}
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java
index 11f060b..189f7f5 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/EnumBytesMarshaller.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshaller;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
import java.util.BitSet;
import java.util.LinkedHashMap;
@@ -28,19 +28,17 @@ import java.util.Map;
/**
* @author peter.lawrey
*/
-public class EnumBytesMarshaller<E extends Enum<E>> implements BytesMarshaller<E> {
- @NotNull
- private final Class<E> classMarshaled;
+public class EnumBytesMarshaller<E extends Enum<E>> extends ImmutableMarshaller<E>
+ implements BytesMarshaller<E> {
@SuppressWarnings("unchecked")
private final E[] interner = (E[]) new Enum[1024];
private final BitSet internerDup = new BitSet(1024);
- private final Map<String, E> map = new LinkedHashMap<String, E>();
+ private final Map<String, E> map = new LinkedHashMap<String, E>(64);
private final E defaultValue;
private final int mask;
- private final StringBuilder reader = new StringBuilder();
+ private static final StringBuilderPool sbp = new StringBuilderPool();
public EnumBytesMarshaller(@NotNull Class<E> classMarshaled, E defaultValue) {
- this.classMarshaled = classMarshaled;
this.defaultValue = defaultValue;
mask = interner.length - 1;
@@ -52,6 +50,7 @@ public class EnumBytesMarshaller<E extends Enum<E>> implements BytesMarshaller<E
//noinspection UnqualifiedFieldAccess,AssignmentToNull
interner[idx] = null;
internerDup.set(idx);
+
} else {
interner[idx] = e;
}
@@ -77,17 +76,18 @@ public class EnumBytesMarshaller<E extends Enum<E>> implements BytesMarshaller<E
@Override
public E read(@NotNull Bytes bytes) {
- bytes.readUTFΔ(reader);
- return builderToEnum();
+ StringBuilder sb = sbp.acquireStringBuilder();
+ bytes.readUTFΔ(sb);
+ return builderToEnum(sb);
}
- private E builderToEnum() {
- int num = hashFor(reader);
+ private E builderToEnum(StringBuilder sb) {
+ int num = hashFor(sb);
int idx = num & mask;
E e = interner[idx];
if (e != null) return e;
if (!internerDup.get(idx)) return defaultValue;
- e = map.get(reader.toString());
+ e = map.get(sb.toString());
return e == null ? defaultValue : e;
}
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ExternalizableMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ExternalizableMarshaller.java
index 05f5390..4e9b82c 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ExternalizableMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ExternalizableMarshaller.java
@@ -1,25 +1,26 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
-import net.openhft.lang.io.serialization.BytesMarshaller;
import net.openhft.lang.io.NativeBytes;
-import org.jetbrains.annotations.NotNull;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
import java.io.Externalizable;
import java.io.IOException;
@@ -28,6 +29,8 @@ import java.io.IOException;
* @author peter.lawrey
*/
public class ExternalizableMarshaller<E extends Externalizable> implements BytesMarshaller<E> {
+ private static final long serialVersionUID = 0L;
+
@NotNull
private final Class<E> classMarshaled;
@@ -35,6 +38,10 @@ public class ExternalizableMarshaller<E extends Externalizable> implements Bytes
this.classMarshaled = classMarshaled;
}
+ public final Class<E> marshaledClass() {
+ return classMarshaled;
+ }
+
@Override
public void write(Bytes bytes, @NotNull E e) {
try {
@@ -46,13 +53,41 @@ public class ExternalizableMarshaller<E extends Externalizable> implements Bytes
@Override
public E read(Bytes bytes) {
- E e;
+ return read(bytes, null);
+ }
+
+ @Nullable
+ @Override
+ public E read(Bytes bytes, @Nullable E e) {
try {
- e = (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled);
+ if (e == null)
+ e = getInstance();
e.readExternal(bytes);
+ return e;
} catch (Exception e2) {
throw new IllegalStateException(e2);
}
- return e;
+ }
+
+ @SuppressWarnings("unchecked")
+ @NotNull
+ protected E getInstance() throws Exception {
+ return (E) NativeBytes.UNSAFE.allocateInstance(classMarshaled);
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == getClass() &&
+ ((ExternalizableMarshaller) obj).classMarshaled == classMarshaled;
+ }
+
+ @Override
+ public int hashCode() {
+ return classMarshaled.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{marshaledClass=" + classMarshaled + "}";
}
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java
index 8a1b52d..8ed4590 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/GenericEnumMarshaller.java
@@ -1,25 +1,25 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshaller;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
@@ -30,17 +30,20 @@ import java.util.Map;
* @author peter.lawrey
*/
public class GenericEnumMarshaller<E> implements BytesMarshaller<E> {
- @NotNull
- private final Class<E> classMarshaled;
+ private final int capacity;
@Nullable
- private final Constructor<E> constructor;
+ private transient final Constructor<E> constructor;
@Nullable
- private final Method valueOf;
+ private transient final Method valueOf;
@NotNull
private final Map<String, E> map;
+ //used by the read resolve method
+ private final Class<E> classMarshaled;
+
public GenericEnumMarshaller(@NotNull Class<E> classMarshaled, final int capacity) {
this.classMarshaled = classMarshaled;
+ this.capacity = capacity;
Constructor<E> constructor = null;
Method valueOf = null;
try {
@@ -48,6 +51,7 @@ public class GenericEnumMarshaller<E> implements BytesMarshaller<E> {
} catch (NoSuchMethodException e) {
try {
constructor = classMarshaled.getConstructor(String.class);
+ constructor.setAccessible(true);
} catch (NoSuchMethodException e1) {
throw new IllegalArgumentException(classMarshaled + " doesn't have a valueOf(String) or a Constructor(String)");
}
@@ -62,6 +66,10 @@ public class GenericEnumMarshaller<E> implements BytesMarshaller<E> {
};
}
+ private Object readResolve() {
+ return new GenericEnumMarshaller(classMarshaled, capacity);
+ }
+
@Override
public void write(@NotNull Bytes bytes, @Nullable E e) {
bytes.writeUTFΔ(e == null ? null : e.toString());
@@ -74,19 +82,26 @@ public class GenericEnumMarshaller<E> implements BytesMarshaller<E> {
return s == null ? null : valueOf(s);
}
+ @Nullable
+ @Override
+ public E read(Bytes bytes, @Nullable E e) {
+ return read(bytes);
+ }
+
private E valueOf(String s) {
E e = map.get(s);
if (e == null)
try {
if (constructor != null) {
map.put(s, e = constructor.newInstance(s));
+
} else {
@SuppressWarnings("unchecked")
E invoke = (E) valueOf.invoke(null, s);
map.put(s, e = invoke);
}
} catch (Exception t) {
- throw new AssertionError(t.getCause());
+ throw new AssertionError(t);
}
return e;
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ImmutableMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ImmutableMarshaller.java
new file mode 100644
index 0000000..de55a9c
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ImmutableMarshaller.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+abstract class ImmutableMarshaller<E> implements BytesMarshaller<E> {
+ @Nullable
+ @Override
+ public final E read(Bytes bytes, @Nullable E e) {
+ return read(bytes);
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/ListMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ListMarshaller.java
new file mode 100644
index 0000000..cc9b592
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/ListMarshaller.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class ListMarshaller<E> extends CollectionMarshaller<E, List<E>> implements CompactBytesMarshaller<List<E>> {
+
+ ListMarshaller(BytesMarshaller<E> eBytesMarshaller) {
+ super(eBytesMarshaller);
+ }
+
+ public static <E> BytesMarshaller<List<E>> of(BytesMarshaller<E> eBytesMarshaller) {
+ return new ListMarshaller<E>(eBytesMarshaller);
+ }
+
+ @Override
+ public byte code() {
+ return LIST_CODE;
+ }
+
+ @Override
+ List<E> newCollection() {
+ return new ArrayList<E>();
+ }
+
+ @Override
+ List<E> readCollection(Bytes bytes, List<E> es, int length) {
+ List<E> ret = es;
+ ret.clear();
+
+ for (int i = 0; i < length; i++) {
+ ret.add(eBytesMarshaller.read(bytes));
+ }
+
+ return ret;
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/MapMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/MapMarshaller.java
new file mode 100755
index 0000000..195d96d
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/MapMarshaller.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * Created by peter.lawrey on 24/10/14.
+ */
+public class MapMarshaller<K, V> implements CompactBytesMarshaller<Map<K, V>> {
+ private final BytesMarshaller<K> kBytesMarshaller;
+ private final BytesMarshaller<V> vBytesMarshaller;
+
+ MapMarshaller(BytesMarshaller<K> kBytesMarshaller, BytesMarshaller<V> vBytesMarshaller) {
+ this.kBytesMarshaller = kBytesMarshaller;
+ this.vBytesMarshaller = vBytesMarshaller;
+ }
+
+ @Override
+ public byte code() {
+ return MAP_CODE;
+ }
+
+ @Override
+ public void write(Bytes bytes, Map<K, V> kvMap) {
+ bytes.writeInt(kvMap.size());
+ for (Map.Entry<K, V> entry : kvMap.entrySet()) {
+ kBytesMarshaller.write(bytes, entry.getKey());
+ vBytesMarshaller.write(bytes, entry.getValue());
+ }
+ }
+
+ @Override
+ public Map<K, V> read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public Map<K, V> read(Bytes bytes, @Nullable Map<K, V> kvMap) {
+ if (kvMap == null) {
+ kvMap = new LinkedHashMap<K, V>();
+
+ } else {
+ kvMap.clear();
+ }
+ int size = bytes.readInt();
+ for (int i = 0; i < size; i++)
+ kvMap.put(kBytesMarshaller.read(bytes), vBytesMarshaller.read(bytes));
+ return kvMap;
+ }
+
+ public static <K, V> BytesMarshaller<Map<K, V>> of(BytesMarshaller<K> keyMarshaller, BytesMarshaller<V> valueMarshaller) {
+ return new MapMarshaller<K, V>(keyMarshaller, valueMarshaller);
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/NewInstanceObjectFactory.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NewInstanceObjectFactory.java
new file mode 100644
index 0000000..0fba720
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NewInstanceObjectFactory.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.serialization.ObjectFactory;
+
+import java.lang.reflect.Modifier;
+
+/**
+ * Object factory which creates an object by means of {@link Class#newInstance()} call,
+ * i. e. with calling the default no-arg constructor of the class.
+ *
+ * @param <E> type of created objects
+ */
+public final class NewInstanceObjectFactory<E> implements ObjectFactory<E> {
+ private static final long serialVersionUID = 0L;
+
+ private final Class<E> eClass;
+
+ public NewInstanceObjectFactory(Class<E> eClass) {
+ if (eClass.isInterface() || Modifier.isAbstract(eClass.getModifiers()) ||
+ eClass.isEnum()) {
+ throw new IllegalArgumentException(eClass + " should be a non-abstract non-enum class");
+ }
+ this.eClass = eClass;
+ }
+
+ @Override
+ public E create() throws IllegalAccessException, InstantiationException {
+ return eClass.newInstance();
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ return obj != null && obj.getClass() == getClass() &&
+ ((NewInstanceObjectFactory) obj).eClass == eClass;
+ }
+
+ @Override
+ public int hashCode() {
+ return eClass.hashCode();
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "{eClass=" + eClass + "}";
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java
index 1369c4a..c76054c 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoMarshaller.java
@@ -1,23 +1,24 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
/**
* Created with IntelliJ IDEA. User: peter.lawrey Date: 19/09/13 Time: 18:26 To change this template use File | Settings | File
@@ -35,4 +36,10 @@ public enum NoMarshaller implements BytesMarshaller<Void> {
public Void read(Bytes bytes) {
throw new UnsupportedOperationException();
}
+
+ @Nullable
+ @Override
+ public Void read(Bytes bytes, @Nullable Void aVoid) {
+ throw new UnsupportedOperationException();
+ }
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoObjectFactory.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoObjectFactory.java
new file mode 100644
index 0000000..c3e061f
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NoObjectFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.serialization.ObjectFactory;
+
+/**
+ * Placeholder object factory which always throws {@code UnsupportedOperationException}.
+ */
+public enum NoObjectFactory implements ObjectFactory {
+ INSTANCE;
+
+ /**
+ * Always throws {@code UnsupportedOperationException}.
+ *
+ * @return nothing
+ * @throws UnsupportedOperationException always
+ */
+ @Override
+ public Object create() throws UnsupportedOperationException {
+ throw new UnsupportedOperationException();
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/NullObjectFactory.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NullObjectFactory.java
new file mode 100644
index 0000000..af76bc7
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/NullObjectFactory.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.serialization.ObjectFactory;
+
+/**
+ * Object factory which always returns {@code null}.
+ */
+public enum NullObjectFactory implements ObjectFactory {
+ INSTANCE;
+
+ public static <E> ObjectFactory<E> of() {
+ return INSTANCE;
+ }
+
+ /**
+ * Always returns {@code null}.
+ *
+ * @return {@code null}
+ */
+ @Override
+ public Object create() {
+ return null;
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/SetMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/SetMarshaller.java
new file mode 100644
index 0000000..e401722
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/SetMarshaller.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.BytesMarshaller;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+public class SetMarshaller<E> extends CollectionMarshaller<E, Set<E>> implements CompactBytesMarshaller<Set<E>> {
+ SetMarshaller(BytesMarshaller<E> eBytesMarshaller) {
+ super(eBytesMarshaller);
+ }
+
+ public static <E> BytesMarshaller<Set<E>> of(BytesMarshaller<E> eBytesMarshaller) {
+ return new SetMarshaller<E>(eBytesMarshaller);
+ }
+
+ @Override
+ public byte code() {
+ return SET_CODE;
+ }
+
+ @Override
+ Set<E> newCollection() {
+ return new LinkedHashSet<E>();
+ }
+
+ @Override
+ Set<E> readCollection(Bytes bytes, Set<E> es, int length) {
+ es.clear();
+
+ for (int i = 0; i < length; i++) {
+ es.add(eBytesMarshaller.read(bytes));
+ }
+
+ return es;
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/SnappyStringMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/SnappyStringMarshaller.java
new file mode 100755
index 0000000..14ff64f
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/SnappyStringMarshaller.java
@@ -0,0 +1,208 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.ByteBufferBytes;
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+import org.xerial.snappy.Snappy;
+
+import java.io.IOException;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.InvocationTargetException;
+import java.nio.ByteBuffer;
+
+/**
+ * Created by peter.lawrey on 24/10/14.
+ */
+public enum SnappyStringMarshaller implements CompactBytesMarshaller<CharSequence> {
+ INSTANCE;
+ private static final StringFactory STRING_FACTORY = getStringFactory();
+
+ private static final int NULL_LENGTH = -1;
+
+ private static StringFactory getStringFactory() {
+ try {
+ return new StringFactory17();
+ } catch (Exception e) {
+ // do nothing
+ }
+
+ try {
+ return new StringFactory16();
+ } catch (Exception e) {
+ // no more alternatives
+ throw new AssertionError(e);
+ }
+ }
+
+ private static final ThreadLocal<ThreadLocals> THREAD_LOCALS = new ThreadLocal<ThreadLocals>();
+
+ static class ThreadLocals {
+ ByteBuffer decompressedByteBuffer = ByteBuffer.allocateDirect(32 * 1024);
+ Bytes decompressedBytes = ByteBufferBytes.wrap(decompressedByteBuffer);
+ ByteBuffer compressedByteBuffer = ByteBuffer.allocateDirect(0);
+
+ public void clear() {
+ decompressedByteBuffer.clear();
+ decompressedBytes.clear();
+ compressedByteBuffer.clear();
+ }
+ }
+
+ @Override
+ public byte code() {
+ return STRINGZ_CODE;
+ }
+
+ public ThreadLocals acquireThreadLocals() {
+ ThreadLocals threadLocals = THREAD_LOCALS.get();
+ if (threadLocals == null)
+ THREAD_LOCALS.set(threadLocals = new ThreadLocals());
+ threadLocals.clear();
+ return threadLocals;
+ }
+
+ @Override
+ public void write(Bytes bytes, CharSequence s) {
+ if (s == null) {
+ bytes.writeStopBit(NULL_LENGTH);
+ return;
+
+ } else if (s.length() == 0) {
+ bytes.writeStopBit(0);
+ return;
+ }
+ // write the total length.
+ int length = s.length();
+ bytes.writeStopBit(length);
+
+ ThreadLocals threadLocals = acquireThreadLocals();
+ // stream the portions of the string.
+ Bytes db = threadLocals.decompressedBytes;
+ ByteBuffer dbb = threadLocals.decompressedByteBuffer;
+ ByteBuffer cbb = bytes.sliceAsByteBuffer(threadLocals.compressedByteBuffer);
+
+ int position = 0;
+ while (position < length) {
+ // 3 is the longest encoding.
+ while (position < length && db.remaining() >= 3)
+ db.writeStopBit(s.charAt(position++));
+ dbb.position(0);
+ dbb.limit((int) db.position());
+ // portion copied now compress it.
+ int portionLengthPos = cbb.position();
+ cbb.putShort((short) 0);
+ int compressedLength;
+ try {
+ Snappy.compress(dbb, cbb);
+ compressedLength = cbb.remaining();
+ if (compressedLength >= 1 << 16)
+ throw new AssertionError();
+ // unflip.
+ cbb.position(cbb.limit());
+ cbb.limit(cbb.capacity());
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ cbb.putShort(portionLengthPos, (short) compressedLength);
+ db.clear();
+ }
+ // the end.
+ cbb.putShort((short) 0);
+ bytes.position(bytes.position() + cbb.position());
+ }
+
+ @Override
+ public String read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public String read(Bytes bytes, @Nullable CharSequence ignored) {
+ long size = bytes.readStopBit();
+ if (size == NULL_LENGTH)
+ return null;
+ if (size < 0 || size > Integer.MAX_VALUE)
+ throw new IllegalStateException("Invalid length: " + size);
+ if (size == 0)
+ return "";
+ ThreadLocals threadLocals = acquireThreadLocals();
+ // stream the portions of the string.
+ Bytes db = threadLocals.decompressedBytes;
+ ByteBuffer dbb = threadLocals.decompressedByteBuffer;
+ ByteBuffer cbb = bytes.sliceAsByteBuffer(threadLocals.compressedByteBuffer);
+
+ char[] chars = new char[(int) size];
+ int pos = 0;
+ for (int chunkLen; (chunkLen = cbb.getShort() & 0xFFFF) > 0; ) {
+ cbb.limit(cbb.position() + chunkLen);
+ dbb.clear();
+ try {
+ Snappy.uncompress(cbb, dbb);
+ cbb.position(cbb.limit());
+ cbb.limit(cbb.capacity());
+ } catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ db.position(0);
+ db.limit(dbb.limit());
+ while (db.remaining() > 0)
+ chars[pos++] = (char) db.readStopBit();
+ }
+ bytes.position(bytes.position() + cbb.position());
+ try {
+ return STRING_FACTORY.fromChars(chars);
+ } catch (Exception e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ private static abstract class StringFactory {
+ abstract String fromChars(char[] chars) throws IllegalAccessException, InvocationTargetException, InstantiationException;
+ }
+
+ private static final class StringFactory16 extends StringFactory {
+ private final Constructor<String> constructor;
+
+ private StringFactory16() throws NoSuchMethodException {
+ constructor = String.class.getDeclaredConstructor(int.class,
+ int.class, char[].class);
+ constructor.setAccessible(true);
+ }
+
+ @Override
+ String fromChars(char[] chars) throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ return constructor.newInstance(0, chars.length, chars);
+ }
+ }
+
+ private static final class StringFactory17 extends StringFactory {
+ private final Constructor<String> constructor;
+
+ private StringFactory17() throws NoSuchMethodException {
+ constructor = String.class.getDeclaredConstructor(char[].class, boolean.class);
+ constructor.setAccessible(true);
+ }
+
+ @Override
+ String fromChars(char[] chars) throws IllegalAccessException, InvocationTargetException, InstantiationException {
+ return constructor.newInstance(chars, true);
+ }
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringBuilderPool.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringBuilderPool.java
new file mode 100755
index 0000000..d7ca469
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringBuilderPool.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+/**
+ * Created by peter.lawrey on 29/10/14.
+ */
+public class StringBuilderPool {
+ final ThreadLocal<StringBuilder> sbtl = new ThreadLocal<StringBuilder>();
+
+ public StringBuilder acquireStringBuilder() {
+ StringBuilder sb = sbtl.get();
+ if (sb == null) {
+ sbtl.set(sb = new StringBuilder(128));
+ }
+ sb.setLength(0);
+ return sb;
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java
index 2fb2ee5..67843ae 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringMarshaller.java
@@ -1,34 +1,35 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.NotNull;
+import net.openhft.lang.model.constraints.Nullable;
import net.openhft.lang.pool.StringInterner;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
/**
* @author peter.lawrey
*/
-public class StringMarshaller implements CompactBytesMarshaller<String> {
+public class StringMarshaller extends ImmutableMarshaller<String>
+ implements CompactBytesMarshaller<String> {
private final int size;
- private final StringBuilder reader = new StringBuilder();
- private StringInterner interner;
+ private static final StringBuilderPool sbp = new StringBuilderPool();
+ private transient StringInterner interner;
public StringMarshaller(int size) {
this.size = size;
@@ -42,19 +43,22 @@ public class StringMarshaller implements CompactBytesMarshaller<String> {
@Nullable
@Override
public String read(@NotNull Bytes bytes) {
- if (bytes.readUTFΔ(reader))
- return builderToString();
+ StringBuilder sb = sbp.acquireStringBuilder();
+ if (bytes.readUTFΔ(sb))
+ return builderToString(sb);
return null;
}
-
- private String builderToString() {
- if (interner == null)
+ private String builderToString(StringBuilder reader) {
+ if (interner == null) {
+ if (size == 0)
+ return reader.toString();
interner = new StringInterner(size);
+ }
return interner.intern(reader);
}
public byte code() {
- return 'S' & 31;
+ return STRING_CODE;
}
}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringZMapMarshaller.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringZMapMarshaller.java
new file mode 100755
index 0000000..efec05e
--- /dev/null
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/StringZMapMarshaller.java
@@ -0,0 +1,121 @@
+/*
+ * Copyright (C) 2015 higherfrequencytrading.com
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+package net.openhft.lang.io.serialization.impl;
+
+import net.openhft.lang.io.Bytes;
+import net.openhft.lang.io.serialization.CompactBytesMarshaller;
+import net.openhft.lang.model.constraints.Nullable;
+
+import java.io.DataInputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.StreamCorruptedException;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.zip.Deflater;
+import java.util.zip.DeflaterOutputStream;
+import java.util.zip.InflaterInputStream;
+
+/**
+ * Created by peter.lawrey on 24/10/14.
+ */
+public enum StringZMapMarshaller implements CompactBytesMarshaller<Map<String, String>> {
+ FAST(Deflater.BEST_SPEED),
+ COMPACT(Deflater.BEST_COMPRESSION),
+ INSTANCE(Deflater.DEFAULT_STRATEGY);
+
+ private final int level;
+
+ private static final long NULL_SIZE = -1;
+
+ StringZMapMarshaller(int level) {
+ this.level = level;
+ }
+
+ @Override
+ public byte code() {
+ return STRINGZ_MAP_CODE;
+ }
+
+ @Override
+ public void write(Bytes bytes, Map<String, String> kvMap) {
+ if (kvMap == null) {
+ bytes.writeStopBit(NULL_SIZE);
+ return;
+ }
+
+ bytes.writeStopBit(kvMap.size());
+ long position = bytes.position();
+ bytes.clear();
+ bytes.position(position + 4);
+ DataOutputStream dos = new DataOutputStream(
+ new DeflaterOutputStream(bytes.outputStream(), new Deflater(level)));
+ try {
+ for (Map.Entry<String, String> entry : kvMap.entrySet()) {
+ dos.writeUTF(entry.getKey());
+ dos.writeUTF(entry.getValue());
+ }
+ dos.close();
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ bytes.writeUnsignedInt(position, bytes.position() - position - 4);
+ }
+
+ @Override
+ public Map<String, String> read(Bytes bytes) {
+ return read(bytes, null);
+ }
+
+ @Override
+ public Map<String, String> read(Bytes bytes, @Nullable Map<String, String> kvMap) {
+ long size = bytes.readStopBit();
+ if (size == NULL_SIZE)
+ return null;
+ if (size < 0 || size > Integer.MAX_VALUE)
+ throw new IllegalStateException("Invalid length: " + size);
+
+ long length = bytes.readUnsignedInt();
+ if (length < 0 || length > Integer.MAX_VALUE)
+ throw new IllegalStateException(new StreamCorruptedException());
+ long position = bytes.position();
+ long end = position + length;
+
+ long limit = bytes.limit();
+ bytes.limit(end);
+
+ DataInputStream dis = new DataInputStream(new InflaterInputStream(bytes.inputStream()));
+ if (kvMap == null) {
+ kvMap = new LinkedHashMap<String, String>();
+
+ } else {
+ kvMap.clear();
+ }
+ try {
+ for (int i = 0; i < size; i++) {
+ String key = dis.readUTF();
+ String value = dis.readUTF();
+ kvMap.put(key, value);
+ }
+ } catch (IOException e) {
+ throw new IllegalStateException(e);
+ }
+ bytes.position(end);
+ bytes.limit(limit);
+ return kvMap;
+ }
+}
diff --git a/lang/src/main/java/net/openhft/lang/io/serialization/impl/VanillaBytesMarshallerFactory.java b/lang/src/main/java/net/openhft/lang/io/serialization/impl/VanillaBytesMarshallerFactory.java
index 6fc66ee..3e8d94a 100644
--- a/lang/src/main/java/net/openhft/lang/io/serialization/impl/VanillaBytesMarshallerFactory.java
+++ b/lang/src/main/java/net/openhft/lang/io/serialization/impl/VanillaBytesMarshallerFactory.java
@@ -1,17 +1,17 @@
/*
- * Copyright 2013 Peter Lawrey
+ * Copyright (C) 2015 higherfrequencytrading.com
*
- * 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
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License.
*
- * http://www.apache.org/licenses/LICENSE-2.0
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
*
- * 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.
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
package net.openhft.lang.io.serialization.impl;
@@ -20,63 +20,92 @@ import net.openhft.lang.io.serialization.BytesMarshallable;
import net.openhft.lang.io.serialization.BytesMarshaller;
import net.openhft.lang.io.serialization.BytesMarshallerFactory;
import net.openhft.lang.io.serialization.CompactBytesMarshaller;
-import org.jetbrains.annotations.NotNull;
+import net.openhft.lang.model.constraints.NotNull;
import java.io.Externalizable;
+import java.nio.ByteBuffer;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.Map;
+import static net.openhft.lang.io.serialization.CompactBytesMarshaller.*;
+
/**
* @author peter.lawrey
*/
-public class VanillaBytesMarshallerFactory implements BytesMarshallerFactory {
+public final class VanillaBytesMarshallerFactory implements BytesMarshallerFactory {
+ private static final long serialVersionUID = 1L;
+
+ private transient Map<Class<?>, BytesMarshaller<?>> marshallerMap;
+ private transient BytesMarshaller<?>[] compactMarshallerMap;
- private final Map<Class, BytesMarshaller> marshallerMap = new LinkedHashMap<Class, BytesMarshaller>();
- private final BytesMarshaller[] compactMarshallerMap = new BytesMarshaller[256];
+ private void init() {
+ marshallerMap = new LinkedHashMap<Class<?>, BytesMarshaller<?>>();
+ compactMarshallerMap = new BytesMarshaller[256];
- // private final Map<Class, BytesMarshaller> marshallerTextMap = new LinkedHashMap<Class, BytesMarshaller>();
- {
- BytesMarshaller stringMarshaller = new StringMarshaller(16 * 1024);
+ BytesMarshaller<String> stringMarshaller = new StringMarshaller(16 * 1024);
addMarshaller(String.class, stringMarshaller);
- addMarshaller(CharSequence.class, stringMarshaller);
+ addMarshaller(CharSequence.class, (BytesMarshaller)stringMarshaller);
addMarshaller(Class.class, new ClassMarshaller(Thread.currentThread().getContextClassLoader()));
addMarshaller(Date.class, new DateMarshaller(10191));
- addMarshaller(Integer.class, new CompactEnumBytesMarshaller<Integer>(Integer.class, 10191, (byte) ('I' & 31)));
- addMarshaller(Long.class, new CompactEnumBytesMarshaller<Long>(Long.class, 10191, (byte) ('L' & 31)));
- addMarshaller(Double.class, new CompactEnumBytesMarshaller<Double>(Double.class, 10191, (byte) ('D' & 31)));
+ addMarshaller(Integer.class, new CompactEnumBytesMarshaller<Integer>(Integer.class, 10191, INT_CODE));
+ addMarshaller(Long.class, new CompactEnumBytesMarshaller<Long>(Long.class, 10191, LONG_CODE));
+ addMarshaller(Double.class, new CompactEnumBytesMarshaller<Double>(Double.class, 10191, DOUBLE_CODE));
+ addMarshaller(ByteBuffer.class, ByteBufferMarshaller.INSTANCE);
}
@NotNull
@SuppressWarnings("unchecked")
@Override
public <E> BytesMarshaller<E> acquireMarshaller(@NotNull Class<E> eClass, boolean create) {
+ if (marshallerMap == null) {
+ init();
+ }
+
BytesMarshaller em = marshallerMap.get(eClass);
- if (em == null)
- if (eClass.isEnum())
+ if (em == null) {
+ if (eClass.isEnum()) {
marshallerMap.put(eClass, em = new EnumBytesMarshaller(eClass, null));
- else if (BytesMarshallable.class.isAssignableFrom(eClass))
+
+ } else if (BytesMarshallable.class.isAssignableFrom(eClass)) {
marshallerMap.put(eClass, em = new BytesMarshallableMarshaller((Class) eClass));
- else if (Externalizable.class.isAssignableFrom(eClass))
+
+ } else if (Externalizable.class.isAssignableFrom(eClass)) {
marshallerMap.put(eClass, em = new ExternalizableMarshaller((Class) eClass));
- else {
+
+ } else if (Throwable.class.isAssignableFrom(eClass)) {
+ marshallerMap.put(eClass, em = NoMarshaller.INSTANCE);
+
+ } else {
try {
marshallerMap.put(eClass, em = new GenericEnumMarshaller<E>(eClass, 1000));
} catch (Exception e) {
marshallerMap.put(eClass, em = NoMarshaller.INSTANCE);
}
}
+ }
+
return em;
}
@Override
+ @SuppressWarnings("unchecked")
public <E> BytesMarshaller<E> getMarshaller(byte code) {
- return compactMarshallerMap[code & 0xFF];
+ if (marshallerMap == null) {
+ init();
+ }
+
+ return (BytesMarshaller<E>) compactMarshallerMap[code & 0xFF];
}
public <E> void addMarshaller(Class<E> eClass, BytesMarshaller<E> marshaller) {
+ if (marshallerMap == null) {
+ init();
+ }
+
marshallerMap.put(eClass, marshaller);
- if (marshaller instanceof CompactBytesMarshaller)
+ if (marshaller instanceof CompactBytesMarshaller) {
compactMarshallerMap[((CompactBytesMarshaller) marshaller).code()] = marshaller;
+ }
}
}