mirror of
https://github.com/OpenHFT/Chronicle-Map.git
synced 2021-09-13 01:26:12 +00:00
Optimize SizedMarshallableDataAccess to avoid double data copy when writing values
This commit is contained in:
+25
-6
@@ -16,8 +16,7 @@
|
|||||||
|
|
||||||
package net.openhft.chronicle.hash.serialization.impl;
|
package net.openhft.chronicle.hash.serialization.impl;
|
||||||
|
|
||||||
import net.openhft.chronicle.bytes.Bytes;
|
import net.openhft.chronicle.bytes.*;
|
||||||
import net.openhft.chronicle.bytes.RandomDataInput;
|
|
||||||
import net.openhft.chronicle.hash.Data;
|
import net.openhft.chronicle.hash.Data;
|
||||||
import net.openhft.chronicle.hash.serialization.DataAccess;
|
import net.openhft.chronicle.hash.serialization.DataAccess;
|
||||||
import net.openhft.chronicle.hash.serialization.SizedReader;
|
import net.openhft.chronicle.hash.serialization.SizedReader;
|
||||||
@@ -36,8 +35,11 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
|||||||
private SizedReader<T> sizedReader;
|
private SizedReader<T> sizedReader;
|
||||||
private SizedWriter<? super T> sizedWriter;
|
private SizedWriter<? super T> sizedWriter;
|
||||||
|
|
||||||
/** Cache field */
|
// Cache fields
|
||||||
|
private transient boolean bytesInit;
|
||||||
private transient Bytes bytes;
|
private transient Bytes bytes;
|
||||||
|
private transient long size;
|
||||||
|
private transient VanillaBytes targetBytes;
|
||||||
|
|
||||||
/** State field */
|
/** State field */
|
||||||
private transient T instance;
|
private transient T instance;
|
||||||
@@ -60,10 +62,16 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
|||||||
|
|
||||||
private void initTransients() {
|
private void initTransients() {
|
||||||
bytes = Bytes.allocateElasticDirect(1);
|
bytes = Bytes.allocateElasticDirect(1);
|
||||||
|
targetBytes = VanillaBytes.vanillaBytes();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public RandomDataInput bytes() {
|
public RandomDataInput bytes() {
|
||||||
|
if (!bytesInit) {
|
||||||
|
bytes.clear();
|
||||||
|
sizedWriter.write(bytes, size, instance);
|
||||||
|
bytesInit = true;
|
||||||
|
}
|
||||||
return bytes.bytesStore();
|
return bytes.bytesStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +82,18 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public long size() {
|
public long size() {
|
||||||
return bytes.readRemaining();
|
return size;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void writeTo(RandomDataOutput target, long targetOffset) {
|
||||||
|
if (bytesInit || !(target instanceof BytesStore)) {
|
||||||
|
target.write(targetOffset, bytes(), offset(), size);
|
||||||
|
} else {
|
||||||
|
targetBytes.bytesStore((BytesStore) target, targetOffset, size);
|
||||||
|
sizedWriter.write(targetBytes, size, instance);
|
||||||
|
targetBytes.bytesStore(NoBytesStore.NO_BYTES_STORE, 0, 0);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -109,8 +128,8 @@ public class SizedMarshallableDataAccess<T> extends InstanceCreatingMarshaller<T
|
|||||||
@Override
|
@Override
|
||||||
public Data<T> getData(@NotNull T instance) {
|
public Data<T> getData(@NotNull T instance) {
|
||||||
this.instance = instance;
|
this.instance = instance;
|
||||||
bytes.clear();
|
this.size = sizedWriter.size(instance);
|
||||||
sizedWriter.write(bytes, sizedWriter.size(instance), instance);
|
bytesInit = false;
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -93,11 +93,13 @@ public abstract class MapEntryStages<K, V> extends HashEntryStages<K>
|
|||||||
// the off-heap bytes. This condition avoids in-place data copy.
|
// the off-heap bytes. This condition avoids in-place data copy.
|
||||||
// TODO would be nice to reduce scope of this check, i. e. check only when it could be
|
// TODO would be nice to reduce scope of this check, i. e. check only when it could be
|
||||||
// true, and avoid when it surely false (fresh value put, relocating put etc.)
|
// true, and avoid when it surely false (fresh value put, relocating put etc.)
|
||||||
RandomDataInput valueBytes = value.bytes();
|
// TODO this optimization is now disabled, because it calls value.bytes() that forces double
|
||||||
if (valueBytes instanceof NativeBytesStore &&
|
// data copy, if sizedReader/Writer configured for the value.
|
||||||
valueBytes.address(value.offset()) == s.segmentBS.address(valueOffset)) {
|
// RandomDataInput valueBytes = value.bytes();
|
||||||
return;
|
// if (valueBytes instanceof NativeBytesStore &&
|
||||||
}
|
// valueBytes.address(value.offset()) == s.segmentBS.address(valueOffset)) {
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
value.writeTo(s.segmentBS, valueOffset);
|
value.writeTo(s.segmentBS, valueOffset);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user