Skip to content

Commit b4d35cd

Browse files
committed
Add C++ wrapper class in .h file
1 parent 53757f7 commit b4d35cd

File tree

1 file changed

+150
-2
lines changed

1 file changed

+150
-2
lines changed

include/minisketch.h

Lines changed: 150 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -151,6 +151,154 @@ size_t minisketch_compute_max_elements(uint32_t bits, size_t capacity, uint32_t
151151

152152
#ifdef __cplusplus
153153
}
154-
#endif
155154

156-
#endif
155+
#if __cplusplus >= 201103L
156+
#include <memory>
157+
#include <vector>
158+
#if __cplusplus >= 201703L
159+
#include <optional>
160+
#endif // __cplusplus >= 201703L
161+
#include <cassert>
162+
163+
/** Simple RAII C++11 wrapper around the minisketch API. */
164+
class Minisketch
165+
{
166+
struct Deleter
167+
{
168+
void operator()(minisketch* ptr) const
169+
{
170+
minisketch_destroy(ptr);
171+
}
172+
};
173+
174+
std::unique_ptr<minisketch, Deleter> m_minisketch;
175+
176+
public:
177+
/** See minisketch_bits_supported(). */
178+
static bool BitsSupported(uint32_t bits) { return minisketch_bits_supported(bits); }
179+
180+
/** See minisketch_implementation_max(). */
181+
static uint32_t MaxImplementation() { return minisketch_implementation_max(); }
182+
183+
/** See minisketch_compute_capacity(). */
184+
static size_t ComputeCapacity(uint32_t bits, size_t max_elements, uint32_t fpbits) { return minisketch_compute_capacity(bits, max_elements, fpbits); }
185+
186+
/** See minisketch_compute_max_elements(). */
187+
static size_t ComputeMaxElements(uint32_t bits, size_t capacity, uint32_t fpbits) { return minisketch_compute_max_elements(bits, capacity, fpbits); }
188+
189+
/** Construct a clone of the specified sketch. */
190+
Minisketch(const Minisketch& sketch)
191+
{
192+
m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone(sketch.m_minisketch.get()));
193+
}
194+
195+
/** Make this Minisketch a clone of the specified one. */
196+
Minisketch& operator=(const Minisketch& sketch)
197+
{
198+
m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_clone(sketch.m_minisketch.get()));
199+
return *this;
200+
}
201+
202+
Minisketch() = default;
203+
Minisketch(Minisketch&&) = default;
204+
Minisketch& operator=(Minisketch&&) = default;
205+
206+
/** Construct a Minisketch object with the specified parameters. */
207+
Minisketch(uint32_t bits, uint32_t implementation, size_t capacity)
208+
{
209+
m_minisketch = std::unique_ptr<minisketch, Deleter>(minisketch_create(bits, implementation, capacity));
210+
}
211+
212+
/** Create a Minisketch object sufficiently large for the specified number of elements at given fpbits. */
213+
static Minisketch CreateFP(uint32_t bits, uint32_t implementation, size_t max_elements, uint32_t fpbits)
214+
{
215+
return Minisketch(bits, implementation, ComputeCapacity(bits, max_elements, fpbits));
216+
}
217+
218+
/** See minisketch_get_bits(). */
219+
uint32_t GetBits() const { return minisketch_bits(m_minisketch.get()); }
220+
221+
/** See minisketch_get_capacity(). */
222+
size_t GetCapacity() const { return minisketch_capacity(m_minisketch.get()); }
223+
224+
/** See minisketch_get_implementation(). */
225+
uint32_t GetImplementation() const { return minisketch_implementation(m_minisketch.get()); }
226+
227+
/** See minisketch_set_seed(). */
228+
Minisketch& SetSeed(uint64_t seed)
229+
{
230+
minisketch_set_seed(m_minisketch.get(), seed);
231+
return *this;
232+
}
233+
234+
/** See miniksetch_add_element(). */
235+
Minisketch& Add(uint64_t element)
236+
{
237+
minisketch_add_uint64(m_minisketch.get(), element);
238+
return *this;
239+
}
240+
241+
/** See minisketch_merge(). */
242+
Minisketch& Merge(const Minisketch& sketch)
243+
{
244+
minisketch_merge(m_minisketch.get(), sketch.m_minisketch.get());
245+
return *this;
246+
}
247+
248+
/** Decode this sketch into the result vector, which must have a size equal to the maximum allowed elements. */
249+
bool Decode(std::vector<uint64_t>& result) const
250+
{
251+
ssize_t ret = minisketch_decode(m_minisketch.get(), result.size(), result.data());
252+
if (ret == -1) return false;
253+
result.resize(ret);
254+
return true;
255+
}
256+
257+
/** See minisketch_serialized_size(). */
258+
size_t GetSerializedSize() const { return minisketch_serialized_size(m_minisketch.get()); }
259+
260+
/** Serialize the sketch as a byte vector. */
261+
std::vector<unsigned char> Serialize() const
262+
{
263+
std::vector<unsigned char> result(GetSerializedSize());
264+
minisketch_serialize(m_minisketch.get(), result.data());
265+
return result;
266+
}
267+
268+
/** Deserialize into this sketch from an object containing its bytes (which has data() and size() members). */
269+
template<typename T>
270+
Minisketch& Deserialize(
271+
const T& obj,
272+
typename std::enable_if<
273+
std::is_convertible<typename std::remove_pointer<decltype(obj.data())>::type (*)[], const unsigned char (*)[]>::value &&
274+
std::is_convertible<decltype(obj.size()), std::size_t>::value,
275+
std::nullptr_t
276+
>::type = nullptr)
277+
{
278+
assert(GetSerializedSize() == obj.size());
279+
minisketch_deserialize(m_minisketch.get(), obj.data());
280+
return *this;
281+
}
282+
283+
#if __cplusplus >= 201703L
284+
/** C++17 only: decode with a specified number of max elements into an optional vector. */
285+
std::optional<std::vector<uint64_t>> Decode(size_t max_elements) const
286+
{
287+
std::vector<uint64_t> result(max_elements);
288+
ssize_t ret = minisketch_decode(m_minisketch.get(), max_elements, result.data());
289+
if (ret == -1) return {};
290+
result.resize(ret);
291+
return std::move(result);
292+
}
293+
294+
/** C++17 only: decode with a specified fpbits into an optional vector. */
295+
std::optional<std::vector<uint64_t>> DecodeFP(uint32_t fpbits) const
296+
{
297+
return Decode(ComputeMaxElements(GetBits(), GetCapacity(), fpbits));
298+
}
299+
#endif // __cplusplus >= 201703L
300+
};
301+
#endif // __cplusplus >= 201103L
302+
#endif // __cplusplus
303+
304+
#endif // _MINISKETCH_H_

0 commit comments

Comments
 (0)