diff options
Diffstat (limited to 'lang/src/main/java/net/openhft/lang/io/serialization/impl')
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; + } } } |