LCOV - code coverage report
Current view: top level - src/leveldb/table - format.cc (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 67 105 63.8 %
Date: 2022-04-21 14:51:19 Functions: 5 5 100.0 %
Legend: Modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed

Not modified by patch:
Lines: hit not hit | Branches: + taken - not taken # not executed
Branches: 15 30 50.0 %

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

Generated by: LCOV version 0-eol-96201-ge66f56f4af6a