void Table::ReadMeta(const Footer& footer) { if (rep_->options.filter_policy == NULL) { return; // Do not need any metadata } // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates // it is an empty block. ReadOptions opt; if (rep_->options.paranoid_checks) { opt.verify_checksums = true; } BlockContents contents; if (!ReadBlock(rep_->file, opt, footer.metaindex_handle(), &contents).ok()) { // Do not propagate errors since meta info is not needed for operation return; } Block* meta = new Block(contents); Iterator* iter = meta->NewIterator(BytewiseComparator()); std::string key = "filter."; key.append(rep_->options.filter_policy->Name()); iter->Seek(key); if (iter->Valid() && iter->key() == Slice(key)) { ReadFilter(iter->value()); } delete iter; delete meta; }
Status Table::Open(const Options& options, RandomAccessFile* file, uint64_t size, Table** table) { *table = NULL; if (size < Footer::kEncodedLength) { return Status::Corruption("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; Footer footer; s = footer.DecodeFrom(&footer_input); if (!s.ok()) return s; // Read the index block BlockContents contents; Block* index_block = NULL; if (s.ok()) { ReadOptions opt; if (options.paranoid_checks) { opt.verify_checksums = true; } s = ReadBlock(file, opt, footer.index_handle(), &contents); if (s.ok()) { index_block = new Block(contents); } } if (s.ok()) { // We've successfully read the footer and the index block: we're // ready to serve requests. Rep* rep = new Table::Rep; rep->options = options; rep->file = file; rep->metaindex_handle = footer.metaindex_handle(); rep->index_block = index_block; rep->cache_id = (options.block_cache ? options.block_cache->NewId() : 0); rep->filter_data = NULL; rep->filter = NULL; *table = new Table(rep); (*table)->ReadMeta(footer); } else { delete index_block; } return s; }