Changeset View
Changeset View
Standalone View
Standalone View
src/leveldb/table/format.cc
Show First 20 Lines • Show All 76 Lines • ▼ Show 20 Lines | Status ReadBlock(RandomAccessFile* file, | ||||
Slice contents; | Slice contents; | ||||
Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf); | Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf); | ||||
if (!s.ok()) { | if (!s.ok()) { | ||||
delete[] buf; | delete[] buf; | ||||
return s; | return s; | ||||
} | } | ||||
if (contents.size() != n + kBlockTrailerSize) { | if (contents.size() != n + kBlockTrailerSize) { | ||||
delete[] buf; | delete[] buf; | ||||
return Status::Corruption("truncated block read"); | return Status::Corruption("truncated block read", file->GetName()); | ||||
} | } | ||||
// Check the crc of the type and the block contents | // Check the crc of the type and the block contents | ||||
const char* data = contents.data(); // Pointer to where Read put the data | const char* data = contents.data(); // Pointer to where Read put the data | ||||
if (options.verify_checksums) { | if (options.verify_checksums) { | ||||
const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1)); | const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1)); | ||||
const uint32_t actual = crc32c::Value(data, n + 1); | const uint32_t actual = crc32c::Value(data, n + 1); | ||||
if (actual != crc) { | if (actual != crc) { | ||||
delete[] buf; | delete[] buf; | ||||
s = Status::Corruption("block checksum mismatch"); | s = Status::Corruption("block checksum mismatch", file->GetName()); | ||||
return s; | return s; | ||||
} | } | ||||
} | } | ||||
switch (data[n]) { | switch (data[n]) { | ||||
case kNoCompression: | case kNoCompression: | ||||
if (data != buf) { | if (data != buf) { | ||||
// File implementation gave us pointer to some other data. | // File implementation gave us pointer to some other data. | ||||
Show All 10 Lines | case kNoCompression: | ||||
} | } | ||||
// Ok | // Ok | ||||
break; | break; | ||||
case kSnappyCompression: { | case kSnappyCompression: { | ||||
size_t ulength = 0; | size_t ulength = 0; | ||||
if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) { | if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) { | ||||
delete[] buf; | delete[] buf; | ||||
return Status::Corruption("corrupted compressed block contents"); | return Status::Corruption("corrupted compressed block contents", file->GetName()); | ||||
} | } | ||||
char* ubuf = new char[ulength]; | char* ubuf = new char[ulength]; | ||||
if (!port::Snappy_Uncompress(data, n, ubuf)) { | if (!port::Snappy_Uncompress(data, n, ubuf)) { | ||||
delete[] buf; | delete[] buf; | ||||
delete[] ubuf; | delete[] ubuf; | ||||
return Status::Corruption("corrupted compressed block contents"); | return Status::Corruption("corrupted compressed block contents", file->GetName()); | ||||
} | } | ||||
delete[] buf; | delete[] buf; | ||||
result->data = Slice(ubuf, ulength); | result->data = Slice(ubuf, ulength); | ||||
result->heap_allocated = true; | result->heap_allocated = true; | ||||
result->cachable = true; | result->cachable = true; | ||||
break; | break; | ||||
} | } | ||||
default: | default: | ||||
delete[] buf; | delete[] buf; | ||||
return Status::Corruption("bad block type"); | return Status::Corruption("bad block type", file->GetName()); | ||||
} | } | ||||
return Status::OK(); | return Status::OK(); | ||||
} | } | ||||
} // namespace leveldb | } // namespace leveldb |