mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
more understandable code after review (IDEA-CR-28595)
This commit is contained in:
@@ -356,7 +356,7 @@ public class PersistentHashMapValueStorage {
|
||||
final int fileBufferLength = 256 * 1024;
|
||||
final int maxRecordHeader = 5 /* max length - variable int */ + 10 /* max long offset*/;
|
||||
final byte[] buffer = new byte[fileBufferLength + maxRecordHeader];
|
||||
byte[] recordBuffer = {};
|
||||
byte[] reusedAccumulatedChunksBuffer = {};
|
||||
|
||||
long lastReadOffset = mySize;
|
||||
long lastConsumedOffset = lastReadOffset;
|
||||
@@ -405,23 +405,23 @@ public class PersistentHashMapValueStorage {
|
||||
prevChunkAddress = readPrevChunkAddress(info.valueAddress);
|
||||
dataOffset = available - myBufferStreamWrapper.available();
|
||||
|
||||
byte[] b;
|
||||
byte[] accumulatedChunksBuffer;
|
||||
if (info.value != null) {
|
||||
int defragmentedChunkSize = info.value.length + chunkSize;
|
||||
if (prevChunkAddress == 0) {
|
||||
if (defragmentedChunkSize >= recordBuffer.length) recordBuffer = new byte[defragmentedChunkSize];
|
||||
b = recordBuffer;
|
||||
if (defragmentedChunkSize >= reusedAccumulatedChunksBuffer.length) reusedAccumulatedChunksBuffer = new byte[defragmentedChunkSize];
|
||||
accumulatedChunksBuffer = reusedAccumulatedChunksBuffer;
|
||||
} else {
|
||||
b = new byte[defragmentedChunkSize];
|
||||
accumulatedChunksBuffer = new byte[defragmentedChunkSize];
|
||||
retained += defragmentedChunkSize;
|
||||
}
|
||||
System.arraycopy(info.value, 0, b, chunkSize, info.value.length);
|
||||
System.arraycopy(info.value, 0, accumulatedChunksBuffer, chunkSize, info.value.length);
|
||||
} else {
|
||||
if (prevChunkAddress == 0) {
|
||||
if (chunkSize >= recordBuffer.length) recordBuffer = new byte[chunkSize];
|
||||
b = recordBuffer;
|
||||
if (chunkSize >= reusedAccumulatedChunksBuffer.length) reusedAccumulatedChunksBuffer = new byte[chunkSize];
|
||||
accumulatedChunksBuffer = reusedAccumulatedChunksBuffer;
|
||||
} else {
|
||||
b = new byte[chunkSize];
|
||||
accumulatedChunksBuffer = new byte[chunkSize];
|
||||
retained += chunkSize;
|
||||
}
|
||||
}
|
||||
@@ -430,11 +430,11 @@ public class PersistentHashMapValueStorage {
|
||||
Math.max((int)(info.valueAddress + dataOffset + chunkSize - lastReadOffset), 0));
|
||||
if (chunkSizeOutOfBuffer > 0) {
|
||||
if (allRecordsStart != 0) {
|
||||
myCompactionModeReader.get(allRecordsStart, b, chunkSize - chunkSizeOutOfBuffer, chunkSizeOutOfBuffer);
|
||||
myCompactionModeReader.get(allRecordsStart, accumulatedChunksBuffer, chunkSize - chunkSizeOutOfBuffer, chunkSizeOutOfBuffer);
|
||||
} else {
|
||||
int offsetInStuffFromPreviousRecord = Math.max((int)(info.valueAddress + dataOffset - lastReadOffset), 0);
|
||||
// stuffFromPreviousRecord starts from lastReadOffset
|
||||
System.arraycopy(stuffFromPreviousRecord, offsetInStuffFromPreviousRecord, b, chunkSize - chunkSizeOutOfBuffer, chunkSizeOutOfBuffer);
|
||||
System.arraycopy(stuffFromPreviousRecord, offsetInStuffFromPreviousRecord, accumulatedChunksBuffer, chunkSize - chunkSizeOutOfBuffer, chunkSizeOutOfBuffer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -442,9 +442,9 @@ public class PersistentHashMapValueStorage {
|
||||
allRecordsStart = allRecordsLength = 0;
|
||||
|
||||
lastConsumedOffset = info.valueAddress;
|
||||
checkPreconditions(b, chunkSize, 0);
|
||||
checkPreconditions(accumulatedChunksBuffer, chunkSize, 0);
|
||||
|
||||
System.arraycopy(buffer, recordStartInBuffer + dataOffset, b, 0, chunkSize - chunkSizeOutOfBuffer);
|
||||
System.arraycopy(buffer, recordStartInBuffer + dataOffset, accumulatedChunksBuffer, 0, chunkSize - chunkSizeOutOfBuffer);
|
||||
|
||||
++fragments;
|
||||
records.remove(info);
|
||||
@@ -455,24 +455,17 @@ public class PersistentHashMapValueStorage {
|
||||
}
|
||||
|
||||
if (prevChunkAddress == 0) {
|
||||
info.newValueAddress = storage.appendBytes(b, 0, chunkSize, info.newValueAddress);
|
||||
info.newValueAddress = storage.appendBytes(accumulatedChunksBuffer, 0, chunkSize, info.newValueAddress);
|
||||
++newFragments;
|
||||
} else {
|
||||
if (retained > SOFT_MAX_RETAINED_LIMIT && b.length > BLOCK_SIZE_TO_WRITE_WHEN_SOFT_MAX_RETAINED_LIMIT_IS_HIT ||
|
||||
if (retained > SOFT_MAX_RETAINED_LIMIT && accumulatedChunksBuffer.length > BLOCK_SIZE_TO_WRITE_WHEN_SOFT_MAX_RETAINED_LIMIT_IS_HIT ||
|
||||
retained > MAX_RETAINED_LIMIT_WHEN_COMPACTING) {
|
||||
// to avoid OOME we need to save 'b' accumulated from chunks
|
||||
// to preserve write order prev data is loaded in usual backward chunk reads
|
||||
ReadResult result = readBytes(prevChunkAddress);
|
||||
info.newValueAddress = storage.appendBytes(result.buffer, 0, result.buffer.length, info.newValueAddress);
|
||||
++newFragments;
|
||||
info.newValueAddress = storage.appendBytes(b, 0, chunkSize, info.newValueAddress);
|
||||
++newFragments;
|
||||
info.value = null;
|
||||
info.valueAddress = 0;
|
||||
retained -= b.length;
|
||||
// to avoid OOME we need to save bytes in accumulatedChunksBuffer
|
||||
newFragments += saveAccumulatedDataOnDiskPreservingWriteOrder(storage, info, prevChunkAddress, accumulatedChunksBuffer, chunkSize);
|
||||
retained -= accumulatedChunksBuffer.length;
|
||||
continue;
|
||||
} else {
|
||||
info.value = b;
|
||||
info.value = accumulatedChunksBuffer;
|
||||
}
|
||||
info.valueAddress = prevChunkAddress;
|
||||
records.add(info);
|
||||
@@ -497,6 +490,22 @@ public class PersistentHashMapValueStorage {
|
||||
return fragments | ((long)newFragments << 32);
|
||||
}
|
||||
|
||||
private int saveAccumulatedDataOnDiskPreservingWriteOrder(PersistentHashMapValueStorage storage,
|
||||
PersistentHashMap.CompactionRecordInfo info,
|
||||
long prevChunkAddress,
|
||||
byte[] accumulatedChunksData,
|
||||
int accumulatedChunkDataLength) throws IOException {
|
||||
ReadResult result = readBytes(prevChunkAddress);
|
||||
// to avoid possible OOME result.bytes and accumulatedChunksData are not combined in one chunk, instead they are
|
||||
// placed one after another, such near placement should be fine because of disk caching
|
||||
info.newValueAddress = storage.appendBytes(result.buffer, 0, result.buffer.length, info.newValueAddress);
|
||||
info.newValueAddress = storage.appendBytes(accumulatedChunksData, 0, accumulatedChunkDataLength, info.newValueAddress);
|
||||
|
||||
info.value = null;
|
||||
info.valueAddress = 0;
|
||||
return 2; // number of chunks produced = number of appendBytes called
|
||||
}
|
||||
|
||||
public static class ReadResult {
|
||||
public final byte[] buffer;
|
||||
public final int chunksCount;
|
||||
|
||||
Reference in New Issue
Block a user