LCOV - code coverage report
Current view: top level - src/leveldb/db - log_writer.cc (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 62 69 89.9 %
Date: 2022-04-21 14:51:19 Functions: 5 6 83.3 %
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: 21 24 87.5 %

           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 "db/log_writer.h"
#       6                 :            : 
#       7                 :            : #include <stdint.h>
#       8                 :            : 
#       9                 :            : #include "leveldb/env.h"
#      10                 :            : #include "util/coding.h"
#      11                 :            : #include "util/crc32c.h"
#      12                 :            : 
#      13                 :            : namespace leveldb {
#      14                 :            : namespace log {
#      15                 :            : 
#      16                 :       5605 : static void InitTypeCrc(uint32_t* type_crc) {
#      17         [ +  + ]:      33630 :   for (int i = 0; i <= kMaxRecordType; i++) {
#      18                 :      28025 :     char t = static_cast<char>(i);
#      19                 :      28025 :     type_crc[i] = crc32c::Value(&t, 1);
#      20                 :      28025 :   }
#      21                 :       5605 : }
#      22                 :            : 
#      23                 :       5605 : Writer::Writer(WritableFile* dest) : dest_(dest), block_offset_(0) {
#      24                 :       5605 :   InitTypeCrc(type_crc_);
#      25                 :       5605 : }
#      26                 :            : 
#      27                 :            : Writer::Writer(WritableFile* dest, uint64_t dest_length)
#      28                 :          0 :     : dest_(dest), block_offset_(dest_length % kBlockSize) {
#      29                 :          0 :   InitTypeCrc(type_crc_);
#      30                 :          0 : }
#      31                 :            : 
#      32                 :       5605 : Writer::~Writer() = default;
#      33                 :            : 
#      34                 :      19391 : Status Writer::AddRecord(const Slice& slice) {
#      35                 :      19391 :   const char* ptr = slice.data();
#      36                 :      19391 :   size_t left = slice.size();
#      37                 :            : 
#      38                 :            :   // Fragment the record if necessary and emit it.  Note that if slice
#      39                 :            :   // is empty, we still want to iterate once to emit a single
#      40                 :            :   // zero-length record
#      41                 :      19391 :   Status s;
#      42                 :      19391 :   bool begin = true;
#      43                 :      19954 :   do {
#      44                 :      19954 :     const int leftover = kBlockSize - block_offset_;
#      45                 :      19954 :     assert(leftover >= 0);
#      46         [ +  + ]:      19954 :     if (leftover < kHeaderSize) {
#      47                 :            :       // Switch to a new block
#      48         [ +  + ]:        567 :       if (leftover > 0) {
#      49                 :            :         // Fill the trailer (literal below relies on kHeaderSize being 7)
#      50                 :          4 :         static_assert(kHeaderSize == 7, "");
#      51                 :          4 :         dest_->Append(Slice("\x00\x00\x00\x00\x00\x00", leftover));
#      52                 :          4 :       }
#      53                 :        567 :       block_offset_ = 0;
#      54                 :        567 :     }
#      55                 :            : 
#      56                 :            :     // Invariant: we never leave < kHeaderSize bytes in a block.
#      57                 :      19954 :     assert(kBlockSize - block_offset_ - kHeaderSize >= 0);
#      58                 :            : 
#      59                 :          0 :     const size_t avail = kBlockSize - block_offset_ - kHeaderSize;
#      60         [ +  + ]:      19954 :     const size_t fragment_length = (left < avail) ? left : avail;
#      61                 :            : 
#      62                 :      19954 :     RecordType type;
#      63                 :      19954 :     const bool end = (left == fragment_length);
#      64 [ +  + ][ +  + ]:      19954 :     if (begin && end) {
#      65                 :      19193 :       type = kFullType;
#      66         [ +  + ]:      19193 :     } else if (begin) {
#      67                 :        198 :       type = kFirstType;
#      68         [ +  + ]:        563 :     } else if (end) {
#      69                 :        198 :       type = kLastType;
#      70                 :        365 :     } else {
#      71                 :        365 :       type = kMiddleType;
#      72                 :        365 :     }
#      73                 :            : 
#      74                 :      19954 :     s = EmitPhysicalRecord(type, ptr, fragment_length);
#      75                 :      19954 :     ptr += fragment_length;
#      76                 :      19954 :     left -= fragment_length;
#      77                 :      19954 :     begin = false;
#      78 [ +  - ][ +  + ]:      19954 :   } while (s.ok() && left > 0);
#      79                 :          0 :   return s;
#      80                 :      19391 : }
#      81                 :            : 
#      82                 :            : Status Writer::EmitPhysicalRecord(RecordType t, const char* ptr,
#      83                 :      19954 :                                   size_t length) {
#      84                 :      19954 :   assert(length <= 0xffff);  // Must fit in two bytes
#      85                 :          0 :   assert(block_offset_ + kHeaderSize + length <= kBlockSize);
#      86                 :            : 
#      87                 :            :   // Format the header
#      88                 :          0 :   char buf[kHeaderSize];
#      89                 :      19954 :   buf[4] = static_cast<char>(length & 0xff);
#      90                 :      19954 :   buf[5] = static_cast<char>(length >> 8);
#      91                 :      19954 :   buf[6] = static_cast<char>(t);
#      92                 :            : 
#      93                 :            :   // Compute the crc of the record type and the payload.
#      94                 :      19954 :   uint32_t crc = crc32c::Extend(type_crc_[t], ptr, length);
#      95                 :      19954 :   crc = crc32c::Mask(crc);  // Adjust for storage
#      96                 :      19954 :   EncodeFixed32(buf, crc);
#      97                 :            : 
#      98                 :            :   // Write the header and the payload
#      99                 :      19954 :   Status s = dest_->Append(Slice(buf, kHeaderSize));
#     100         [ +  - ]:      19954 :   if (s.ok()) {
#     101                 :      19954 :     s = dest_->Append(Slice(ptr, length));
#     102         [ +  - ]:      19954 :     if (s.ok()) {
#     103                 :      19954 :       s = dest_->Flush();
#     104                 :      19954 :     }
#     105                 :      19954 :   }
#     106                 :      19954 :   block_offset_ += kHeaderSize + length;
#     107                 :      19954 :   return s;
#     108                 :      19954 : }
#     109                 :            : 
#     110                 :            : }  // namespace log
#     111                 :            : }  // namespace leveldb

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