mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
readBytes on removed record will produce empty result instead of assertion,
better diagnostics (EA-82826)
This commit is contained in:
+4
-5
@@ -103,7 +103,6 @@ public class CompactRecordsTable extends AbstractRecordsTable {
|
||||
private static final int CAPACITY_MASK = 0x7FFF0000;
|
||||
private static final int CAPACITY_SHIFT = 16;
|
||||
private static final int SPECIAL_POSITIVE_VALUE_FOR_SPECIAL_NEGATIVE_SIZE = 0xFFFF;
|
||||
private static final int SPECIAL_NEGATIVE_SIZE = -1;
|
||||
|
||||
@Override
|
||||
public int getSize(int record) {
|
||||
@@ -113,7 +112,7 @@ public class CompactRecordsTable extends AbstractRecordsTable {
|
||||
return myStorage.getInt(getOffset(-currentValue, SIZE_OFFSET_IN_INDIRECT_RECORD));
|
||||
}
|
||||
int i = currentValue & SIZE_MASK;
|
||||
if (i == SPECIAL_POSITIVE_VALUE_FOR_SPECIAL_NEGATIVE_SIZE) i = SPECIAL_NEGATIVE_SIZE;
|
||||
if (i == SPECIAL_POSITIVE_VALUE_FOR_SPECIAL_NEGATIVE_SIZE) i = SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD;
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -130,13 +129,13 @@ public class CompactRecordsTable extends AbstractRecordsTable {
|
||||
}
|
||||
|
||||
// size to fit in normal record [-1 .. 0xFFFF)
|
||||
if (size >= 0xFFFF || size < SPECIAL_NEGATIVE_SIZE || forceSplit) {
|
||||
if (size >= 0xFFFF || size < SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD || forceSplit) {
|
||||
// introduce indirect record able to hold larger size range
|
||||
extendSizeAndCapacityRecord(record, size, getCapacity(record));
|
||||
return;
|
||||
}
|
||||
|
||||
if (size == SPECIAL_NEGATIVE_SIZE) {
|
||||
if (size == SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD) {
|
||||
size = SPECIAL_POSITIVE_VALUE_FOR_SPECIAL_NEGATIVE_SIZE;
|
||||
}
|
||||
|
||||
@@ -232,7 +231,7 @@ public class CompactRecordsTable extends AbstractRecordsTable {
|
||||
@Override
|
||||
public boolean validId() {
|
||||
assert hasNextId();
|
||||
return getSize(nextId) != -1;
|
||||
return isSizeOfLiveRecord(getSize(nextId));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -52,6 +52,9 @@ public class CompactStorageTest extends StorageTestBase {
|
||||
int logicalRecordCount = countLiveLogicalRecords();
|
||||
assertEquals(recordCount / 2, logicalRecordCount);
|
||||
|
||||
int removedRecordId = recordsList.getQuick(0);
|
||||
assertEquals("No content for reading removed record",0, myStorage.readStream(removedRecordId).available());
|
||||
|
||||
Disposer.dispose(myStorage); // compact is triggered
|
||||
myStorage = createStorage(getFileName());
|
||||
assertEquals(myStorage.getLiveRecordsCount(), physicalRecordCount / 2);
|
||||
|
||||
@@ -52,6 +52,7 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
|
||||
private TIntArrayList myFreeRecordsList = null;
|
||||
private boolean myIsDirty = false;
|
||||
protected static final int SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD = -1;
|
||||
|
||||
public AbstractRecordsTable(final File storageFilePath, final PagePool pool) throws IOException {
|
||||
myStorage = new RandomAccessDataFile(storageFilePath, pool);
|
||||
@@ -93,7 +94,7 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
}
|
||||
else {
|
||||
final int result = myFreeRecordsList.remove(myFreeRecordsList.size() - 1);
|
||||
assert getSize(result) == -1;
|
||||
assert isSizeOfRemovedRecord(getSize(result));
|
||||
setSize(result, 0);
|
||||
return result;
|
||||
}
|
||||
@@ -127,7 +128,7 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
@Override
|
||||
public boolean validId() {
|
||||
assert hasNextId();
|
||||
return getSize(recordId) != -1;
|
||||
return isSizeOfLiveRecord(getSize(recordId));
|
||||
}
|
||||
};
|
||||
}
|
||||
@@ -147,7 +148,7 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
private TIntArrayList scanForFreeRecords() throws IOException {
|
||||
final TIntArrayList result = new TIntArrayList();
|
||||
for (int i = 1; i <= getRecordsCount(); i++) {
|
||||
if (getSize(i) == -1) {
|
||||
if (isSizeOfRemovedRecord(getSize(i))) {
|
||||
result.add(i);
|
||||
}
|
||||
}
|
||||
@@ -194,7 +195,7 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
markDirty();
|
||||
ensureFreeRecordsScanned();
|
||||
doCleanRecord(record);
|
||||
setSize(record, -1);
|
||||
setSize(record, SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD);
|
||||
myFreeRecordsList.add(record);
|
||||
}
|
||||
|
||||
@@ -248,4 +249,12 @@ public abstract class AbstractRecordsTable implements Disposable, Forceable {
|
||||
myStorage.putInt(HEADER_MAGIC_OFFSET, getSafelyClosedMagic());
|
||||
}
|
||||
}
|
||||
|
||||
protected static boolean isSizeOfRemovedRecord(int length) {
|
||||
return length == SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD;
|
||||
}
|
||||
|
||||
protected static boolean isSizeOfLiveRecord(int length) {
|
||||
return length != SPECIAL_NEGATIVE_SIZE_FOR_REMOVED_RECORD;
|
||||
}
|
||||
}
|
||||
@@ -255,8 +255,8 @@ public abstract class AbstractStorage implements Disposable, Forceable {
|
||||
protected byte[] readBytes(int record) throws IOException {
|
||||
synchronized (myLock) {
|
||||
final int length = myRecordsTable.getSize(record);
|
||||
if (length == 0) return ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
assert length > 0;
|
||||
if (length == 0 || AbstractRecordsTable.isSizeOfRemovedRecord(length)) return ArrayUtil.EMPTY_BYTE_ARRAY;
|
||||
assert length > 0:length;
|
||||
|
||||
final long address = myRecordsTable.getAddress(record);
|
||||
byte[] result = new byte[length];
|
||||
|
||||
Reference in New Issue
Block a user