Merge remote-tracking branch 'origin/master'

This commit is contained in:
Rob Austin
2015-01-03 18:44:35 +00:00
6 changed files with 153 additions and 94 deletions
@@ -238,15 +238,18 @@ class Int24Int24MultiMap implements MultiMap {
}
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
public void replacePrevPos(SearchState searchState, long newValue,
boolean oldValueInPositions) {
checkValueForPut(newValue);
long prevPos = searchState.searchPos;
if (!searchState.putAfterFailedSearch)
prevPos = stepBack(prevPos);
long oldEntry = bytes.readInt48(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
if (oldValueInPositions) {
long oldEntry = bytes.readInt48(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
}
positions.set(newValue);
bytes.writeInt48(prevPos, entry(searchState.searchHash, newValue));
}
@@ -239,15 +239,18 @@ class IntIntMultiMap implements MultiMap {
}
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
public void replacePrevPos(SearchState searchState, long newValue,
boolean oldValueInPositions) {
checkValueForPut(newValue);
long prevPos = searchState.searchPos;
if (!searchState.putAfterFailedSearch)
prevPos = stepBack(prevPos);
long oldEntry = bytes.readLong(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
if (oldValueInPositions) {
long oldEntry = bytes.readLong(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
}
positions.set(newValue);
bytes.writeLong(prevPos, entry(searchState.searchHash, newValue));
}
@@ -65,7 +65,7 @@ interface MultiMap {
void removePrevPos(SearchState searchState);
void replacePrevPos(SearchState searchState, long newValue);
void replacePrevPos(SearchState searchState, long newValue, boolean oldValueInPositions);
void putAfterFailedSearch(SearchState searchState, long value);
@@ -749,7 +749,8 @@ final class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? supe
} else {
throw defaultValueOrPrepareBytesShouldBeSpecified();
}
putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState,
putValue(pos, offset, entry, valueSizePos, entryEndAddr, isDeleted,
segmentState,
metaElemWriter, elemWriter, elem, metaElemWriter.size(elemWriter, elem),
hashLookup, sizeOfEverythingBeforeValue);
pos = segmentState.pos;
@@ -771,7 +772,7 @@ final class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? supe
V valueInstance = toValue.toInstance(copies, v, valueSize);
eventListener.onPut(keyInstance, valueInstance, null);
}
entryCreated(lock);
return v;
} else {
segmentState.pos = pos; // for WriteLocked.close()
@@ -785,11 +786,7 @@ final class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? supe
RV result = createEntryOnAcquire(copies, segmentState,
metaKeyInterop, keyInterop, key, keySize, toKey,
readValue, usingValue, toValue, entry);
// notify the context that the entry was created
if (lock instanceof WriteLocked)
((WriteLocked) lock).created(false);
entryCreated(lock);
return result;
}
@@ -1299,13 +1296,6 @@ final class ReplicatedChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? supe
return new TimestampTrackingEntry(key, value, timestamp);
}
@Override
boolean isDeleted(long pos) {
bytes.position(offsetFromPos(pos) + metaDataBytes);
long keySize = keySizeMarshaller.readSize(bytes);
return bytes.readBoolean(bytes.position() + keySize + ADDITIONAL_ENTRY_BYTES - 1L);
}
}
@Override
@@ -236,15 +236,18 @@ class ShortShortMultiMap implements MultiMap {
}
@Override
public void replacePrevPos(SearchState searchState, long newValue) {
public void replacePrevPos(SearchState searchState, long newValue,
boolean oldValueInPositions) {
checkValueForPut(newValue);
long prevPos = searchState.searchPos;
if (!searchState.putAfterFailedSearch)
prevPos = stepBack(prevPos);
int oldEntry = bytes.readInt(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
if (oldValueInPositions) {
int oldEntry = bytes.readInt(prevPos);
long oldValue = value(oldEntry);
checkValueForRemove(oldValue);
positions.clear(oldValue);
}
positions.set(newValue);
bytes.writeInt(prevPos, entry(searchState.searchHash, newValue));
}
@@ -779,17 +779,11 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
checkReallyUsingValue(usingValue, mustReuseValue, v);
lock.copies = copies;
lock.metaKeyInterop = metaKeyInterop;
lock.keyInterop = keyInterop;
lock.keySize = keySize;
lock.segmentHash = segmentHash;
lock.initKey(copies, metaKeyInterop, keyInterop, keySize, segmentHash, key);
if (!nativeValueClass && lockType == LockType.WRITE_LOCK && v == null)
v = usingValue;
lock.value(v);
lock.key(key);
return (T) lock;
}
@@ -1373,24 +1367,21 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>>
ReadLocked<K, KI, MKI, V, VI, MVI> readLocked(VanillaChronicleMap.Segment segment) {
readLocked.segment = segment;
readLocked.map = segment.map();
readLocked.initSegment(segment);
return readLocked;
}
<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>>
WriteLocked<K, KI, MKI, V, VI, MVI> nativeWriteLocked(VanillaChronicleMap.Segment segment) {
nativeWriteLocked.segment = segment;
nativeWriteLocked.map = segment.map();
nativeWriteLocked.initSegment(segment);
return nativeWriteLocked;
}
<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>>
WriteLocked<K, KI, MKI, V, VI, MVI> heapWriteLocked(VanillaChronicleMap.Segment segment) {
heapWriteLocked.segment = segment;
heapWriteLocked.map = segment.map();
heapWriteLocked.initSegment(segment);
return heapWriteLocked;
}
}
@@ -1720,12 +1711,14 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
RV result = createEntryOnAcquire(copies, segmentState,
metaKeyInterop, keyInterop, key, keySize, toKey,
readValue, usingValue, toValue, entry);
entryCreated(lock);
return result;
}
final void entryCreated(MutableLockedEntry lock) {
// notify the context that the entry was created
if (lock instanceof WriteLocked)
((WriteLocked) lock).created(true);
return result;
}
final <KB, KBI, MKBI extends MetaBytesInterop<KB, ? super KBI>, RV>
@@ -1911,7 +1904,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
}
// putValue may relocate entry and change offset
putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState,
putValue(pos, offset, entry, valueSizePos, entryEndAddr, entryIsDeleted, segmentState,
metaValueInterop, valueInterop, value, valueSize, searchedHashLookup,
sizeOfEverythingBeforeValue);
@@ -2288,7 +2281,8 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
MVBI metaValueInterop = getNewValueInterops.getMetaValueInterop(
copies, valueInterop, newValue);
long newValueSize = metaValueInterop.size(valueInterop, newValue);
putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState,
boolean entryIsDeleted = false; // couldn't replace deleted entry
putValue(pos, offset, entry, valueSizePos, entryEndAddr, entryIsDeleted, segmentState,
metaValueInterop, valueInterop, newValue, newValueSize, searchedHashLookup,
sizeOfEverythingBeforeValue);
@@ -2321,6 +2315,7 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
*/
final <E, EW> long putValue(
long pos, long offset, MultiStoreBytes entry, long valueSizePos, long entryEndAddr,
boolean entryIsDeleted,
SegmentState segmentState,
MetaBytesWriter<E, ? super EW> metaElemWriter, EW elemWriter, E newElem,
long newElemSize,
@@ -2351,7 +2346,8 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
long newPos = alloc(allocatedChunks);
// putValue() is called from put() and replace()
// after successful search by key
searchedHashLookup.replacePrevPos(segmentState.searchState, newPos);
searchedHashLookup.replacePrevPos(segmentState.searchState, newPos,
!entryIsDeleted);
long newOffset = offsetFromPos(newPos);
reuse(entry, newOffset);
// Moving metadata, key size and key.
@@ -2416,10 +2412,6 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
return new WriteThroughEntry(key, value);
}
boolean isDeleted(long pos) {
return false;
}
/**
* Check there is no garbage in freeList.
*/
@@ -2669,13 +2661,13 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>> implements Context<K, V> {
final SegmentState segmentState;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment;
ThreadLocalCopies copies;
MKI metaKeyInterop;
KI keyInterop;
long keySize;
long segmentHash;
private VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map;
private VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment;
private ThreadLocalCopies copies;
private MKI metaKeyInterop;
private KI keyInterop;
private long keySize;
private long segmentHash;
private K key;
private V value;
@@ -2684,22 +2676,72 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
this.segmentState = segmentState;
}
public final K key() {
return key;
final void initSegment(VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment) {
this.map = segment.map();
this.segment = segment;
init();
}
final void key(K key) {
final void initKey(ThreadLocalCopies copies, MKI metaKeyInterop, KI keyInterop,
long keySize, long segmentHash, K key) {
this.copies = copies;
this.metaKeyInterop = metaKeyInterop;
this.keyInterop = keyInterop;
this.keySize = keySize;
this.segmentHash = segmentHash;
this.key = key;
init();
}
void init() {
// nothing
}
final VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map() {
return map;
}
final VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment() {
return segment;
}
final ThreadLocalCopies copies() {
return copies;
}
final MKI metaKeyInterop() {
return metaKeyInterop;
}
final KI keyInterop() {
return keyInterop;
}
final long keySize() {
return keySize;
}
final long segmentHash() {
return segmentHash;
}
public final K key() {
return key;
}
public final V value() {
return value;
}
void value(V value) {
final void value(V value) {
this.value = value;
}
@Override
public void close() {
segmentState.close();
segment().readUnlock();
}
}
private static class ReadLocked<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
@@ -2707,17 +2749,10 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
extends MutableLockedEntry<K, KI, MKI, V, VI, MVI>
implements ReadContext<K, V> {
ReadLocked(SegmentState segmentState) {
super(segmentState);
}
@Override
public void close() {
segmentState.close();
segment.readUnlock();
}
/**
* @return if the value is not null
*/
@@ -2731,12 +2766,20 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
extends MutableLockedEntry<K, KI, MKI, V, VI, MVI>
implements WriteContext<K, V> {
private boolean created = false;
private boolean created;
boolean removed;
WriteLocked(SegmentState segmentState) {
super(segmentState);
}
@Override
void init() {
super.init();
created = false;
removed = false;
}
/**
* @return if the entry was created
*/
@@ -2757,32 +2800,36 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
super(segmentState);
}
@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();
if (!removed) {
// TODO optimize -- keep replication bytes offset in SegmentState to jump directly
long pos = segmentState.pos;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment = segment();
VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map = map();
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);
}
super.close();
}
@Override
public void dontPutOnClose() {
throw new IllegalStateException(
"This method is not supported for native value classes");
"dontPutOnClose() method is not supported for native value classes");
}
@Override
public void removeEntry() {
segment.removeWithoutLock(copies, segmentState,
metaKeyInterop, keyInterop, key(), keySize, map.keyIdentity(),
map, null, map.valueIdentity(), segmentHash, map, true);
removed = true;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map = map();
segment().removeWithoutLock(copies(), segmentState,
metaKeyInterop(), keyInterop(), key(), keySize(), map.keyIdentity(),
map, null, map.valueIdentity(), segmentHash(), map, true);
}
}
@@ -2790,18 +2837,28 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
V, VI, MVI extends MetaBytesInterop<V, ? super VI>>
extends WriteLocked<K, KI, MKI, V, VI, MVI> {
private boolean putOnClose = true;
private boolean putOnClose;
HeapWriteLocked(SegmentState segmentState) {
super(segmentState);
}
@Override
void init() {
super.init();
putOnClose = true;
}
@Override
public void close() {
VanillaChronicleMap<K, KI, MKI, V, VI, MVI>.Segment segment = segment();
if (putOnClose) {
assert !removed;
// TODO optimize -- keep keySize, valueSizePos, entryEndAddr, etc. inside
// segmentState
long pos = segmentState.pos;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map = map();
ThreadLocalCopies copies = copies();
long offset = segment.offsetFromPos(pos);
MultiStoreBytes entry = segment.reuse(segmentState.tmpBytes, offset);
long keySize = map.keySizeMarshaller.readSize(entry);
@@ -2817,28 +2874,31 @@ class VanillaChronicleMap<K, KI, MKI extends MetaBytesInterop<K, ? super KI>,
MVI metaValueInterop = map.metaValueInteropProvider
.get(copies, map.originalMetaValueInterop, valueInterop, value);
long newValueSize = metaValueInterop.size(valueInterop, value);
segment.putValue(pos, offset, entry, valueSizePos, entryEndAddr, segmentState,
segment.putValue(pos, offset, entry, valueSizePos, entryEndAddr, removed,
segmentState,
metaValueInterop, valueInterop, value, newValueSize, segment.hashLookup(),
sizeOfEverythingBeforeValue);
map.onPut(segment, segmentState.pos);
}
putOnClose = true;
segmentState.close();
segment.writeUnlock();
super.close();
}
@Override
public void dontPutOnClose() {
if (removed)
throw new IllegalStateException("Shouldn't call this method after removeEntry()");
putOnClose = false;
}
@Override
public void removeEntry() {
putOnClose = false;
segment.removeWithoutLock(copies, segmentState,
metaKeyInterop, keyInterop, key(), keySize, map.keyIdentity(),
map, null, map.valueIdentity(), segmentHash, map, true);
removed = true;
VanillaChronicleMap<K, KI, MKI, V, VI, MVI> map = map();
segment().removeWithoutLock(copies(), segmentState,
metaKeyInterop(), keyInterop(), key(), keySize(), map.keyIdentity(),
map, null, map.valueIdentity(), segmentHash(), map, true);
}
}