Beispiel #1
0
        /// <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;
        }
Beispiel #2
0
        void ReadMeta(Footer footer)
        {
            if (rep_.Options.FilterPolicy == null)
            {
                // Do not need any metadata
                return;
            }

            // TODO(sanjay): Skip this if footer.metaindex_handle() size indicates
            // it is an empty block.
            ReadOptions opt = ReadOptions.Default;
            BlockContents contents;
            if (!FormatHelper.ReadBlock(rep_.File, opt, footer.MetaindexHandle, out contents).IsOk)
            {
                // Do not propagate errors since meta info is not needed for operation
                return;
            }

            Block meta = new Block(contents);

            Iterator iter = meta.NewIterator(Comparator.BytewiseComparator);
            string key = "filter." + rep_.Options.FilterPolicy.Name;

            iter.Seek(key);
            if (iter.Valid && iter.Key == key)
            {
                ReadFilter(iter.Value);
            }
        }
Beispiel #3
0
        private static Iterator BlockReader(object arg, ReadOptions options, Slice indexValue)
        {
            Table table = (Table)arg;
            Cache blockCache = table.rep_.Options.BlockCache;
            Block block = null;
            Cache.Handle cacheHandle = null;

            BlockHandle handle = new BlockHandle();
            Slice input = indexValue;
            Status s = handle.DecodeFrom(ref input);
            // We intentionally allow extra stuff in index_value so that we
            // can add more features in the future.

            if (s.IsOk)
            {
                BlockContents contents;
                if (blockCache != null)
                {
                    ByteArrayPointer cacheKeyBuffer = new ByteArrayPointer(16);

                    Coding.EncodeFixed64(cacheKeyBuffer, table.rep_.CacheId);
                    Coding.EncodeFixed64(cacheKeyBuffer + 8, handle.Offset);

                    Slice key = new Slice(cacheKeyBuffer, cacheKeyBuffer.Length);

                    cacheHandle = blockCache.Lookup(key);
                    if (cacheHandle != null)
                    {
                        block = (Block)(blockCache.Value(cacheHandle));
                    }
                    else
                    {
                        s = FormatHelper.ReadBlock(table.rep_.File, options, handle, out contents);
                        if (s.IsOk)
                        {
                            block = new Block(contents);
                            if (contents.Cachable && options.FillCache)
                            {
                                cacheHandle = blockCache.Insert(key, block, block.Size);
                            }
                        }
                    }
                }
                else
                {
                    s = FormatHelper.ReadBlock(table.rep_.File, options, handle, out contents);
                    if (s.IsOk)
                    {
                        block = new Block(contents);
                    }
                }
            }

            Iterator iter;

            if (block != null)
            {
                iter = block.NewIterator(table.rep_.Options.Comparator);
                if (cacheHandle != null)
                {
                    iter.RegisterCleanup(ReleaseBlock, blockCache, cacheHandle);
                }
            }
            else
            {
                iter = Iterator.NewErrorIterator(s);
            }
            return iter;
        }