示例#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;
        }
示例#2
0
        public static Status ReadBlock(RandomAccessFile file, ReadOptions options, BlockHandle handle, out BlockContents result)
        {
            result.Data = new Slice();
            result.Cachable = false;
            result.HeapAllocated = false;

            // Read the block contents as well as the type/crc footer.
            // See table_builder.cc for the code that built this structure.
            int n = (int)handle.Size;
            ByteArrayPointer buf = new ByteArrayPointer(n + kBlockTrailerSize);

            Slice contents;
            Status s = file.Read(handle.Offset, n + kBlockTrailerSize, out contents, buf);

            if (!s.IsOk)
            {
                return s;
            }
            if (contents.Size != n + kBlockTrailerSize)
            {
                return Status.Corruption("truncated block read");
            }

            // Check the crc of the type and the block contents
            ByteArrayPointer data = contents.Data;    // Pointer to where Read put the data
            if (options.VerifyChecksums)
            {
                //    const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));
                //const uint32_t actual = crc32c::Value(data, n + 1);
                //if (actual != crc) {
                //  delete[] buf;
                //  s = Status::Corruption("block checksum mismatch");
                //  return s;
                //}
                throw new NotSupportedException("CRC is not supported yet");
            }

            switch ((CompressionType)data[n])
            {
                case CompressionType.kNoCompression:
                    if (data != buf)
                    {
                        // File implementation gave us pointer to some other data.
                        // Use it directly under the assumption that it will be live
                        // while the file is open.

                        result.Data = new Slice(data, n);
                        result.HeapAllocated = false;
                        result.Cachable = false;  // Do not double-cache
                    }
                    else
                    {
                        result.Data = new Slice(buf, n);
                        result.HeapAllocated = true;
                        result.Cachable = true;
                    }

                    // Ok
                    break;
                case CompressionType.kSnappyCompression:
                    throw new NotSupportedException("snappy not supported");
                //  {
                //  int ulength = 0;
                //  if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
                //    delete[] buf;
                //    return Status::Corruption("corrupted compressed block contents");
                //  }
                //  char* ubuf = new char[ulength];
                //  if (!port::Snappy_Uncompress(data, n, ubuf)) {
                //    delete[] buf;
                //    delete[] ubuf;
                //    return Status::Corruption("corrupted compressed block contents");
                //  }
                //  delete[] buf;
                //  result->data = Slice(ubuf, ulength);
                //  result->heap_allocated = true;
                //  result->cachable = true;
                //  break;
                //}
                default:

                    return Status.Corruption("bad block type");
            }

            return Status.OK;
        }