simple arrayo of doubles instead of std::vector
diff --git a/tuple/include/array_of_doubles_intersection.hpp b/tuple/include/array_of_doubles_intersection.hpp
index 008d9d6..89459c3 100644
--- a/tuple/include/array_of_doubles_intersection.hpp
+++ b/tuple/include/array_of_doubles_intersection.hpp
@@ -32,10 +32,10 @@
typename Policy,
typename Allocator = std::allocator<double>
>
-class array_of_doubles_intersection: public tuple_intersection<std::vector<double, Allocator>, Policy, AllocVectorDouble<Allocator>> {
+class array_of_doubles_intersection: public tuple_intersection<aod<Allocator>, Policy, AllocAOD<Allocator>> {
public:
- using Summary = std::vector<double, Allocator>;
- using AllocSummary = AllocVectorDouble<Allocator>;
+ using Summary = aod<Allocator>;
+ using AllocSummary = AllocAOD<Allocator>;
using Base = tuple_intersection<Summary, Policy, AllocSummary>;
using CompactSketch = compact_array_of_doubles_sketch_alloc<Allocator>;
using resize_factor = theta_constants::resize_factor;
diff --git a/tuple/include/array_of_doubles_sketch.hpp b/tuple/include/array_of_doubles_sketch.hpp
index a3c26d1..af9e87a 100644
--- a/tuple/include/array_of_doubles_sketch.hpp
+++ b/tuple/include/array_of_doubles_sketch.hpp
@@ -28,18 +28,71 @@
namespace datasketches {
-// equivalent of ArrayOfDoublesSketch in Java
+// This sketch is equivalent of ArrayOfDoublesSketch in Java
+
+// This simple array of double is faster than std::vector and should be sufficient for this application
+template<typename Allocator = std::allocator<double>>
+class aod {
+public:
+ explicit aod(uint8_t size, const Allocator& allocator = Allocator()):
+ allocator_(allocator), size_(size), array_(allocator_.allocate(size_)) {
+ std::fill(array_, array_ + size_, 0);
+ }
+ aod(const aod& other):
+ allocator_(other.allocator_),
+ size_(other.size_),
+ array_(allocator_.allocate(size_))
+ {
+ std::copy(other.array_, other.array_ + size_, array_);
+ }
+ aod(aod&& other) noexcept:
+ allocator_(std::move(other.allocator_)),
+ size_(other.size_),
+ array_(other.array_)
+ {
+ other.array_ = nullptr;
+ }
+ ~aod() {
+ if (array_ != nullptr) allocator_.deallocate(array_, size_);
+ }
+ aod& operator=(const aod& other) {
+ aod copy(other);
+ std::swap(allocator_, copy.allocator_);
+ std::swap(size_, copy.size_);
+ std::swap(array_, copy.array_);
+ return *this;
+ }
+ aod& operator=(aod&& other) {
+ std::swap(allocator_, other.allocator_);
+ std::swap(size_, other.size_);
+ std::swap(array_, other.array_);
+ return *this;
+ }
+ double& operator[](size_t index) { return array_[index]; }
+ double operator[](size_t index) const { return array_[index]; }
+ uint8_t size() const { return size_; }
+ double* data() { return array_; }
+ const double* data() const { return array_; }
+ bool operator==(const aod& other) const {
+ for (uint8_t i = 0; i < size_; ++i) if (array_[i] != other.array_[i]) return false;
+ return true;
+ }
+private:
+ Allocator allocator_;
+ uint8_t size_;
+ double* array_;
+};
template<typename A = std::allocator<double>>
class array_of_doubles_update_policy {
public:
array_of_doubles_update_policy(uint8_t num_values = 1, const A& allocator = A()):
allocator_(allocator), num_values_(num_values) {}
- std::vector<double, A> create() const {
- return std::vector<double, A>(num_values_, 0, allocator_);
+ aod<A> create() const {
+ return aod<A>(num_values_, allocator_);
}
template<typename InputVector> // to allow any type with indexed access (such as double*)
- void update(std::vector<double, A>& summary, const InputVector& update) const {
+ void update(aod<A>& summary, const InputVector& update) const {
for (uint8_t i = 0; i < num_values_; ++i) summary[i] += update[i];
}
uint8_t get_num_values() const {
@@ -54,13 +107,12 @@
// forward declaration
template<typename A> class compact_array_of_doubles_sketch_alloc;
-template<typename A> using AllocVectorDouble = typename std::allocator_traits<A>::template rebind_alloc<std::vector<double, A>>;
+template<typename A> using AllocAOD = typename std::allocator_traits<A>::template rebind_alloc<aod<A>>;
template<typename A = std::allocator<double>>
-class update_array_of_doubles_sketch_alloc: public update_tuple_sketch<std::vector<double, A>, std::vector<double, A>,
-array_of_doubles_update_policy<A>, AllocVectorDouble<A>> {
+class update_array_of_doubles_sketch_alloc: public update_tuple_sketch<aod<A>, aod<A>, array_of_doubles_update_policy<A>, AllocAOD<A>> {
public:
- using Base = update_tuple_sketch<std::vector<double, A>, std::vector<double, A>, array_of_doubles_update_policy<A>, AllocVectorDouble<A>>;
+ using Base = update_tuple_sketch<aod<A>, aod<A>, array_of_doubles_update_policy<A>, AllocAOD<A>>;
using resize_factor = typename Base::resize_factor;
class builder;
@@ -85,9 +137,9 @@
};
template<typename A = std::allocator<double>>
-class compact_array_of_doubles_sketch_alloc: public compact_tuple_sketch<std::vector<double, A>, AllocVectorDouble<A>> {
+class compact_array_of_doubles_sketch_alloc: public compact_tuple_sketch<aod<A>, AllocAOD<A>> {
public:
- using Base = compact_tuple_sketch<std::vector<double, A>, AllocVectorDouble<A>>;
+ using Base = compact_tuple_sketch<aod<A>, AllocAOD<A>>;
using Entry = typename Base::Entry;
using AllocEntry = typename Base::AllocEntry;
using AllocU64 = typename Base::AllocU64;
diff --git a/tuple/include/array_of_doubles_sketch_impl.hpp b/tuple/include/array_of_doubles_sketch_impl.hpp
index 16fa925..6457072 100644
--- a/tuple/include/array_of_doubles_sketch_impl.hpp
+++ b/tuple/include/array_of_doubles_sketch_impl.hpp
@@ -176,7 +176,7 @@
std::vector<uint64_t, AllocU64> keys(num_entries, 0, allocator);
is.read(reinterpret_cast<char*>(keys.data()), num_entries * sizeof(uint64_t));
for (size_t i = 0; i < num_entries; ++i) {
- std::vector<double, A> summary(num_values, 0, allocator);
+ aod<A> summary(num_values, allocator);
is.read(reinterpret_cast<char*>(summary.data()), num_values * sizeof(double));
entries.push_back(Entry(keys[i], std::move(summary)));
}
@@ -225,7 +225,7 @@
std::vector<uint64_t, AllocU64> keys(num_entries, 0, allocator);
ptr += copy_from_mem(ptr, keys.data(), sizeof(uint64_t) * num_entries);
for (size_t i = 0; i < num_entries; ++i) {
- std::vector<double, A> summary(num_values, 0, allocator);
+ aod<A> summary(num_values, allocator);
ptr += copy_from_mem(ptr, summary.data(), num_values * sizeof(double));
entries.push_back(Entry(keys[i], std::move(summary)));
}
diff --git a/tuple/include/array_of_doubles_union.hpp b/tuple/include/array_of_doubles_union.hpp
index a70a015..592c1f9 100644
--- a/tuple/include/array_of_doubles_union.hpp
+++ b/tuple/include/array_of_doubles_union.hpp
@@ -32,7 +32,7 @@
struct array_of_doubles_union_policy_alloc {
array_of_doubles_union_policy_alloc(uint8_t num_values = 1): num_values_(num_values) {}
- void operator()(std::vector<double, A>& summary, const std::vector<double, A>& other) const {
+ void operator()(aod<A>& summary, const aod<A>& other) const {
for (size_t i = 0; i < summary.size(); ++i) {
summary[i] += other[i];
}
@@ -48,10 +48,10 @@
using array_of_doubles_union_policy = array_of_doubles_union_policy_alloc<>;
template<typename Allocator = std::allocator<double>>
-class array_of_doubles_union_alloc: public tuple_union<std::vector<double, Allocator>, array_of_doubles_union_policy_alloc<Allocator>, AllocVectorDouble<Allocator>> {
+class array_of_doubles_union_alloc: public tuple_union<aod<Allocator>, array_of_doubles_union_policy_alloc<Allocator>, AllocAOD<Allocator>> {
public:
using Policy = array_of_doubles_union_policy_alloc<Allocator>;
- using Base = tuple_union<std::vector<double, Allocator>, Policy, AllocVectorDouble<Allocator>>;
+ using Base = tuple_union<aod<Allocator>, Policy, AllocAOD<Allocator>>;
using CompactSketch = compact_array_of_doubles_sketch_alloc<Allocator>;
using resize_factor = theta_constants::resize_factor;