LCOV - code coverage report
Current view: top level - src/leveldb/util - coding.h (source / functions) Hit Total Coverage
Test: coverage.lcov Lines: 59 64 92.2 %
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: 4 4 100.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                 :            : // Endian-neutral encoding:
#       6                 :            : // * Fixed-length numbers are encoded with least-significant byte first
#       7                 :            : // * In addition we support variable length "varint" encoding
#       8                 :            : // * Strings are encoded prefixed by their length in varint format
#       9                 :            : 
#      10                 :            : #ifndef STORAGE_LEVELDB_UTIL_CODING_H_
#      11                 :            : #define STORAGE_LEVELDB_UTIL_CODING_H_
#      12                 :            : 
#      13                 :            : #include <cstdint>
#      14                 :            : #include <cstring>
#      15                 :            : #include <string>
#      16                 :            : 
#      17                 :            : #include "leveldb/slice.h"
#      18                 :            : #include "port/port.h"
#      19                 :            : 
#      20                 :            : namespace leveldb {
#      21                 :            : 
#      22                 :            : // Standard Put... routines append to a string
#      23                 :            : void PutFixed32(std::string* dst, uint32_t value);
#      24                 :            : void PutFixed64(std::string* dst, uint64_t value);
#      25                 :            : void PutVarint32(std::string* dst, uint32_t value);
#      26                 :            : void PutVarint64(std::string* dst, uint64_t value);
#      27                 :            : void PutLengthPrefixedSlice(std::string* dst, const Slice& value);
#      28                 :            : 
#      29                 :            : // Standard Get... routines parse a value from the beginning of a Slice
#      30                 :            : // and advance the slice past the parsed value.
#      31                 :            : bool GetVarint32(Slice* input, uint32_t* value);
#      32                 :            : bool GetVarint64(Slice* input, uint64_t* value);
#      33                 :            : bool GetLengthPrefixedSlice(Slice* input, Slice* result);
#      34                 :            : 
#      35                 :            : // Pointer-based variants of GetVarint...  These either store a value
#      36                 :            : // in *v and return a pointer just past the parsed value, or return
#      37                 :            : // nullptr on error.  These routines only look at bytes in the range
#      38                 :            : // [p..limit-1]
#      39                 :            : const char* GetVarint32Ptr(const char* p, const char* limit, uint32_t* v);
#      40                 :            : const char* GetVarint64Ptr(const char* p, const char* limit, uint64_t* v);
#      41                 :            : 
#      42                 :            : // Returns the length of the varint32 or varint64 encoding of "v"
#      43                 :            : int VarintLength(uint64_t v);
#      44                 :            : 
#      45                 :            : // Lower-level versions of Put... that write directly into a character buffer
#      46                 :            : // and return a pointer just past the last byte written.
#      47                 :            : // REQUIRES: dst has enough space for the value being written
#      48                 :            : char* EncodeVarint32(char* dst, uint32_t value);
#      49                 :            : char* EncodeVarint64(char* dst, uint64_t value);
#      50                 :            : 
#      51                 :            : // TODO(costan): Remove port::kLittleEndian and the fast paths based on
#      52                 :            : //               std::memcpy when clang learns to optimize the generic code, as
#      53                 :            : //               described in https://bugs.llvm.org/show_bug.cgi?id=41761
#      54                 :            : //
#      55                 :            : // The platform-independent code in DecodeFixed{32,64}() gets optimized to mov
#      56                 :            : // on x86 and ldr on ARM64, by both clang and gcc. However, only gcc optimizes
#      57                 :            : // the platform-independent code in EncodeFixed{32,64}() to mov / str.
#      58                 :            : 
#      59                 :            : // Lower-level versions of Put... that write directly into a character buffer
#      60                 :            : // REQUIRES: dst has enough space for the value being written
#      61                 :            : 
#      62                 :     431013 : inline void EncodeFixed32(char* dst, uint32_t value) {
#      63                 :     431013 :   uint8_t* const buffer = reinterpret_cast<uint8_t*>(dst);
#      64                 :            : 
#      65                 :     431013 :   if (port::kLittleEndian) {
#      66                 :            :     // Fast path for little-endian CPUs. All major compilers optimize this to a
#      67                 :            :     // single mov (x86_64) / str (ARM) instruction.
#      68                 :     431013 :     std::memcpy(buffer, &value, sizeof(uint32_t));
#      69                 :     431013 :     return;
#      70                 :     431013 :   }
#      71                 :            : 
#      72                 :            :   // Platform-independent code.
#      73                 :            :   // Currently, only gcc optimizes this to a single mov / str instruction.
#      74                 :          0 :   buffer[0] = static_cast<uint8_t>(value);
#      75                 :          0 :   buffer[1] = static_cast<uint8_t>(value >> 8);
#      76                 :          0 :   buffer[2] = static_cast<uint8_t>(value >> 16);
#      77                 :          0 :   buffer[3] = static_cast<uint8_t>(value >> 24);
#      78                 :          0 : }
#      79                 :            : 
#      80                 :   14179424 : inline void EncodeFixed64(char* dst, uint64_t value) {
#      81                 :   14179424 :   uint8_t* const buffer = reinterpret_cast<uint8_t*>(dst);
#      82                 :            : 
#      83                 :   14179424 :   if (port::kLittleEndian) {
#      84                 :            :     // Fast path for little-endian CPUs. All major compilers optimize this to a
#      85                 :            :     // single mov (x86_64) / str (ARM) instruction.
#      86                 :   14179423 :     std::memcpy(buffer, &value, sizeof(uint64_t));
#      87                 :   14179423 :     return;
#      88                 :   14179423 :   }
#      89                 :            : 
#      90                 :            :   // Platform-independent code.
#      91                 :            :   // Currently, only gcc optimizes this to a single mov / str instruction.
#      92                 :          1 :   buffer[0] = static_cast<uint8_t>(value);
#      93                 :          1 :   buffer[1] = static_cast<uint8_t>(value >> 8);
#      94                 :          1 :   buffer[2] = static_cast<uint8_t>(value >> 16);
#      95                 :          1 :   buffer[3] = static_cast<uint8_t>(value >> 24);
#      96                 :          1 :   buffer[4] = static_cast<uint8_t>(value >> 32);
#      97                 :          1 :   buffer[5] = static_cast<uint8_t>(value >> 40);
#      98                 :          1 :   buffer[6] = static_cast<uint8_t>(value >> 48);
#      99                 :          1 :   buffer[7] = static_cast<uint8_t>(value >> 56);
#     100                 :          1 : }
#     101                 :            : 
#     102                 :            : // Lower-level versions of Get... that read directly from a character buffer
#     103                 :            : // without any bounds checking.
#     104                 :            : 
#     105                 :   86452065 : inline uint32_t DecodeFixed32(const char* ptr) {
#     106                 :   86452065 :   const uint8_t* const buffer = reinterpret_cast<const uint8_t*>(ptr);
#     107                 :            : 
#     108                 :   86452068 :   if (port::kLittleEndian) {
#     109                 :            :     // Fast path for little-endian CPUs. All major compilers optimize this to a
#     110                 :            :     // single mov (x86_64) / ldr (ARM) instruction.
#     111                 :   86452068 :     uint32_t result;
#     112                 :   86452068 :     std::memcpy(&result, buffer, sizeof(uint32_t));
#     113                 :   86452068 :     return result;
#     114                 :   86452068 :   }
#     115                 :            : 
#     116                 :            :   // Platform-independent code.
#     117                 :            :   // Clang and gcc optimize this to a single mov / ldr instruction.
#     118                 :>1844*10^16 :   return (static_cast<uint32_t>(buffer[0])) |
#     119                 :>1844*10^16 :          (static_cast<uint32_t>(buffer[1]) << 8) |
#     120                 :>1844*10^16 :          (static_cast<uint32_t>(buffer[2]) << 16) |
#     121                 :>1844*10^16 :          (static_cast<uint32_t>(buffer[3]) << 24);
#     122                 :   86452065 : }
#     123                 :            : 
#     124                 :    2652717 : inline uint64_t DecodeFixed64(const char* ptr) {
#     125                 :    2652717 :   const uint8_t* const buffer = reinterpret_cast<const uint8_t*>(ptr);
#     126                 :            : 
#     127                 :    2652720 :   if (port::kLittleEndian) {
#     128                 :            :     // Fast path for little-endian CPUs. All major compilers optimize this to a
#     129                 :            :     // single mov (x86_64) / ldr (ARM) instruction.
#     130                 :    2652720 :     uint64_t result;
#     131                 :    2652720 :     std::memcpy(&result, buffer, sizeof(uint64_t));
#     132                 :    2652720 :     return result;
#     133                 :    2652720 :   }
#     134                 :            : 
#     135                 :            :   // Platform-independent code.
#     136                 :            :   // Clang and gcc optimize this to a single mov / ldr instruction.
#     137                 :>1844*10^16 :   return (static_cast<uint64_t>(buffer[0])) |
#     138                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[1]) << 8) |
#     139                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[2]) << 16) |
#     140                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[3]) << 24) |
#     141                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[4]) << 32) |
#     142                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[5]) << 40) |
#     143                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[6]) << 48) |
#     144                 :>1844*10^16 :          (static_cast<uint64_t>(buffer[7]) << 56);
#     145                 :    2652717 : }
#     146                 :            : 
#     147                 :            : // Internal routine for use by fallback path of GetVarint32Ptr
#     148                 :            : const char* GetVarint32PtrFallback(const char* p, const char* limit,
#     149                 :            :                                    uint32_t* value);
#     150                 :            : inline const char* GetVarint32Ptr(const char* p, const char* limit,
#     151                 :  451513337 :                                   uint32_t* value) {
#     152         [ +  + ]:  451513337 :   if (p < limit) {
#     153                 :  451510118 :     uint32_t result = *(reinterpret_cast<const uint8_t*>(p));
#     154         [ +  + ]:  451510118 :     if ((result & 128) == 0) {
#     155                 :  451506262 :       *value = result;
#     156                 :  451506262 :       return p + 1;
#     157                 :  451506262 :     }
#     158                 :  451510118 :   }
#     159                 :       7075 :   return GetVarint32PtrFallback(p, limit, value);
#     160                 :  451513337 : }
#     161                 :            : 
#     162                 :            : }  // namespace leveldb
#     163                 :            : 
#     164                 :            : #endif  // STORAGE_LEVELDB_UTIL_CODING_H_

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