use previously calculated data from PHM if no read right now is performed: calculate the value instead of wait for IO to complete

This commit is contained in:
Maxim.Mossienko
2014-05-16 22:46:00 +02:00
parent 53e5113b5a
commit 4e540d44c8
2 changed files with 23 additions and 8 deletions
@@ -311,15 +311,20 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
Map<Key, Value> data = null;
boolean havePersistentData = false;
Integer hashId = null;
boolean skippedReadingPersistentDataButMayHaveIt = false;
if (myContents != null && weProcessPhysicalContent && content != null) {
try {
hashId = getHashOfContent((FileContent)content);
if (doReadSavedPersistentData) {
ByteSequence bytes = myContents.get(hashId);
if (bytes != null) {
data = deserializeSavedPersistentData(bytes);
havePersistentData = true;
if (!myContents.isBusyReading()) {
ByteSequence bytes = myContents.get(hashId);
if (bytes != null) {
data = deserializeSavedPersistentData(bytes);
havePersistentData = true;
}
} else {
skippedReadingPersistentDataButMayHaveIt = true;
}
} else {
havePersistentData = myContents.containsMapping(hashId);
@@ -333,7 +338,7 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
if (data == null) data = content != null ? myIndexer.map(content) : Collections.<Key, Value>emptyMap();
if (hashId != null && !havePersistentData) {
savePersistentData(data, hashId);
savePersistentData(data, hashId, skippedReadingPersistentDataButMayHaveIt);
}
ProgressManager.checkCanceled();
@@ -448,8 +453,9 @@ public class MapReduceIndex<Key, Value, Input> implements UpdatableIndex<Key,Val
private static final ThreadLocalCachedByteArray ourSpareByteArray = new ThreadLocalCachedByteArray();
private void savePersistentData(Map<Key, Value> data, int id) {
private void savePersistentData(Map<Key, Value> data, int id, boolean delayedReading) {
try {
if (delayedReading && myContents.containsMapping(id)) return;
BufferExposingByteArrayOutputStream out = new BufferExposingByteArrayOutputStream(ourSpareByteArray.getBuffer(4 * data.size()));
DataOutputStream stream = new DataOutputStream(out);
int size = data.size();
@@ -81,6 +81,7 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
private int myLargeIndexWatermarkId; // starting with this id we store offset in adjacent file in long format
private boolean myIntAddressForNewRecord;
private static final boolean doHardConsistencyChecks = true;
private volatile boolean myBusyReading;
private static class AppendStream extends DataOutputStream {
private AppendStream() {
@@ -445,10 +446,19 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
@Override
public final Value get(Key key) throws IOException {
synchronized (myEnumerator) {
return doGet(key);
myBusyReading = true;
try {
return doGet(key);
} finally {
myBusyReading = false;
}
}
}
public boolean isBusyReading() {
return myBusyReading;
}
@Nullable
protected Value doGet(Key key) throws IOException {
final long valueOffset;
@@ -523,7 +533,6 @@ public class PersistentHashMap<Key, Value> extends PersistentEnumeratorDelegate<
try {
myAppendCache.remove(key);
if (myDirectlyStoreLongFileOffsetMode) {
if (myIntMapping) return true;
return ((PersistentBTreeEnumerator<Key>)myEnumerator).getNonnegativeValue(key) != NULL_ADDR;
} else {
final int id = tryEnumerate(key);