diff --git a/table/block_based_table_builder.cc b/table/block_based_table_builder.cc index fa7d56472..4cba3934f 100644 --- a/table/block_based_table_builder.cc +++ b/table/block_based_table_builder.cc @@ -77,12 +77,12 @@ void LogPropertiesCollectionError( } // anonymous namespace -// kBlockedBasedTableMagicNumber was picked by running +// kBlockBasedTableMagicNumber was picked by running // echo http://code.google.com/p/leveldb/ | sha1sum // 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". -extern const uint64_t kBlockedBasedTableMagicNumber +extern const uint64_t kBlockBasedTableMagicNumber = 0xdb4775248b80fb57ull; struct BlockBasedTableBuilder::Rep { @@ -511,7 +511,7 @@ Status BlockBasedTableBuilder::Finish() { // Write footer if (ok()) { - Footer footer(kBlockedBasedTableMagicNumber); + Footer footer(kBlockBasedTableMagicNumber); footer.set_metaindex_handle(metaindex_block_handle); footer.set_index_handle(index_block_handle); std::string footer_encoding; diff --git a/table/block_based_table_reader.cc b/table/block_based_table_reader.cc index d5b52fba2..11b8f6ca8 100644 --- a/table/block_based_table_reader.cc +++ b/table/block_based_table_reader.cc @@ -29,7 +29,7 @@ namespace rocksdb { -extern uint64_t kBlockedBasedTableMagicNumber; +extern uint64_t kBlockBasedTableMagicNumber; // 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 @@ -228,24 +228,9 @@ Status BlockBasedTable::Open(const Options& options, uint64_t size, unique_ptr* table_reader) { table_reader->reset(); - if (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(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); + Footer footer(kBlockBasedTableMagicNumber); + auto s = ReadFooterFromFile(file.get(), size, &footer); if (!s.ok()) return s; // We've successfully read the footer and the index block: we're diff --git a/table/format.cc b/table/format.cc index 17add6680..77a55237e 100644 --- a/table/format.cc +++ b/table/format.cc @@ -73,6 +73,30 @@ Status Footer::DecodeFrom(Slice* input) { 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, const ReadOptions& options, const BlockHandle& handle, diff --git a/table/format.h b/table/format.h index c10cab857..207527fcb 100644 --- a/table/format.h +++ b/table/format.h @@ -98,6 +98,11 @@ class Footer { 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 static const size_t kBlockTrailerSize = 5;