LCOV - code coverage report
Current view: top level - src/leveldb/table - format.cc (source / functions) Hit Total Coverage
Test: total_coverage.info Lines: 50 66 75.8 %
Date: 2015-10-12 22:39:14 Functions: 5 5 100.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : // Copyright (c) 2011 The LevelDB Authors. All rights reserved.
       2             : // Use of this source code is governed by a BSD-style license that can be
       3             : // found in the LICENSE file. See the AUTHORS file for names of contributors.
       4             : 
       5             : #include "table/format.h"
       6             : 
       7             : #include "leveldb/env.h"
       8             : #include "port/port.h"
       9             : #include "table/block.h"
      10             : #include "util/coding.h"
      11             : #include "util/crc32c.h"
      12             : 
      13             : namespace leveldb {
      14             : 
      15         883 : void BlockHandle::EncodeTo(std::string* dst) const {
      16             :   // Sanity check that all fields have been set
      17         883 :   assert(offset_ != ~static_cast<uint64_t>(0));
      18         883 :   assert(size_ != ~static_cast<uint64_t>(0));
      19         883 :   PutVarint64(dst, offset_);
      20         883 :   PutVarint64(dst, size_);
      21         883 : }
      22             : 
      23       29786 : Status BlockHandle::DecodeFrom(Slice* input) {
      24       59572 :   if (GetVarint64(input, &offset_) &&
      25       29786 :       GetVarint64(input, &size_)) {
      26             :     return Status::OK();
      27             :   } else {
      28           0 :     return Status::Corruption("bad block handle");
      29             :   }
      30             : }
      31             : 
      32         122 : void Footer::EncodeTo(std::string* dst) const {
      33             : #ifndef NDEBUG
      34         122 :   const size_t original_size = dst->size();
      35             : #endif
      36         122 :   metaindex_handle_.EncodeTo(dst);
      37         122 :   index_handle_.EncodeTo(dst);
      38             :   dst->resize(2 * BlockHandle::kMaxEncodedLength);  // Padding
      39         122 :   PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber & 0xffffffffu));
      40         122 :   PutFixed32(dst, static_cast<uint32_t>(kTableMagicNumber >> 32));
      41         122 :   assert(dst->size() == original_size + kEncodedLength);
      42         122 : }
      43             : 
      44         160 : Status Footer::DecodeFrom(Slice* input) {
      45         160 :   const char* magic_ptr = input->data() + kEncodedLength - 8;
      46         160 :   const uint32_t magic_lo = DecodeFixed32(magic_ptr);
      47         320 :   const uint32_t magic_hi = DecodeFixed32(magic_ptr + 4);
      48         160 :   const uint64_t magic = ((static_cast<uint64_t>(magic_hi) << 32) |
      49         160 :                           (static_cast<uint64_t>(magic_lo)));
      50         160 :   if (magic != kTableMagicNumber) {
      51           0 :     return Status::Corruption("not an sstable (bad magic number)");
      52             :   }
      53             : 
      54         160 :   Status result = metaindex_handle_.DecodeFrom(input);
      55         160 :   if (result.ok()) {
      56         320 :     result = index_handle_.DecodeFrom(input);
      57             :   }
      58         160 :   if (result.ok()) {
      59             :     // We skip over any leftover data (just padding for now) in "input"
      60         160 :     const char* end = magic_ptr + 8;
      61         160 :     *input = Slice(end, input->data() + input->size() - end);
      62             :   }
      63             :   return result;
      64             : }
      65             : 
      66       12896 : Status ReadBlock(RandomAccessFile* file,
      67             :                  const ReadOptions& options,
      68             :                  const BlockHandle& handle,
      69             :                  BlockContents* result) {
      70       12896 :   result->data = Slice();
      71       12896 :   result->cachable = false;
      72       12896 :   result->heap_allocated = false;
      73             : 
      74             :   // Read the block contents as well as the type/crc footer.
      75             :   // See table_builder.cc for the code that built this structure.
      76       12896 :   size_t n = static_cast<size_t>(handle.size());
      77       12896 :   char* buf = new char[n + kBlockTrailerSize];
      78             :   Slice contents;
      79       12896 :   Status s = file->Read(handle.offset(), n + kBlockTrailerSize, &contents, buf);
      80       12896 :   if (!s.ok()) {
      81           0 :     delete[] buf;
      82             :     return s;
      83             :   }
      84       12896 :   if (contents.size() != n + kBlockTrailerSize) {
      85           0 :     delete[] buf;
      86           0 :     return Status::Corruption("truncated block read");
      87             :   }
      88             : 
      89             :   // Check the crc of the type and the block contents
      90       12896 :   const char* data = contents.data();    // Pointer to where Read put the data
      91       12896 :   if (options.verify_checksums) {
      92       38688 :     const uint32_t crc = crc32c::Unmask(DecodeFixed32(data + n + 1));
      93       25792 :     const uint32_t actual = crc32c::Value(data, n + 1);
      94       12896 :     if (actual != crc) {
      95           0 :       delete[] buf;
      96           0 :       s = Status::Corruption("block checksum mismatch");
      97             :       return s;
      98             :     }
      99             :   }
     100             : 
     101       12896 :   switch (data[n]) {
     102             :     case kNoCompression:
     103       12896 :       if (data != buf) {
     104             :         // File implementation gave us pointer to some other data.
     105             :         // Use it directly under the assumption that it will be live
     106             :         // while the file is open.
     107       12896 :         delete[] buf;
     108       12896 :         result->data = Slice(data, n);
     109       12896 :         result->heap_allocated = false;
     110       12896 :         result->cachable = false;  // Do not double-cache
     111             :       } else {
     112           0 :         result->data = Slice(buf, n);
     113           0 :         result->heap_allocated = true;
     114           0 :         result->cachable = true;
     115             :       }
     116             : 
     117             :       // Ok
     118             :       break;
     119             :     case kSnappyCompression: {
     120           0 :       size_t ulength = 0;
     121           0 :       if (!port::Snappy_GetUncompressedLength(data, n, &ulength)) {
     122           0 :         delete[] buf;
     123           0 :         return Status::Corruption("corrupted compressed block contents");
     124             :       }
     125             :       char* ubuf = new char[ulength];
     126             :       if (!port::Snappy_Uncompress(data, n, ubuf)) {
     127             :         delete[] buf;
     128             :         delete[] ubuf;
     129             :         return Status::Corruption("corrupted compressed block contents");
     130             :       }
     131             :       delete[] buf;
     132             :       result->data = Slice(ubuf, ulength);
     133             :       result->heap_allocated = true;
     134             :       result->cachable = true;
     135             :       break;
     136             :     }
     137             :     default:
     138           0 :       delete[] buf;
     139           0 :       return Status::Corruption("bad block type");
     140             :   }
     141             : 
     142             :   return Status::OK();
     143             : }
     144             : 
     145             : }  // namespace leveldb

Generated by: LCOV version 1.11