HCOLL-201 implemented LongValue special case marshallers

This commit is contained in:
leventov
2014-11-12 15:11:55 +03:00
parent 86c9ce49e1
commit 356b4e7eef
6 changed files with 116 additions and 34 deletions
@@ -23,12 +23,24 @@ import net.openhft.chronicle.hash.serialization.BytesReader;
import net.openhft.chronicle.hash.serialization.Hasher;
import net.openhft.chronicle.hash.serialization.SizeMarshaller;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.model.DataValueClasses;
import net.openhft.lang.values.LongValue;
public enum LongValueMarshaller
public class LongValueKeyMarshaller
implements BytesInterop<LongValue>, BytesReader<LongValue>, SizeMarshaller {
INSTANCE;
private static final long serialVersionUID = 0L;
public static final LongValueKeyMarshaller INSTANCE = new LongValueKeyMarshaller();
private static final Class<LongValue> heapLongValueClass =
DataValueClasses.heapClassFor(LongValue.class);
LongValueKeyMarshaller() {}
private Object readResolve() {
return INSTANCE;
}
@Override
public long size(LongValue e) {
@@ -67,11 +79,19 @@ public enum LongValueMarshaller
@Override
public LongValue read(Bytes bytes, long size) {
return read(bytes, size, DataValueClasses.newInstance(LongValue.class));
return read(bytes, size, null);
}
@Override
public LongValue read(Bytes bytes, long size, LongValue toReuse) {
if (toReuse == null ||
(toReuse instanceof Byteable && ((Byteable) toReuse).bytes() == null)) {
try {
toReuse = heapLongValueClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
toReuse.setValue(bytes.readLong());
return toReuse;
}
@@ -0,0 +1,52 @@
/*
* Copyright 2014 Higher Frequency Trading http://www.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
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.openhft.chronicle.hash.serialization.internal;
import net.openhft.lang.io.Bytes;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.model.DataValueClasses;
import net.openhft.lang.values.LongValue;
public final class LongValueValueMarshaller extends LongValueKeyMarshaller {
private static final long serialVersionUID = 0L;
public static final LongValueValueMarshaller INSTANCE = new LongValueValueMarshaller();
private static final Class<LongValue> directLongValueClass =
DataValueClasses.directClassFor(LongValue.class);
private LongValueValueMarshaller() {}
private Object readResolve() {
return INSTANCE;
}
@Override
public LongValue read(Bytes bytes, long size, LongValue toReuse) {
if (!(toReuse instanceof Byteable)) {
try {
toReuse = directLongValueClass.newInstance();
} catch (InstantiationException | IllegalAccessException e) {
throw new AssertionError(e);
}
}
Byteable value = (Byteable) toReuse;
ByteableMarshaller.setBytesAndOffset(value, bytes);
bytes.skip(8L);
return toReuse;
}
}
@@ -39,6 +39,7 @@ import net.openhft.lang.io.serialization.impl.VanillaBytesMarshallerFactory;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.threadlocal.Provider;
import net.openhft.lang.threadlocal.ThreadLocalCopies;
import net.openhft.lang.values.LongValue;
import org.jetbrains.annotations.NotNull;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -143,6 +144,8 @@ public abstract class AbstractChronicleMapBuilder<K, V,
AbstractChronicleMapBuilder(Class<K> keyClass, Class<V> valueClass) {
keyBuilder = new SerializationBuilder<K>(keyClass, SerializationBuilder.Role.KEY);
valueBuilder = new SerializationBuilder<V>(valueClass, SerializationBuilder.Role.VALUE);
if (valueClass == LongValue.class)
prepareValueBytesOnAcquire(new ZeroOutValueBytes<K, V>(valueSize()));
}
protected static boolean offHeapReference(Class valueClass) {
@@ -721,6 +724,8 @@ public abstract class AbstractChronicleMapBuilder<K, V,
}
PrepareValueBytesAsWriter<K> prepareValueBytesAsWriter() {
if (prepareValueBytes == null)
return null;
return new PrepareValueBytesAsWriter<>(prepareValueBytes, valueSize());
}
@@ -29,6 +29,7 @@ import net.openhft.lang.io.serialization.ObjectFactory;
import net.openhft.lang.io.serialization.ObjectSerializer;
import net.openhft.lang.io.serialization.impl.*;
import net.openhft.lang.model.Byteable;
import net.openhft.lang.values.LongValue;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
@@ -39,6 +40,7 @@ import java.lang.reflect.Modifier;
import static net.openhft.chronicle.map.Objects.hash;
import static net.openhft.chronicle.hash.serialization.SizeMarshallers.stopBit;
import static net.openhft.chronicle.map.SerializationBuilder.Role.KEY;
final class SerializationBuilder<E> implements Cloneable {
@@ -83,34 +85,40 @@ final class SerializationBuilder<E> implements Cloneable {
if (concreteClass(eClass) && Byteable.class.isAssignableFrom(eClass)) {
ByteableMarshaller byteableMarshaller = ByteableMarshaller.of((Class) eClass);
sizeMarshaller(byteableMarshaller)
.reader(byteableMarshaller)
.interop(byteableMarshaller);
sizeMarshaller(byteableMarshaller);
reader(byteableMarshaller);
interop(byteableMarshaller);
} else if (eClass == CharSequence.class || eClass == String.class) {
reader((BytesReader<E>) CharSequenceReader.of());
writer((BytesWriter<E>) CharSequenceWriter.instance());
} else if (eClass == Void.class) {
sizeMarshaller(VoidMarshaller.INSTANCE)
.reader((BytesReader<E>) VoidMarshaller.INSTANCE)
.interop((BytesInterop<E>) VoidMarshaller.INSTANCE);
sizeMarshaller(VoidMarshaller.INSTANCE);
reader((BytesReader<E>) VoidMarshaller.INSTANCE);
interop((BytesInterop<E>) VoidMarshaller.INSTANCE);
} else if (eClass == Long.class) {
sizeMarshaller(LongMarshaller.INSTANCE)
.reader((BytesReader<E>) LongMarshaller.INSTANCE)
.interop((BytesInterop<E>) LongMarshaller.INSTANCE);
sizeMarshaller(LongMarshaller.INSTANCE);
reader((BytesReader<E>) LongMarshaller.INSTANCE);
interop((BytesInterop<E>) LongMarshaller.INSTANCE);
} else if (eClass == Double.class) {
sizeMarshaller(DoubleMarshaller.INSTANCE)
.reader((BytesReader<E>) DoubleMarshaller.INSTANCE)
.interop((BytesInterop<E>) DoubleMarshaller.INSTANCE);
sizeMarshaller(DoubleMarshaller.INSTANCE);
reader((BytesReader<E>) DoubleMarshaller.INSTANCE);
interop((BytesInterop<E>) DoubleMarshaller.INSTANCE);
} else if (eClass == Integer.class) {
sizeMarshaller(IntegerMarshaller.INSTANCE)
.reader((BytesReader<E>) IntegerMarshaller.INSTANCE)
.interop((BytesInterop<E>) IntegerMarshaller.INSTANCE);
sizeMarshaller(IntegerMarshaller.INSTANCE);
reader((BytesReader<E>) IntegerMarshaller.INSTANCE);
interop((BytesInterop<E>) IntegerMarshaller.INSTANCE);
} else if (eClass == byte[].class) {
reader((BytesReader<E>) ByteArrayMarshaller.INSTANCE);
interop((BytesInterop<E>) ByteArrayMarshaller.INSTANCE);
} else if (eClass == char[].class) {
reader((BytesReader<E>) CharArrayMarshaller.INSTANCE);
interop((BytesInterop<E>) CharArrayMarshaller.INSTANCE);
} else if (eClass == LongValue.class) {
LongValueKeyMarshaller marshaller = role == KEY ?
LongValueKeyMarshaller.INSTANCE : LongValueValueMarshaller.INSTANCE;
sizeMarshaller(marshaller);
reader((BytesReader<E>) marshaller);
interop((BytesInterop<E>) marshaller);
} else if (concreteClass(eClass)) {
BytesMarshaller<E> marshaller = chooseMarshaller(eClass, eClass);
if (marshaller != null)
@@ -881,8 +881,14 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, KI>,
offset = putEntry(metaKeyInterop, keyInterop, key, keySize,
metaValueWriter, valueWriter, defaultValue);
} else {
offset = putEntry(metaKeyInterop, keyInterop, key, keySize,
prepareValueBytesAsWriter, null, key);
if (prepareValueBytesAsWriter != null) {
offset = putEntry(metaKeyInterop, keyInterop, key, keySize,
prepareValueBytesAsWriter, null, key);
} else {
throw new IllegalStateException("To call acquire*() methods, " +
"you should specify either default value, default value provider " +
"or prepareBytes strategy during map building");
}
}
return onKeyAbsentOnAcquire(copies, key, keySize, usingValue, offset);
}