contrib/faiss/faiss/impl/maybe_owned_vector.h
Line | Count | Source |
1 | | /* |
2 | | * Copyright (c) Meta Platforms, Inc. and affiliates. |
3 | | * |
4 | | * This source code is licensed under the MIT license found in the |
5 | | * LICENSE file in the root directory of this source tree. |
6 | | */ |
7 | | #pragma once |
8 | | |
9 | | #include <cstddef> |
10 | | #include <cstdint> |
11 | | #include <cstring> |
12 | | #include <memory> |
13 | | #include <vector> |
14 | | |
15 | | #include <faiss/impl/FaissAssert.h> |
16 | | |
17 | | namespace faiss { |
18 | | |
19 | | // An interface for an owner of a MaybeOwnedVector. |
20 | | struct MaybeOwnedVectorOwner { |
21 | 0 | virtual ~MaybeOwnedVectorOwner() = default; |
22 | | }; |
23 | | |
24 | | // a container that either works as std::vector<T> that owns its own memory, |
25 | | // or as a view of a memory buffer, with a known size |
26 | | template <typename T> |
27 | | struct MaybeOwnedVector { |
28 | | using value_type = T; |
29 | | using self_type = MaybeOwnedVector<T>; |
30 | | using iterator = typename std::vector<T>::iterator; |
31 | | using const_iterator = typename std::vector<T>::const_iterator; |
32 | | using size_type = typename std::vector<T>::size_type; |
33 | | |
34 | | bool is_owned = true; |
35 | | |
36 | | // this one is used if is_owned == true |
37 | | std::vector<T> owned_data; |
38 | | |
39 | | // these three are used if is_owned == false |
40 | | T* view_data = nullptr; |
41 | | // the number of T elements |
42 | | size_t view_size = 0; |
43 | | // who owns the data. |
44 | | // This field can be nullptr, and it is present ONLY in order |
45 | | // to avoid possible tricky memory / resource leaks. |
46 | | std::shared_ptr<MaybeOwnedVectorOwner> owner; |
47 | | |
48 | | // points either to view_data, or to owned.data() |
49 | | T* c_ptr = nullptr; |
50 | | // uses either view_size, or owned.size(); |
51 | | size_t c_size = 0; |
52 | | |
53 | 4.74k | MaybeOwnedVector() = default; _ZN5faiss16MaybeOwnedVectorIhEC2Ev Line | Count | Source | 53 | 2.39k | MaybeOwnedVector() = default; |
_ZN5faiss16MaybeOwnedVectorIiEC2Ev Line | Count | Source | 53 | 138 | MaybeOwnedVector() = default; |
_ZN5faiss16MaybeOwnedVectorIlEC2Ev Line | Count | Source | 53 | 2.21k | MaybeOwnedVector() = default; |
|
54 | 0 | MaybeOwnedVector(const size_t initial_size) { |
55 | 0 | is_owned = true; |
56 | |
|
57 | 0 | owned_data.resize(initial_size); |
58 | 0 | c_ptr = owned_data.data(); |
59 | 0 | c_size = owned_data.size(); |
60 | 0 | } |
61 | | |
62 | | explicit MaybeOwnedVector(const std::vector<T>& vec) |
63 | | : faiss::MaybeOwnedVector<T>(vec.size()) { |
64 | | if (vec.size() > 0) { |
65 | | memcpy(owned_data.data(), vec.data(), sizeof(T) * vec.size()); |
66 | | } |
67 | | } |
68 | | |
69 | 0 | MaybeOwnedVector(const MaybeOwnedVector& other) { |
70 | 0 | is_owned = other.is_owned; |
71 | 0 | owned_data = other.owned_data; |
72 | |
|
73 | 0 | view_data = other.view_data; |
74 | 0 | view_size = other.view_size; |
75 | 0 | owner = other.owner; |
76 | |
|
77 | 0 | if (is_owned) { |
78 | 0 | c_ptr = owned_data.data(); |
79 | 0 | c_size = owned_data.size(); |
80 | 0 | } else { |
81 | 0 | c_ptr = view_data; |
82 | 0 | c_size = view_size; |
83 | 0 | } |
84 | 0 | } Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIlEC2ERKS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIhEC2ERKS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiEC2ERKS1_ |
85 | | |
86 | 0 | MaybeOwnedVector(MaybeOwnedVector&& other) { |
87 | 0 | is_owned = other.is_owned; |
88 | 0 | owned_data = std::move(other.owned_data); |
89 | |
|
90 | 0 | view_data = other.view_data; |
91 | 0 | view_size = other.view_size; |
92 | 0 | owner = std::move(other.owner); |
93 | 0 | other.owner = nullptr; |
94 | |
|
95 | 0 | if (is_owned) { |
96 | 0 | c_ptr = owned_data.data(); |
97 | 0 | c_size = owned_data.size(); |
98 | 0 | } else { |
99 | 0 | c_ptr = view_data; |
100 | 0 | c_size = view_size; |
101 | 0 | } |
102 | 0 | } Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIhEC2EOS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiEC2EOS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIlEC2EOS1_ |
103 | | |
104 | 0 | MaybeOwnedVector& operator=(const MaybeOwnedVector& other) { |
105 | 0 | if (this == &other) { |
106 | 0 | return *this; |
107 | 0 | } |
108 | | |
109 | | // create a copy |
110 | 0 | MaybeOwnedVector cloned(other); |
111 | | // swap |
112 | 0 | swap(*this, cloned); |
113 | |
|
114 | 0 | return *this; |
115 | 0 | } |
116 | | |
117 | 0 | MaybeOwnedVector& operator=(MaybeOwnedVector&& other) { |
118 | 0 | if (this == &other) { |
119 | 0 | return *this; |
120 | 0 | } |
121 | | |
122 | | // moved |
123 | 0 | MaybeOwnedVector moved(std::move(other)); |
124 | | // swap |
125 | 0 | swap(*this, moved); |
126 | |
|
127 | 0 | return *this; |
128 | 0 | } Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIhEaSEOS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiEaSEOS1_ Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIlEaSEOS1_ |
129 | | |
130 | 0 | MaybeOwnedVector(std::vector<T>&& other) { |
131 | 0 | is_owned = true; |
132 | |
|
133 | 0 | owned_data = std::move(other); |
134 | 0 | c_ptr = owned_data.data(); |
135 | 0 | c_size = owned_data.size(); |
136 | 0 | } Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiEC2EOSt6vectorIiSaIiEE Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIlEC2EOSt6vectorIlSaIlEE |
137 | | |
138 | | static MaybeOwnedVector create_view( |
139 | | void* address, |
140 | | const size_t n_elements, |
141 | 0 | const std::shared_ptr<MaybeOwnedVectorOwner>& owner) { |
142 | 0 | MaybeOwnedVector vec; |
143 | 0 | vec.is_owned = false; |
144 | 0 | vec.view_data = reinterpret_cast<T*>(address); |
145 | 0 | vec.view_size = n_elements; |
146 | 0 | vec.owner = owner; |
147 | |
|
148 | 0 | vec.c_ptr = vec.view_data; |
149 | 0 | vec.c_size = vec.view_size; |
150 | |
|
151 | 0 | return vec; |
152 | 0 | } Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIhE11create_viewEPvmRKSt10shared_ptrINS_21MaybeOwnedVectorOwnerEE Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIlE11create_viewEPvmRKSt10shared_ptrINS_21MaybeOwnedVectorOwnerEE Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiE11create_viewEPvmRKSt10shared_ptrINS_21MaybeOwnedVectorOwnerEE |
153 | | |
154 | 40.4k | const T* data() const { |
155 | 40.4k | return c_ptr; |
156 | 40.4k | } _ZNK5faiss16MaybeOwnedVectorIhE4dataEv Line | Count | Source | 154 | 40.2k | const T* data() const { | 155 | 40.2k | return c_ptr; | 156 | 40.2k | } |
_ZNK5faiss16MaybeOwnedVectorIlE4dataEv Line | Count | Source | 154 | 134 | const T* data() const { | 155 | 134 | return c_ptr; | 156 | 134 | } |
_ZNK5faiss16MaybeOwnedVectorIiE4dataEv Line | Count | Source | 154 | 25 | const T* data() const { | 155 | 25 | return c_ptr; | 156 | 25 | } |
|
157 | | |
158 | 18.3k | T* data() { |
159 | 18.3k | return c_ptr; |
160 | 18.3k | } _ZN5faiss16MaybeOwnedVectorIhE4dataEv Line | Count | Source | 158 | 18.3k | T* data() { | 159 | 18.3k | return c_ptr; | 160 | 18.3k | } |
_ZN5faiss16MaybeOwnedVectorIlE4dataEv Line | Count | Source | 158 | 12 | T* data() { | 159 | 12 | return c_ptr; | 160 | 12 | } |
_ZN5faiss16MaybeOwnedVectorIiE4dataEv Line | Count | Source | 158 | 20 | T* data() { | 159 | 20 | return c_ptr; | 160 | 20 | } |
|
161 | | |
162 | 3.93k | size_t size() const { |
163 | 3.93k | return c_size; |
164 | 3.93k | } _ZNK5faiss16MaybeOwnedVectorIhE4sizeEv Line | Count | Source | 162 | 79 | size_t size() const { | 163 | 79 | return c_size; | 164 | 79 | } |
_ZNK5faiss16MaybeOwnedVectorIiE4sizeEv Line | Count | Source | 162 | 25 | size_t size() const { | 163 | 25 | return c_size; | 164 | 25 | } |
_ZNK5faiss16MaybeOwnedVectorIlE4sizeEv Line | Count | Source | 162 | 3.83k | size_t size() const { | 163 | 3.83k | return c_size; | 164 | 3.83k | } |
|
165 | | |
166 | | size_t byte_size() const { |
167 | | return c_size * sizeof(T); |
168 | | } |
169 | | |
170 | 72.4M | T& operator[](const size_t idx) { |
171 | 72.4M | return c_ptr[idx]; |
172 | 72.4M | } _ZN5faiss16MaybeOwnedVectorIhEixEm Line | Count | Source | 170 | 3.58k | T& operator[](const size_t idx) { | 171 | 3.58k | return c_ptr[idx]; | 172 | 3.58k | } |
_ZN5faiss16MaybeOwnedVectorIiEixEm Line | Count | Source | 170 | 72.4M | T& operator[](const size_t idx) { | 171 | 72.4M | return c_ptr[idx]; | 172 | 72.4M | } |
_ZN5faiss16MaybeOwnedVectorIlEixEm Line | Count | Source | 170 | 3.55k | T& operator[](const size_t idx) { | 171 | 3.55k | return c_ptr[idx]; | 172 | 3.55k | } |
|
173 | | |
174 | 668k | const T& operator[](const size_t idx) const { |
175 | 668k | return c_ptr[idx]; |
176 | 668k | } _ZNK5faiss16MaybeOwnedVectorIhEixEm Line | Count | Source | 174 | 498 | const T& operator[](const size_t idx) const { | 175 | 498 | return c_ptr[idx]; | 176 | 498 | } |
_ZNK5faiss16MaybeOwnedVectorIiEixEm Line | Count | Source | 174 | 667k | const T& operator[](const size_t idx) const { | 175 | 667k | return c_ptr[idx]; | 176 | 667k | } |
|
177 | | |
178 | | T& at(size_type pos) { |
179 | | FAISS_ASSERT_MSG( |
180 | | is_owned, |
181 | | "This operation cannot be performed on a viewed vector"); |
182 | | |
183 | | return owned_data.at(pos); |
184 | | } |
185 | | |
186 | | const T& at(size_type pos) const { |
187 | | FAISS_ASSERT_MSG( |
188 | | is_owned, |
189 | | "This operation cannot be performed on a viewed vector"); |
190 | | |
191 | | return owned_data.at(pos); |
192 | | } |
193 | | |
194 | | iterator begin() { |
195 | | FAISS_ASSERT_MSG( |
196 | | is_owned, |
197 | | "This operation cannot be performed on a viewed vector"); |
198 | | |
199 | | return owned_data.begin(); |
200 | | } |
201 | | |
202 | | const_iterator begin() const { |
203 | | FAISS_ASSERT_MSG( |
204 | | is_owned, |
205 | | "This operation cannot be performed on a viewed vector"); |
206 | | |
207 | | return owned_data.begin(); |
208 | | } |
209 | | |
210 | 0 | iterator end() { |
211 | 0 | FAISS_ASSERT_MSG( |
212 | 0 | is_owned, |
213 | 0 | "This operation cannot be performed on a viewed vector"); |
214 | | |
215 | 0 | return owned_data.end(); |
216 | 0 | } |
217 | | |
218 | | const_iterator end() const { |
219 | | FAISS_ASSERT_MSG( |
220 | | is_owned, |
221 | | "This operation cannot be performed on a viewed vector"); |
222 | | |
223 | | return owned_data.end(); |
224 | | } |
225 | | |
226 | | iterator erase(const_iterator begin, const_iterator end) { |
227 | | FAISS_ASSERT_MSG( |
228 | | is_owned, |
229 | | "This operation cannot be performed on a viewed vector"); |
230 | | |
231 | | auto result = owned_data.erase(begin, end); |
232 | | c_ptr = owned_data.data(); |
233 | | c_size = owned_data.size(); |
234 | | |
235 | | return result; |
236 | | } |
237 | | |
238 | | template <class InputIt> |
239 | 0 | iterator insert(const_iterator pos, InputIt first, InputIt last) { |
240 | 0 | FAISS_ASSERT_MSG( |
241 | 0 | is_owned, |
242 | 0 | "This operation cannot be performed on a viewed vector"); |
243 | | |
244 | 0 | auto result = owned_data.insert(pos, first, last); |
245 | 0 | c_ptr = owned_data.data(); |
246 | 0 | c_size = owned_data.size(); |
247 | |
|
248 | 0 | return result; |
249 | 0 | } |
250 | | |
251 | 297 | void clear() { |
252 | 297 | FAISS_ASSERT_MSG( |
253 | 297 | is_owned, |
254 | 297 | "This operation cannot be performed on a viewed vector"); |
255 | | |
256 | 297 | owned_data.clear(); |
257 | 297 | c_ptr = owned_data.data(); |
258 | 297 | c_size = owned_data.size(); |
259 | 297 | } _ZN5faiss16MaybeOwnedVectorIhE5clearEv Line | Count | Source | 251 | 297 | void clear() { | 252 | 297 | FAISS_ASSERT_MSG( | 253 | 297 | is_owned, | 254 | 297 | "This operation cannot be performed on a viewed vector"); | 255 | | | 256 | 297 | owned_data.clear(); | 257 | 297 | c_ptr = owned_data.data(); | 258 | 297 | c_size = owned_data.size(); | 259 | 297 | } |
Unexecuted instantiation: _ZN5faiss16MaybeOwnedVectorIiE5clearEv |
260 | | |
261 | 25.4k | void resize(const size_t new_size) { |
262 | 25.4k | FAISS_ASSERT_MSG( |
263 | 25.4k | is_owned, |
264 | 25.4k | "This operation cannot be performed on a viewed vector"); |
265 | | |
266 | 25.4k | owned_data.resize(new_size); |
267 | 25.4k | c_ptr = owned_data.data(); |
268 | 25.4k | c_size = owned_data.size(); |
269 | 25.4k | } _ZN5faiss16MaybeOwnedVectorIhE6resizeEm Line | Count | Source | 261 | 21.9k | void resize(const size_t new_size) { | 262 | 21.9k | FAISS_ASSERT_MSG( | 263 | 21.9k | is_owned, | 264 | 21.9k | "This operation cannot be performed on a viewed vector"); | 265 | | | 266 | 21.9k | owned_data.resize(new_size); | 267 | 21.9k | c_ptr = owned_data.data(); | 268 | 21.9k | c_size = owned_data.size(); | 269 | 21.9k | } |
_ZN5faiss16MaybeOwnedVectorIlE6resizeEm Line | Count | Source | 261 | 3.49k | void resize(const size_t new_size) { | 262 | 3.49k | FAISS_ASSERT_MSG( | 263 | 3.49k | is_owned, | 264 | 3.49k | "This operation cannot be performed on a viewed vector"); | 265 | | | 266 | 3.49k | owned_data.resize(new_size); | 267 | 3.49k | c_ptr = owned_data.data(); | 268 | 3.49k | c_size = owned_data.size(); | 269 | 3.49k | } |
_ZN5faiss16MaybeOwnedVectorIiE6resizeEm Line | Count | Source | 261 | 20 | void resize(const size_t new_size) { | 262 | 20 | FAISS_ASSERT_MSG( | 263 | 20 | is_owned, | 264 | 20 | "This operation cannot be performed on a viewed vector"); | 265 | | | 266 | 20 | owned_data.resize(new_size); | 267 | 20 | c_ptr = owned_data.data(); | 268 | 20 | c_size = owned_data.size(); | 269 | 20 | } |
|
270 | | |
271 | 18.0k | void resize(const size_t new_size, const value_type v) { |
272 | 18.0k | FAISS_ASSERT_MSG( |
273 | 18.0k | is_owned, |
274 | 18.0k | "This operation cannot be performed on a viewed vector"); |
275 | | |
276 | 18.0k | owned_data.resize(new_size, v); |
277 | 18.0k | c_ptr = owned_data.data(); |
278 | 18.0k | c_size = owned_data.size(); |
279 | 18.0k | } |
280 | | |
281 | 0 | friend void swap(self_type& a, self_type& b) { |
282 | 0 | std::swap(a.is_owned, b.is_owned); |
283 | 0 | std::swap(a.owned_data, b.owned_data); |
284 | 0 | std::swap(a.view_data, b.view_data); |
285 | 0 | std::swap(a.view_size, b.view_size); |
286 | 0 | std::swap(a.owner, b.owner); |
287 | 0 | std::swap(a.c_ptr, b.c_ptr); |
288 | 0 | std::swap(a.c_size, b.c_size); |
289 | 0 | } Unexecuted instantiation: _ZN5faiss4swapERNS_16MaybeOwnedVectorIhEES2_ Unexecuted instantiation: _ZN5faiss4swapERNS_16MaybeOwnedVectorIiEES2_ Unexecuted instantiation: _ZN5faiss4swapERNS_16MaybeOwnedVectorIlEES2_ |
290 | | }; |
291 | | |
292 | | template <typename T> |
293 | | struct is_maybe_owned_vector : std::false_type {}; |
294 | | |
295 | | template <typename T> |
296 | | struct is_maybe_owned_vector<MaybeOwnedVector<T>> : std::true_type {}; |
297 | | |
298 | | template <typename T> |
299 | | inline constexpr bool is_maybe_owned_vector_v = is_maybe_owned_vector<T>::value; |
300 | | |
301 | | template <typename T> |
302 | | bool operator==( |
303 | | const MaybeOwnedVector<T>& lhs, |
304 | | const MaybeOwnedVector<T>& rhs) { |
305 | | return lhs.size() == rhs.size() && |
306 | | !memcmp(lhs.data(), rhs.data(), lhs.byte_size()); |
307 | | } |
308 | | |
309 | | template <typename T> |
310 | | bool operator!=( |
311 | | const MaybeOwnedVector<T>& lhs, |
312 | | const MaybeOwnedVector<T>& rhs) { |
313 | | return !(lhs == rhs); |
314 | | } |
315 | | |
316 | | } // namespace faiss |