Skip to content

Commit ea3f294

Browse files
Exclude index records from record compression sanity checks
Summary: Preallocated index records have different circumstances that violate the compression sanity check logic. Let's not try, it makes valid files look corrupt. Added more index record debug info. Reviewed By: finik Differential Revision: D77476404 fbshipit-source-id: faa8a4e818bac3a6a1d79734b76a120a2f71170d
1 parent d094254 commit ea3f294

1 file changed

Lines changed: 42 additions & 7 deletions

File tree

vrs/FileFormat.cpp

Lines changed: 42 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@
3333

3434
#include "ErrorCode.h"
3535
#include "IndexRecord.h"
36+
#include "ProgressLogger.h"
3637

3738
using namespace std;
3839
using namespace std::chrono;
@@ -200,13 +201,15 @@ bool RecordHeader::isSanityCheckOk() const {
200201
}
201202
uint32_t uncompressedPayload = uncompressedSize.get(); // doesn't include header already
202203
if (uncompressedPayload > 0) {
203-
uint32_t compressedPayload = recordSize.get() - sizeof(RecordHeader);
204-
// we did not always check that compression actually helped, and smaller sizes do worse
205-
uint32_t maxIncrease = (uncompressedPayload < 200)
206-
? max<size_t>(50, uncompressedPayload / 2) // 50 bytes or 50%
207-
: max<size_t>(100, uncompressedPayload * 5ULL / 100); // 100 bytes or 5%
208-
if (!XR_VERIFY(compressedPayload < uncompressedPayload + maxIncrease)) {
209-
return false;
204+
if (getRecordableTypeId() != RecordableTypeId::VRSIndex) {
205+
uint32_t compressedPayload = recordSize.get() - sizeof(RecordHeader);
206+
// we did not always check that compression actually helped, and smaller sizes do worse
207+
uint32_t maxIncrease = (uncompressedPayload < 200)
208+
? max<size_t>(50, uncompressedPayload / 2) // 50 bytes or 50%
209+
: max<size_t>(100, uncompressedPayload * 5ULL / 100); // 100 bytes or 5%
210+
if (!XR_VERIFY(compressedPayload < uncompressedPayload + maxIncrease)) {
211+
return false;
212+
}
210213
}
211214
if (!XR_VERIFY(compressionType.get() != static_cast<uint8_t>(CompressionType::None)) ||
212215
!XR_VERIFY(compressionType.get() < static_cast<uint8_t>(CompressionType::COUNT))) {
@@ -309,6 +312,38 @@ bool printVRSFileInternals(unique_ptr<FileHandler>& file) {
309312
} else if (indexRecordHeader.recordSize.get() < fileHeader.recordHeaderSize.get()) {
310313
cerr << "This is smaller than a record header, so something's really off!\n";
311314
returnValue = false;
315+
} else if (
316+
indexRecordHeader.getCompressionType() != CompressionType::None ||
317+
indexRecordHeader.uncompressedSize.get() != 0) {
318+
cout << "Index Record uncompressed size: "
319+
<< helpers::humanReadableFileSize(indexRecordHeader.uncompressedSize.get())
320+
<< ", compressed with " << toString(indexRecordHeader.getCompressionType()) << ".\n";
321+
}
322+
int64_t offsetBefore = file->getPos();
323+
set<StreamId> streamIds;
324+
vector<IndexRecord::RecordInfo> records;
325+
ProgressLogger logger;
326+
IndexRecord::Reader indexReader(*file, fileHeader, &logger, streamIds, records);
327+
int64_t usedFileSize{};
328+
int status = indexReader.readRecord(fileHeader.firstUserRecordOffset.get(), usedFileSize);
329+
if (status != 0) {
330+
cerr << "Can't read index record, error " << errorCodeToMessageWithCode(status) << "\n";
331+
returnValue = false;
332+
} else {
333+
int64_t indexReadSize = file->getPos() - offsetBefore;
334+
cout << "Index Record contains " << records.size() << " records, "
335+
<< helpers::humanReadableFileSize(records.size() * sizeof(IndexRecord::DiskRecordInfo))
336+
<< " worth of data, " << helpers::humanReadableFileSize(indexReadSize) << " compressed";
337+
if (indexRecordHeader.uncompressedSize.get() > 0) {
338+
double ratio = ((indexRecordHeader.uncompressedSize.get() - indexReadSize) * 100.0) /
339+
indexRecordHeader.uncompressedSize.get();
340+
cout << fmt::format(", {:.2f}% saved", ratio);
341+
}
342+
if (indexRecordHeader.recordSize.get() > indexReadSize) {
343+
double usage = (indexReadSize * 100.0) / indexRecordHeader.recordSize.get();
344+
cout << fmt::format(", record {:.2f}% used", usage);
345+
}
346+
cout << ".\n";
312347
}
313348
int64_t endOfSplitIndexRecordOffset = 0;
314349
uint32_t indexFormatVersion = indexRecordHeader.formatVersion.get();

0 commit comments

Comments
 (0)