/// <summary> /// Attempt to open the table that is stored in bytes [0..file_size) /// of "file", and read the metadata entries necessary to allow /// retrieving data from the table. /// /// If successful, returns ok and sets "*table" to the newly opened /// table. The client should delete "*table" when no longer needed. /// If there was an error while initializing the table, sets "*table" /// to NULL and returns a non-ok status. Does not take ownership of /// "*source", but the client must ensure that "source" remains live /// for the duration of the returned table's lifetime. /// /// *file must remain live while this Table is in use. /// </summary> public static Status Open(Options options, RandomAccessFile file, UInt64 size, out Table table) { table = null; if (size < Footer.kEncodedLength) { return Status.InvalidArgument("file is too short to be an sstable"); } ByteArrayPointer footerSpace = new ByteArrayPointer(Footer.kEncodedLength); Slice footerInput; Status s = file.Read(size - Footer.kEncodedLength, Footer.kEncodedLength, out footerInput, footerSpace); if (!s.IsOk) return s; Footer footer = new Footer(); s = footer.DecodeFrom(ref footerInput); if (!s.IsOk) return s; // Read the index block BlockContents contents; Block indexBlock = null; if (s.IsOk) { s = FormatHelper.ReadBlock(file, ReadOptions.Default, footer.IndexHandle, out contents); if (s.IsOk) { indexBlock = new Block(contents); } } if (s.IsOk) { // We've successfully read the footer and the index block: we're // ready to serve requests. Rep rep = new Rep(); rep.Options = options; rep.File = file; rep.MetaindexHandle = footer.MetaindexHandle; rep.IndexBlock = indexBlock; rep.CacheId = (options.BlockCache != null ? options.BlockCache.NewId() : 0); rep.FilterData = ByteArrayPointer.Null; rep.Filter = null; table = new Table(rep); table.ReadMeta(footer); } return s; }