/Users/deen/code/yugabyte-db/src/yb/util/ref_cnt_buffer.h
Line | Count | Source (jump to first uncovered line) |
1 | | // |
2 | | // Copyright (c) YugaByte, Inc. |
3 | | // |
4 | | // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except |
5 | | // in compliance with the License. You may obtain a copy of the License at |
6 | | // |
7 | | // http://www.apache.org/licenses/LICENSE-2.0 |
8 | | // |
9 | | // Unless required by applicable law or agreed to in writing, software distributed under the License |
10 | | // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express |
11 | | // or implied. See the License for the specific language governing permissions and limitations |
12 | | // under the License. |
13 | | // |
14 | | // |
15 | | |
16 | | #ifndef YB_UTIL_REF_CNT_BUFFER_H |
17 | | #define YB_UTIL_REF_CNT_BUFFER_H |
18 | | |
19 | | #include <stdlib.h> |
20 | | #include <string.h> |
21 | | |
22 | | #include <atomic> |
23 | | #include <string> |
24 | | |
25 | | #include "yb/util/slice.h" |
26 | | |
27 | | namespace yb { |
28 | | |
29 | | class faststring; |
30 | | |
31 | | // Byte buffer with reference counting. It embeds reference count, size and data in a single block. |
32 | | class RefCntBuffer { |
33 | | public: |
34 | | RefCntBuffer(); |
35 | | explicit RefCntBuffer(size_t size); |
36 | | RefCntBuffer(const char *data, size_t size); |
37 | | |
38 | | RefCntBuffer(const char *data, const char *end) |
39 | 0 | : RefCntBuffer(data, end - data) {} |
40 | | |
41 | | RefCntBuffer(const uint8_t *data, size_t size) |
42 | 43.0M | : RefCntBuffer(static_cast<const char*>(static_cast<const void*>(data)), size) {} Unexecuted instantiation: yb::RefCntBuffer::RefCntBuffer(unsigned char const*, unsigned long) yb::RefCntBuffer::RefCntBuffer(unsigned char const*, unsigned long) Line | Count | Source | 42 | 43.0M | : RefCntBuffer(static_cast<const char*>(static_cast<const void*>(data)), size) {} |
|
43 | | |
44 | | explicit RefCntBuffer(const std::string& str) : |
45 | 4.69M | RefCntBuffer(str.c_str(), str.length()) {} Unexecuted instantiation: yb::RefCntBuffer::RefCntBuffer(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) yb::RefCntBuffer::RefCntBuffer(std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&) Line | Count | Source | 45 | 4.69M | RefCntBuffer(str.c_str(), str.length()) {} |
|
46 | | |
47 | | explicit RefCntBuffer(const faststring& str); |
48 | | |
49 | | explicit RefCntBuffer(const Slice& slice) : |
50 | 33.9M | RefCntBuffer(slice.data(), slice.size()) {} Unexecuted instantiation: yb::RefCntBuffer::RefCntBuffer(yb::Slice const&) yb::RefCntBuffer::RefCntBuffer(yb::Slice const&) Line | Count | Source | 50 | 33.9M | RefCntBuffer(slice.data(), slice.size()) {} |
|
51 | | |
52 | | RefCntBuffer(const RefCntBuffer& rhs) noexcept; |
53 | | RefCntBuffer(RefCntBuffer&& rhs) noexcept; |
54 | | |
55 | | void operator=(const RefCntBuffer& rhs) noexcept; |
56 | | void operator=(RefCntBuffer&& rhs) noexcept; |
57 | | |
58 | | ~RefCntBuffer(); |
59 | | |
60 | 2.39G | size_t size() const { |
61 | 2.39G | return size_reference(); |
62 | 2.39G | } |
63 | | |
64 | 235M | size_t DynamicMemoryUsage() const { return data_ ? GetInternalBufSize(size())82.6M : 0152M ; } |
65 | | |
66 | 153M | bool empty() const { |
67 | 153M | return size() == 0; |
68 | 153M | } |
69 | | |
70 | 2.93G | char* data() const { |
71 | 2.93G | return data_ + sizeof(CounterType) + sizeof(size_t); |
72 | 2.93G | } |
73 | | |
74 | 81.8M | char* begin() const { |
75 | 81.8M | return data(); |
76 | 81.8M | } |
77 | | |
78 | 56.3k | char* end() const { |
79 | 56.3k | return begin() + size(); |
80 | 56.3k | } |
81 | | |
82 | 606M | uint8_t* udata() const { |
83 | 606M | return static_cast<unsigned char*>(static_cast<void*>(data())); |
84 | 606M | } |
85 | | |
86 | 10.5M | uint8_t* ubegin() const { |
87 | 10.5M | return udata(); |
88 | 10.5M | } |
89 | | |
90 | 10.7M | uint8_t* uend() const { |
91 | 10.7M | return udata() + size(); |
92 | 10.7M | } |
93 | | |
94 | 1.84G | void Reset() { DoReset(nullptr); } |
95 | | |
96 | 28.2M | explicit operator bool() const { |
97 | 28.2M | return data_ != nullptr; |
98 | 28.2M | } |
99 | | |
100 | 158M | bool operator!() const { |
101 | 158M | return data_ == nullptr; |
102 | 158M | } |
103 | | |
104 | 6.37k | std::string ToBuffer() const { |
105 | 6.37k | return std::string(begin(), end()); |
106 | 6.37k | } |
107 | | |
108 | 3.40M | Slice AsSlice() const { |
109 | 3.40M | return Slice(data(), size()); |
110 | 3.40M | } |
111 | | |
112 | 25 | Slice as_slice() const __attribute__ ((deprecated)) { |
113 | 25 | return Slice(data(), size()); |
114 | 25 | } |
115 | | |
116 | 4.56M | void Shrink(size_t new_size) { |
117 | 4.56M | size_reference() = new_size; |
118 | 4.56M | } |
119 | | |
120 | | private: |
121 | | void DoReset(char* data); |
122 | | |
123 | | static size_t GetInternalBufSize(size_t data_size); |
124 | | |
125 | | // Using ptrdiff_t since it matches register size and is signed. |
126 | | typedef std::atomic<std::ptrdiff_t> CounterType; |
127 | | |
128 | 2.77G | size_t& size_reference() const { |
129 | 2.77G | return *static_cast<size_t*>(static_cast<void*>(data_ + sizeof(CounterType))); |
130 | 2.77G | } |
131 | | |
132 | 2.23G | CounterType& counter_reference() const { |
133 | 2.23G | return *static_cast<CounterType*>(static_cast<void*>(data_)); |
134 | 2.23G | } |
135 | | |
136 | | char *data_; |
137 | | }; |
138 | | |
139 | | struct RefCntBufferHash { |
140 | 0 | size_t operator()(const RefCntBuffer& inp) const { |
141 | 0 | return inp.as_slice().hash(); |
142 | 0 | } |
143 | | }; |
144 | | |
145 | | class RefCntPrefix { |
146 | | public: |
147 | 22.1M | RefCntPrefix() : size_(0) {} |
148 | | |
149 | | explicit RefCntPrefix(const std::string& str) |
150 | | : bytes_(RefCntBuffer(str)), size_(bytes_.size()) {} |
151 | | |
152 | | explicit RefCntPrefix(const Slice& slice) |
153 | 23.3M | : bytes_(RefCntBuffer(slice)), size_(bytes_.size()) {} |
154 | | |
155 | | RefCntPrefix(RefCntBuffer bytes) // NOLINT |
156 | 28.1M | : bytes_(std::move(bytes)), size_(bytes_.size()) {} |
157 | | |
158 | | RefCntPrefix(RefCntBuffer bytes, size_t size) |
159 | 0 | : bytes_(std::move(bytes)), size_(size) {} |
160 | | |
161 | | RefCntPrefix(const RefCntPrefix& doc_key, size_t size) |
162 | 0 | : bytes_(doc_key.bytes_), size_(size) {} |
163 | | |
164 | 28.1M | explicit operator bool() const { |
165 | 28.1M | return static_cast<bool>(bytes_); |
166 | 28.1M | } |
167 | | |
168 | | void Resize(size_t value); |
169 | | |
170 | 219M | Slice as_slice() const { |
171 | 219M | return Slice(bytes_.data(), size_); |
172 | 219M | } |
173 | | |
174 | 309M | const char* data() const { |
175 | 309M | return bytes_.data(); |
176 | 309M | } |
177 | | |
178 | 83.7M | size_t size() const { |
179 | 83.7M | return size_; |
180 | 83.7M | } |
181 | | |
182 | 560M | int Compare(const RefCntPrefix& rhs) const { |
183 | 560M | auto my_size = size_; |
184 | 560M | auto rhs_size = rhs.size_; |
185 | 560M | const size_t min_len = std::min(my_size, rhs_size); |
186 | 560M | int r = strings::fastmemcmp_inlined(bytes_.data(), rhs.bytes_.data(), min_len); |
187 | 560M | if (r == 0) { |
188 | 194M | if (my_size < rhs_size) { return -1; }70.1M |
189 | 124M | if (my_size > rhs_size) { return 1; }61.2M |
190 | 124M | } |
191 | 429M | return r; |
192 | 560M | } |
193 | | |
194 | | std::string ShortDebugString() const; |
195 | | |
196 | | private: |
197 | | RefCntBuffer bytes_; |
198 | | size_t size_; |
199 | | |
200 | 560M | friend inline bool operator<(const RefCntPrefix& lhs, const RefCntPrefix& rhs) { |
201 | 560M | return lhs.Compare(rhs) < 0; |
202 | 560M | } |
203 | | |
204 | 127M | friend inline bool operator==(const RefCntPrefix& lhs, const RefCntPrefix& rhs) { |
205 | 127M | return lhs.size_ == rhs.size_ && strings::memeq(lhs.data(), rhs.data(), lhs.size_)80.9M ; |
206 | 127M | } |
207 | | }; |
208 | | |
209 | | struct RefCntPrefixHash { |
210 | 95.2M | size_t operator()(const RefCntPrefix& inp) const { |
211 | 95.2M | return inp.as_slice().hash(); |
212 | 95.2M | } |
213 | | }; |
214 | | |
215 | | } // namespace yb |
216 | | |
217 | | #endif // YB_UTIL_REF_CNT_BUFFER_H |