1#include "duckdb/common/types/hyperloglog.hpp"
2
3#include "duckdb/common/exception.hpp"
4#include "hyperloglog.hpp"
5
6using namespace duckdb;
7using namespace std;
8
9HyperLogLog::HyperLogLog() : hll(nullptr) {
10 hll = hll_create();
11}
12
13HyperLogLog::HyperLogLog(void *hll) : hll(hll) {
14}
15
16HyperLogLog::~HyperLogLog() {
17 hll_destroy((robj *)hll);
18}
19
20void HyperLogLog::Add(data_ptr_t element, idx_t size) {
21 if (hll_add((robj *)hll, element, size) == C_ERR) {
22 throw Exception("Could not add to HLL?");
23 }
24}
25
26idx_t HyperLogLog::Count() {
27 size_t result; // exception from size_t ban
28 if (hll_count((robj *)hll, &result) != C_OK) {
29 throw Exception("Could not count HLL?");
30 }
31 return result;
32}
33
34unique_ptr<HyperLogLog> HyperLogLog::Merge(HyperLogLog &other) {
35 robj *hlls[2];
36 hlls[0] = (robj *)hll;
37 hlls[1] = (robj *)other.hll;
38 auto new_hll = hll_merge(hlls, 2);
39 if (!new_hll) {
40 throw Exception("Could not merge HLLs");
41 }
42 return unique_ptr<HyperLogLog>(new HyperLogLog((void *)new_hll));
43}
44
45unique_ptr<HyperLogLog> HyperLogLog::Merge(HyperLogLog logs[], idx_t count) {
46 auto hlls_uptr = unique_ptr<robj *[]> { new robj *[count] };
47 auto hlls = hlls_uptr.get();
48 for (idx_t i = 0; i < count; i++) {
49 hlls[i] = (robj *)logs[i].hll;
50 }
51 auto new_hll = hll_merge(hlls, count);
52 if (!new_hll) {
53 throw Exception("Could not merge HLLs");
54 }
55 return unique_ptr<HyperLogLog>(new HyperLogLog((void *)new_hll));
56}
57