Merge remote-tracking branch 'origin/master'

This commit is contained in:
Rob Austin
2014-12-16 11:08:59 +00:00
6 changed files with 66 additions and 17 deletions
@@ -33,7 +33,16 @@ public final class CharSequenceReader<S extends CharSequence>
implements BytesReader<S>, StatefulCopyable<CharSequenceReader<S>> {
private static final long serialVersionUID = 0L;
private enum NoInterning implements CharSequenceInterner<String> {
private enum NoInterningIdentity implements CharSequenceInterner<CharSequence> {
INSTANCE;
@Override
public CharSequence intern(CharSequence cs) {
return cs;
}
}
private enum NoInterningToString implements CharSequenceInterner<String> {
INSTANCE;
@Override
public String intern(CharSequence cs) {
@@ -41,10 +50,17 @@ public final class CharSequenceReader<S extends CharSequence>
}
}
private static final CharSequenceReader<String> DEFAULT_READER =
new CharSequenceReader<String>(NoInterning.INSTANCE, NoInterning.INSTANCE);
private static final CharSequenceReader<String> STRING_READER =
new CharSequenceReader<String>(NoInterningToString.INSTANCE, NoInterningToString.INSTANCE);
public static CharSequenceReader<String> of() {
private static final CharSequenceReader DEFAULT_READER =
new CharSequenceReader(NoInterningIdentity.INSTANCE, NoInterningIdentity.INSTANCE);
public static CharSequenceReader of() {
return STRING_READER;
}
public static CharSequenceReader<String> ofStringBuilder() {
return DEFAULT_READER;
}
@@ -111,7 +127,9 @@ public final class CharSequenceReader<S extends CharSequence>
}
private Object readResolve() throws ObjectStreamException {
if (interner == NoInterning.INSTANCE)
if (interner == NoInterningToString.INSTANCE)
return STRING_READER;
if (interner == NoInterningIdentity.INSTANCE)
return DEFAULT_READER;
return this;
}
@@ -104,6 +104,8 @@ public final class ChronicleMapBuilder<K, V> implements Cloneable,
LoggerFactory.getLogger(ChronicleMapBuilder.class.getName());
public static final long DEFAULT_STATELESS_CLIENT_TIMEOUT = TimeUnit.SECONDS.toMillis(10);
private static final StringBuilder EMTRY_STRING_BUILDER = new StringBuilder();
SerializationBuilder<K> keyBuilder;
SerializationBuilder<V> valueBuilder;
@@ -148,6 +150,8 @@ public final class ChronicleMapBuilder<K, V> implements Cloneable,
if (CharSequence.class == valueClass)
defaultValue = (V) "";
if (StringBuilder.class == valueClass)
defaultValue = (V) EMTRY_STRING_BUILDER;
}
/**
@@ -130,6 +130,9 @@ final class SerializationBuilder<E> implements Cloneable, Serializable {
} else if (eClass == CharSequence.class || eClass == String.class) {
reader((BytesReader<E>) CharSequenceReader.of());
writer((BytesWriter<E>) CharSequenceWriter.instance());
} else if (eClass == StringBuilder.class) {
reader((BytesReader<E>) CharSequenceReader.ofStringBuilder());
writer((BytesWriter<E>) CharSequenceWriter.instance());
} else if (eClass == Void.class) {
sizeMarshaller(VoidMarshaller.INSTANCE);
reader((BytesReader<E>) VoidMarshaller.INSTANCE);
@@ -652,7 +652,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
@Override
public V newValueInstance() {
if (vClass.equals(CharSequence.class) || vClass.equals(StringBuilder.class)) {
if (vClass == CharSequence.class || vClass == StringBuilder.class) {
return (V) new StringBuilder();
}
@@ -2818,6 +2818,14 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
@Override
public void close() {
// TODO optimize -- keep replication bytes offset in SegmentState to jump directly
long pos = segmentState.pos;
long offset = segment.offsetFromPos(pos);
MultiStoreBytes entry = segment.reuse(segmentState.tmpBytes, offset);
long keySize = map.keySizeMarshaller.readSize(entry);
entry.skip(keySize);
segment.manageReplicationBytes(entry, true, false);
map.onPut(segment, pos);
segmentState.close();
segment.writeUnlock();
}
@@ -2849,9 +2857,25 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
@Override
public void close() {
if (putOnClose) {
segment.putWithoutLock(copies, segmentState,
metaKeyInterop, keyInterop, key(), keySize, map.keyIdentity(),
map, value(), map.valueIdentity(), segmentHash, true, map, true);
// TODO optimize -- keep keySize, valueSizePos, entryEndAddr, etc. inside
// segmentState
long pos = segmentState.pos;
long offset = segment.offsetFromPos(pos);
MultiStoreBytes entry = segment.reuse(segmentState.tmpBytes, offset);
long keySize = map.keySizeMarshaller.readSize(entry);
entry.skip(keySize);
segment.manageReplicationBytes(entry, true, false);
long valueSizePos = entry.position();
long valueSize = map.readValueSize(entry);
long entryEndAddr = entry.positionAddr() + valueSize;
VI valueInterop = map.valueInteropProvider.get(copies, map.originalValueInterop);
V value = value();
MVI metaValueInterop = map.metaValueInteropProvider
.get(copies, map.originalMetaValueInterop, valueInterop, value);
long newValueSize = metaValueInterop.size(valueInterop, value);
segment.putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState,
metaValueInterop, valueInterop, value, newValueSize, segment.hashLookup());
map.onPut(segment, segmentState.pos);
}
putOnClose = true;
segmentState.close();