Coverage Report

Created: 2025-08-29 06:56

/src/leveldb/port/port_stdcxx.h
Line
Count
Source (jump to first uncovered line)
1
// Copyright (c) 2018 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
#ifndef STORAGE_LEVELDB_PORT_PORT_STDCXX_H_
6
#define STORAGE_LEVELDB_PORT_PORT_STDCXX_H_
7
8
// port/port_config.h availability is automatically detected via __has_include
9
// in newer compilers. If LEVELDB_HAS_PORT_CONFIG_H is defined, it overrides the
10
// configuration detection.
11
#if defined(LEVELDB_HAS_PORT_CONFIG_H)
12
13
#if LEVELDB_HAS_PORT_CONFIG_H
14
#include "port/port_config.h"
15
#endif  // LEVELDB_HAS_PORT_CONFIG_H
16
17
#elif defined(__has_include)
18
19
#if __has_include("port/port_config.h")
20
#include "port/port_config.h"
21
#endif  // __has_include("port/port_config.h")
22
23
#endif  // defined(LEVELDB_HAS_PORT_CONFIG_H)
24
25
#if HAVE_CRC32C
26
#include <crc32c/crc32c.h>
27
#endif  // HAVE_CRC32C
28
#if HAVE_SNAPPY
29
#include <snappy.h>
30
#endif  // HAVE_SNAPPY
31
#if HAVE_ZSTD
32
#define ZSTD_STATIC_LINKING_ONLY  // For ZSTD_compressionParameters.
33
#include <zstd.h>
34
#endif  // HAVE_ZSTD
35
36
#include <cassert>
37
#include <condition_variable>  // NOLINT
38
#include <cstddef>
39
#include <cstdint>
40
#include <mutex>  // NOLINT
41
#include <string>
42
43
#include "port/thread_annotations.h"
44
45
namespace leveldb {
46
namespace port {
47
48
class CondVar;
49
50
// Thinly wraps std::mutex.
51
class LOCKABLE Mutex {
52
 public:
53
4.33M
  Mutex() = default;
54
  ~Mutex() = default;
55
56
  Mutex(const Mutex&) = delete;
57
  Mutex& operator=(const Mutex&) = delete;
58
59
10.5M
  void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); }
60
10.5M
  void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); }
61
5.57M
  void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {}
62
63
 private:
64
  friend class CondVar;
65
  std::mutex mu_;
66
};
67
68
// Thinly wraps std::condition_variable.
69
class CondVar {
70
 public:
71
2.37M
  explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); }
72
2.37M
  ~CondVar() = default;
73
74
  CondVar(const CondVar&) = delete;
75
  CondVar& operator=(const CondVar&) = delete;
76
77
270k
  void Wait() {
78
270k
    std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock);
79
270k
    cv_.wait(lock);
80
270k
    lock.release();
81
270k
  }
82
138k
  void Signal() { cv_.notify_one(); }
83
146k
  void SignalAll() { cv_.notify_all(); }
84
85
 private:
86
  std::condition_variable cv_;
87
  Mutex* const mu_;
88
};
89
90
inline bool Snappy_Compress(const char* input, size_t length,
91
261k
                            std::string* output) {
92
#if HAVE_SNAPPY
93
  output->resize(snappy::MaxCompressedLength(length));
94
  size_t outlen;
95
  snappy::RawCompress(input, length, &(*output)[0], &outlen);
96
  output->resize(outlen);
97
  return true;
98
#else
99
  // Silence compiler warnings about unused arguments.
100
261k
  (void)input;
101
261k
  (void)length;
102
261k
  (void)output;
103
261k
#endif  // HAVE_SNAPPY
104
105
261k
  return false;
106
261k
}
107
108
inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
109
0
                                         size_t* result) {
110
#if HAVE_SNAPPY
111
  return snappy::GetUncompressedLength(input, length, result);
112
#else
113
  // Silence compiler warnings about unused arguments.
114
0
  (void)input;
115
0
  (void)length;
116
0
  (void)result;
117
0
  return false;
118
0
#endif  // HAVE_SNAPPY
119
0
}
120
121
0
inline bool Snappy_Uncompress(const char* input, size_t length, char* output) {
122
#if HAVE_SNAPPY
123
  return snappy::RawUncompress(input, length, output);
124
#else
125
  // Silence compiler warnings about unused arguments.
126
0
  (void)input;
127
0
  (void)length;
128
0
  (void)output;
129
0
  return false;
130
0
#endif  // HAVE_SNAPPY
131
0
}
132
133
inline bool Zstd_Compress(int level, const char* input, size_t length,
134
0
                          std::string* output) {
135
#if HAVE_ZSTD
136
  // Get the MaxCompressedLength.
137
  size_t outlen = ZSTD_compressBound(length);
138
  if (ZSTD_isError(outlen)) {
139
    return false;
140
  }
141
  output->resize(outlen);
142
  ZSTD_CCtx* ctx = ZSTD_createCCtx();
143
  ZSTD_compressionParameters parameters =
144
      ZSTD_getCParams(level, std::max(length, size_t{1}), /*dictSize=*/0);
145
  ZSTD_CCtx_setCParams(ctx, parameters);
146
  outlen = ZSTD_compress2(ctx, &(*output)[0], output->size(), input, length);
147
  ZSTD_freeCCtx(ctx);
148
  if (ZSTD_isError(outlen)) {
149
    return false;
150
  }
151
  output->resize(outlen);
152
  return true;
153
#else
154
  // Silence compiler warnings about unused arguments.
155
0
  (void)level;
156
0
  (void)input;
157
0
  (void)length;
158
0
  (void)output;
159
0
  return false;
160
0
#endif  // HAVE_ZSTD
161
0
}
162
163
inline bool Zstd_GetUncompressedLength(const char* input, size_t length,
164
0
                                       size_t* result) {
165
#if HAVE_ZSTD
166
  size_t size = ZSTD_getFrameContentSize(input, length);
167
  if (size == 0) return false;
168
  *result = size;
169
  return true;
170
#else
171
  // Silence compiler warnings about unused arguments.
172
0
  (void)input;
173
0
  (void)length;
174
0
  (void)result;
175
0
  return false;
176
0
#endif  // HAVE_ZSTD
177
0
}
178
179
0
inline bool Zstd_Uncompress(const char* input, size_t length, char* output) {
180
#if HAVE_ZSTD
181
  size_t outlen;
182
  if (!Zstd_GetUncompressedLength(input, length, &outlen)) {
183
    return false;
184
  }
185
  ZSTD_DCtx* ctx = ZSTD_createDCtx();
186
  outlen = ZSTD_decompressDCtx(ctx, output, outlen, input, length);
187
  ZSTD_freeDCtx(ctx);
188
  if (ZSTD_isError(outlen)) {
189
    return false;
190
  }
191
  return true;
192
#else
193
  // Silence compiler warnings about unused arguments.
194
0
  (void)input;
195
0
  (void)length;
196
0
  (void)output;
197
0
  return false;
198
0
#endif  // HAVE_ZSTD
199
0
}
200
201
0
inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
202
0
  // Silence compiler warnings about unused arguments.
203
0
  (void)func;
204
0
  (void)arg;
205
0
  return false;
206
0
}
207
208
1
inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) {
209
#if HAVE_CRC32C
210
  return ::crc32c::Extend(crc, reinterpret_cast<const uint8_t*>(buf), size);
211
#else
212
  // Silence compiler warnings about unused arguments.
213
1
  (void)crc;
214
1
  (void)buf;
215
1
  (void)size;
216
1
  return 0;
217
1
#endif  // HAVE_CRC32C
218
1
}
219
220
}  // namespace port
221
}  // namespace leveldb
222
223
#endif  // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_