You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

223 lines
5.6 KiB

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