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
32#include <cassert>
33#include <condition_variable> // NOLINT
34#include <cstddef>
35#include <cstdint>
36#include <mutex> // NOLINT
37#include <string>
38
39#include "port/thread_annotations.h"
40
41namespace leveldb {
42namespace port {
43
44class CondVar;
45
46// Thinly wraps std::mutex.
47class LOCKABLE Mutex {
48 public:
49 Mutex() = default;
50 ~Mutex() = default;
51
52 Mutex(const Mutex&) = delete;
53 Mutex& operator=(const Mutex&) = delete;
54
55 void Lock() EXCLUSIVE_LOCK_FUNCTION() { mu_.lock(); }
56 void Unlock() UNLOCK_FUNCTION() { mu_.unlock(); }
57 void AssertHeld() ASSERT_EXCLUSIVE_LOCK() {}
58
59 private:
60 friend class CondVar;
61 std::mutex mu_;
62};
63
64// Thinly wraps std::condition_variable.
65class CondVar {
66 public:
67 explicit CondVar(Mutex* mu) : mu_(mu) { assert(mu != nullptr); }
68 ~CondVar() = default;
69
70 CondVar(const CondVar&) = delete;
71 CondVar& operator=(const CondVar&) = delete;
72
73 void Wait() {
74 std::unique_lock<std::mutex> lock(mu_->mu_, std::adopt_lock);
75 cv_.wait(lock);
76 lock.release();
77 }
78 void Signal() { cv_.notify_one(); }
79 void SignalAll() { cv_.notify_all(); }
80
81 private:
82 std::condition_variable cv_;
83 Mutex* const mu_;
84};
85
86inline bool Snappy_Compress(const char* input, size_t length,
87 std::string* output) {
88#if HAVE_SNAPPY
89 output->resize(snappy::MaxCompressedLength(length));
90 size_t outlen;
91 snappy::RawCompress(input, length, &(*output)[0], &outlen);
92 output->resize(outlen);
93 return true;
94#else
95 // Silence compiler warnings about unused arguments.
96 (void)input;
97 (void)length;
98 (void)output;
99#endif // HAVE_SNAPPY
100
101 return false;
102}
103
104inline bool Snappy_GetUncompressedLength(const char* input, size_t length,
105 size_t* result) {
106#if HAVE_SNAPPY
107 return snappy::GetUncompressedLength(input, length, result);
108#else
109 // Silence compiler warnings about unused arguments.
110 (void)input;
111 (void)length;
112 (void)result;
113 return false;
114#endif // HAVE_SNAPPY
115}
116
117inline bool Snappy_Uncompress(const char* input, size_t length, char* output) {
118#if HAVE_SNAPPY
119 return snappy::RawUncompress(input, length, output);
120#else
121 // Silence compiler warnings about unused arguments.
122 (void)input;
123 (void)length;
124 (void)output;
125 return false;
126#endif // HAVE_SNAPPY
127}
128
129inline bool GetHeapProfile(void (*func)(void*, const char*, int), void* arg) {
130 // Silence compiler warnings about unused arguments.
131 (void)func;
132 (void)arg;
133 return false;
134}
135
136inline uint32_t AcceleratedCRC32C(uint32_t crc, const char* buf, size_t size) {
137#if HAVE_CRC32C
138 return ::crc32c::Extend(crc, reinterpret_cast<const uint8_t*>(buf), size);
139#else
140 // Silence compiler warnings about unused arguments.
141 (void)crc;
142 (void)buf;
143 (void)size;
144 return 0;
145#endif // HAVE_CRC32C
146}
147
148} // namespace port
149} // namespace leveldb
150
151#endif // STORAGE_LEVELDB_PORT_PORT_STDCXX_H_
152