| 39 | }; |
| 40 | |
| 41 | Status Table::Open(const Options& options, RandomAccessFile* file, uint64 size, |
| 42 | Table** table) { |
| 43 | *table = nullptr; |
| 44 | if (size < Footer::kEncodedLength) { |
| 45 | return errors::DataLoss("file is too short to be an sstable"); |
| 46 | } |
| 47 | |
| 48 | char footer_space[Footer::kEncodedLength]; |
| 49 | StringPiece footer_input; |
| 50 | Status s = file->Read(size - Footer::kEncodedLength, Footer::kEncodedLength, |
| 51 | &footer_input, footer_space); |
| 52 | if (!s.ok()) return s; |
| 53 | |
| 54 | Footer footer; |
| 55 | s = footer.DecodeFrom(&footer_input); |
| 56 | if (!s.ok()) return s; |
| 57 | |
| 58 | // Read the index block |
| 59 | BlockContents contents; |
| 60 | Block* index_block = nullptr; |
| 61 | if (s.ok()) { |
| 62 | s = ReadBlock(file, footer.index_handle(), &contents); |
| 63 | if (s.ok()) { |
| 64 | index_block = new Block(contents); |
| 65 | } |
| 66 | } |
| 67 | |
| 68 | if (s.ok()) { |
| 69 | // We've successfully read the footer and the index block: we're |
| 70 | // ready to serve requests. |
| 71 | Rep* rep = new Table::Rep; |
| 72 | rep->options = options; |
| 73 | rep->file = file; |
| 74 | rep->metaindex_handle = footer.metaindex_handle(); |
| 75 | rep->index_block = index_block; |
| 76 | // XXX rep->cache_id = (options.block_cache ? |
| 77 | // options.block_cache->NewId() : 0); |
| 78 | *table = new Table(rep); |
| 79 | } else { |
| 80 | if (index_block) delete index_block; |
| 81 | } |
| 82 | |
| 83 | return s; |
| 84 | } |
| 85 | |
| 86 | Table::~Table() { delete rep_; } |
| 87 | |