Generalize footer reading from file
Summary: Generalizing this process will help us to re-use the code for plain table Test Plan: ran ./table_test
This commit is contained in:
parent
5dec7acd91
commit
219b35be6a
@ -77,12 +77,12 @@ void LogPropertiesCollectionError(
|
|||||||
|
|
||||||
} // anonymous namespace
|
} // anonymous namespace
|
||||||
|
|
||||||
// kBlockedBasedTableMagicNumber was picked by running
|
// kBlockBasedTableMagicNumber was picked by running
|
||||||
// echo http://code.google.com/p/leveldb/ | sha1sum
|
// echo http://code.google.com/p/leveldb/ | sha1sum
|
||||||
// and taking the leading 64 bits.
|
// and taking the leading 64 bits.
|
||||||
// Please note that kBlockedBasedTableMagicNumber may also be accessed by
|
// Please note that kBlockBasedTableMagicNumber may also be accessed by
|
||||||
// other .cc files so it have to be explicitly declared with "extern".
|
// other .cc files so it have to be explicitly declared with "extern".
|
||||||
extern const uint64_t kBlockedBasedTableMagicNumber
|
extern const uint64_t kBlockBasedTableMagicNumber
|
||||||
= 0xdb4775248b80fb57ull;
|
= 0xdb4775248b80fb57ull;
|
||||||
|
|
||||||
struct BlockBasedTableBuilder::Rep {
|
struct BlockBasedTableBuilder::Rep {
|
||||||
@ -511,7 +511,7 @@ Status BlockBasedTableBuilder::Finish() {
|
|||||||
|
|
||||||
// Write footer
|
// Write footer
|
||||||
if (ok()) {
|
if (ok()) {
|
||||||
Footer footer(kBlockedBasedTableMagicNumber);
|
Footer footer(kBlockBasedTableMagicNumber);
|
||||||
footer.set_metaindex_handle(metaindex_block_handle);
|
footer.set_metaindex_handle(metaindex_block_handle);
|
||||||
footer.set_index_handle(index_block_handle);
|
footer.set_index_handle(index_block_handle);
|
||||||
std::string footer_encoding;
|
std::string footer_encoding;
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
|
|
||||||
namespace rocksdb {
|
namespace rocksdb {
|
||||||
|
|
||||||
extern uint64_t kBlockedBasedTableMagicNumber;
|
extern uint64_t kBlockBasedTableMagicNumber;
|
||||||
|
|
||||||
// The longest the prefix of the cache key used to identify blocks can be.
|
// The longest the prefix of the cache key used to identify blocks can be.
|
||||||
// We are using the fact that we know for Posix files the unique ID is three
|
// We are using the fact that we know for Posix files the unique ID is three
|
||||||
@ -228,24 +228,9 @@ Status BlockBasedTable::Open(const Options& options,
|
|||||||
uint64_t size,
|
uint64_t size,
|
||||||
unique_ptr<TableReader>* table_reader) {
|
unique_ptr<TableReader>* table_reader) {
|
||||||
table_reader->reset();
|
table_reader->reset();
|
||||||
if (size < Footer::kEncodedLength) {
|
|
||||||
return Status::InvalidArgument("file is too short to be an sstable");
|
|
||||||
}
|
|
||||||
|
|
||||||
char footer_space[Footer::kEncodedLength];
|
Footer footer(kBlockBasedTableMagicNumber);
|
||||||
Slice footer_input;
|
auto s = ReadFooterFromFile(file.get(), size, &footer);
|
||||||
Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength,
|
|
||||||
&footer_input, footer_space);
|
|
||||||
if (!s.ok()) return s;
|
|
||||||
|
|
||||||
// Check that we actually read the whole footer from the file. It may be
|
|
||||||
// that size isn't correct.
|
|
||||||
if (footer_input.size() != Footer::kEncodedLength) {
|
|
||||||
return Status::InvalidArgument("file is too short to be an sstable");
|
|
||||||
}
|
|
||||||
|
|
||||||
Footer footer(kBlockedBasedTableMagicNumber);
|
|
||||||
s = footer.DecodeFrom(&footer_input);
|
|
||||||
if (!s.ok()) return s;
|
if (!s.ok()) return s;
|
||||||
|
|
||||||
// We've successfully read the footer and the index block: we're
|
// We've successfully read the footer and the index block: we're
|
||||||
|
@ -73,6 +73,30 @@ Status Footer::DecodeFrom(Slice* input) {
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Status ReadFooterFromFile(RandomAccessFile* file,
|
||||||
|
uint64_t file_size,
|
||||||
|
Footer* footer) {
|
||||||
|
if (file_size < Footer::kEncodedLength) {
|
||||||
|
return Status::InvalidArgument("file is too short to be an sstable");
|
||||||
|
}
|
||||||
|
|
||||||
|
char footer_space[Footer::kEncodedLength];
|
||||||
|
Slice footer_input;
|
||||||
|
Status s = file->Read(file_size - Footer::kEncodedLength,
|
||||||
|
Footer::kEncodedLength,
|
||||||
|
&footer_input,
|
||||||
|
footer_space);
|
||||||
|
if (!s.ok()) return s;
|
||||||
|
|
||||||
|
// Check that we actually read the whole footer from the file. It may be
|
||||||
|
// that size isn't correct.
|
||||||
|
if (footer_input.size() != Footer::kEncodedLength) {
|
||||||
|
return Status::InvalidArgument("file is too short to be an sstable");
|
||||||
|
}
|
||||||
|
|
||||||
|
return footer->DecodeFrom(&footer_input);
|
||||||
|
}
|
||||||
|
|
||||||
Status ReadBlockContents(RandomAccessFile* file,
|
Status ReadBlockContents(RandomAccessFile* file,
|
||||||
const ReadOptions& options,
|
const ReadOptions& options,
|
||||||
const BlockHandle& handle,
|
const BlockHandle& handle,
|
||||||
|
@ -98,6 +98,11 @@ class Footer {
|
|||||||
const uint64_t kTableMagicNumber;
|
const uint64_t kTableMagicNumber;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
// Read the footer from file
|
||||||
|
Status ReadFooterFromFile(RandomAccessFile* file,
|
||||||
|
uint64_t file_size,
|
||||||
|
Footer* footer);
|
||||||
|
|
||||||
// 1-byte type + 32-bit crc
|
// 1-byte type + 32-bit crc
|
||||||
static const size_t kBlockTrailerSize = 5;
|
static const size_t kBlockTrailerSize = 5;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user