You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@datasketches.apache.org by al...@apache.org on 2020/07/17 23:57:15 UTC

[incubator-datasketches-cpp] branch tuple_sketch updated: copy and move

This is an automated email from the ASF dual-hosted git repository.

alsay pushed a commit to branch tuple_sketch
in repository https://gitbox.apache.org/repos/asf/incubator-datasketches-cpp.git


The following commit(s) were added to refs/heads/tuple_sketch by this push:
     new 5b07fe6  copy and move
5b07fe6 is described below

commit 5b07fe69e3f1aed88c6a90273bf8a74c15a9fe04
Author: AlexanderSaydakov <Al...@users.noreply.github.com>
AuthorDate: Fri Jul 17 16:57:00 2020 -0700

    copy and move
---
 common/test/test_allocator.hpp                  |  6 +-
 tuple/include/theta_update_sketch_base.hpp      |  5 +-
 tuple/include/theta_update_sketch_base_impl.hpp | 79 +++++++++++++++++++++++--
 tuple/include/tuple_sketch.hpp                  |  8 +++
 tuple/test/tuple_sketch_allocation_test.cpp     | 17 +++++-
 5 files changed, 106 insertions(+), 9 deletions(-)

diff --git a/common/test/test_allocator.hpp b/common/test/test_allocator.hpp
index 8b5481b..b383af6 100644
--- a/common/test/test_allocator.hpp
+++ b/common/test/test_allocator.hpp
@@ -47,7 +47,10 @@ public:
   test_allocator(const test_allocator&) {}
   template <class U>
   test_allocator(const test_allocator<U>&) {}
+  test_allocator(test_allocator&&) {}
   ~test_allocator() {}
+  test_allocator& operator=(const test_allocator&) { return *this; }
+  test_allocator& operator=(test_allocator&&) { return *this; }
 
   pointer address(reference x) const { return &x; }
   const_pointer address(const_reference x) const {
@@ -77,9 +80,6 @@ public:
     new(p) value_type(std::forward<Args>(args)...);
   }
   void destroy(pointer p) { p->~value_type(); }
-
-private:
-  void operator=(const test_allocator&);
 };
 
 template<> class test_allocator<void> {
diff --git a/tuple/include/theta_update_sketch_base.hpp b/tuple/include/theta_update_sketch_base.hpp
index 70e3fe5..0da68c5 100644
--- a/tuple/include/theta_update_sketch_base.hpp
+++ b/tuple/include/theta_update_sketch_base.hpp
@@ -45,8 +45,11 @@ struct theta_update_sketch_base {
 
   theta_update_sketch_base(uint8_t lg_cur_size, uint8_t lg_nom_size, resize_factor rf, float p,
       uint64_t seed, const Allocator& allocator);
-  // TODO: copy and move
+  theta_update_sketch_base(const theta_update_sketch_base& other);
+  theta_update_sketch_base(theta_update_sketch_base&& other) noexcept;
   ~theta_update_sketch_base();
+  theta_update_sketch_base& operator=(const theta_update_sketch_base& other);
+  theta_update_sketch_base& operator=(theta_update_sketch_base&& other);
 
   using iterator = Entry*;
 
diff --git a/tuple/include/theta_update_sketch_base_impl.hpp b/tuple/include/theta_update_sketch_base_impl.hpp
index 01a1bcb..9fbf6f0 100644
--- a/tuple/include/theta_update_sketch_base_impl.hpp
+++ b/tuple/include/theta_update_sketch_base_impl.hpp
@@ -42,13 +42,84 @@ entries_(nullptr)
 }
 
 template<typename EN, typename EK, typename A>
+theta_update_sketch_base<EN, EK, A>::theta_update_sketch_base(const theta_update_sketch_base& other):
+allocator_(other.allocator_),
+is_empty_(other.is_empty_),
+lg_cur_size_(other.lg_cur_size_),
+lg_nom_size_(other.lg_nom_size_),
+rf_(other.rf_),
+num_entries_(other.num_entries_),
+theta_(other.theta_),
+seed_(other.seed_),
+entries_(nullptr)
+{
+  if (other.entries_ != nullptr) {
+    const size_t size = 1 << lg_cur_size_;
+    entries_ = allocator_.allocate(size);
+    for (size_t i = 0; i < size; ++i) {
+      if (EK()(other.entries_[i]) != 0) {
+        entries_[i] = other.entries_[i];
+      } else {
+        EK()(entries_[i]) = 0;
+      }
+    }
+  }
+}
+
+template<typename EN, typename EK, typename A>
+theta_update_sketch_base<EN, EK, A>::theta_update_sketch_base(theta_update_sketch_base&& other) noexcept:
+allocator_(other.allocator_),
+is_empty_(other.is_empty_),
+lg_cur_size_(other.lg_cur_size_),
+lg_nom_size_(other.lg_nom_size_),
+rf_(other.rf_),
+num_entries_(other.num_entries_),
+theta_(other.theta_),
+seed_(other.seed_),
+entries_(other.entries_)
+{
+  other.entries_ = nullptr;
+}
+
+template<typename EN, typename EK, typename A>
 theta_update_sketch_base<EN, EK, A>::~theta_update_sketch_base()
 {
-  const size_t size = 1 << lg_cur_size_;
-  for (size_t i = 0; i < size; ++i) {
-    if (EK()(entries_[i]) != 0) entries_[i].~EN();
+  if (entries_ != nullptr) {
+    const size_t size = 1 << lg_cur_size_;
+    for (size_t i = 0; i < size; ++i) {
+      if (EK()(entries_[i]) != 0) entries_[i].~EN();
+    }
+    allocator_.deallocate(entries_, size);
   }
-  allocator_.deallocate(entries_, size);
+}
+
+template<typename EN, typename EK, typename A>
+theta_update_sketch_base<EN, EK, A>& theta_update_sketch_base<EN, EK, A>::operator=(const theta_update_sketch_base& other) {
+  theta_update_sketch_base<EN, EK, A> copy(other);
+  std::swap(allocator_, copy.allocator_);
+  std::swap(is_empty_, copy.is_empty_);
+  std::swap(lg_cur_size_, copy.lg_cur_size_);
+  std::swap(lg_nom_size_, copy.lg_nom_size_);
+  std::swap(rf_, copy.rf_);
+  std::swap(num_entries_, copy.num_entries_);
+  std::swap(theta_, copy.theta_);
+  std::swap(seed_, copy.seed_);
+  std::swap(entries_, copy.entries_);
+  return *this;
+}
+
+template<typename EN, typename EK, typename A>
+theta_update_sketch_base<EN, EK, A>& theta_update_sketch_base<EN, EK, A>::operator=(theta_update_sketch_base&& other) {
+  std::swap(allocator_, other.allocator_);
+  std::swap(is_empty_, other.is_empty_);
+  std::swap(lg_cur_size_, other.lg_cur_size_);
+  std::swap(lg_nom_size_, other.lg_nom_size_);
+  std::swap(rf_, other.rf_);
+  std::swap(num_entries_, other.num_entries_);
+  std::swap(theta_, other.theta_);
+  std::swap(seed_, other.seed_);
+  std::swap(entries_, other.entries_);
+  return *this;
 }
 
 template<typename EN, typename EK, typename A>
diff --git a/tuple/include/tuple_sketch.hpp b/tuple/include/tuple_sketch.hpp
index 7ebc9e2..0f22005 100644
--- a/tuple/include/tuple_sketch.hpp
+++ b/tuple/include/tuple_sketch.hpp
@@ -178,7 +178,11 @@ public:
   // No constructor here. Use builder instead.
   class builder;
 
+  update_tuple_sketch(const update_tuple_sketch&) = default;
+  update_tuple_sketch(update_tuple_sketch&&) noexcept = default;
   virtual ~update_tuple_sketch() = default;
+  update_tuple_sketch& operator=(const update_tuple_sketch&) = default;
+  update_tuple_sketch& operator=(update_tuple_sketch&&) = default;
 
   virtual Allocator get_allocator() const;
   virtual bool is_empty() const;
@@ -353,7 +357,11 @@ public:
   // - by deserializing a previously serialized compact sketch
 
   compact_tuple_sketch(const Base& other, bool ordered);
+  compact_tuple_sketch(const compact_tuple_sketch&) = default;
+  compact_tuple_sketch(compact_tuple_sketch&&) noexcept = default;
   virtual ~compact_tuple_sketch() = default;
+  compact_tuple_sketch& operator=(const compact_tuple_sketch&) = default;
+  compact_tuple_sketch& operator=(compact_tuple_sketch&&) = default;
 
   virtual Allocator get_allocator() const;
   virtual bool is_empty() const;
diff --git a/tuple/test/tuple_sketch_allocation_test.cpp b/tuple/test/tuple_sketch_allocation_test.cpp
index e6d62e0..42a1f3e 100644
--- a/tuple/test/tuple_sketch_allocation_test.cpp
+++ b/tuple/test/tuple_sketch_allocation_test.cpp
@@ -27,6 +27,8 @@ namespace datasketches {
 
 using update_tuple_sketch_int_alloc =
     update_tuple_sketch<int, int, default_update_policy<int, int>, test_allocator<int>>;
+using compact_tuple_sketch_int_alloc =
+    compact_tuple_sketch<int, test_allocator<int>>;
 
 TEST_CASE("tuple sketch with test allocator: exact mode", "[tuple_sketch]") {
   test_allocator_total_bytes = 0;
@@ -58,8 +60,21 @@ TEST_CASE("tuple sketch with test allocator: exact mode", "[tuple_sketch]") {
     REQUIRE(count == update_sketch.get_num_retained());
 
     auto bytes = compact_sketch.serialize();
-    auto deserialized_sketch = compact_tuple_sketch<int, test_allocator<int>>::deserialize(bytes.data(), bytes.size());
+    auto deserialized_sketch = compact_tuple_sketch_int_alloc::deserialize(bytes.data(), bytes.size());
     REQUIRE(deserialized_sketch.get_estimate() == compact_sketch.get_estimate());
+
+    // update sketch copy
+    update_tuple_sketch_int_alloc update_sketch_copy(update_sketch);
+    update_sketch_copy = update_sketch;
+    // update sketch move
+    update_tuple_sketch_int_alloc update_sketch_moved(std::move(update_sketch_copy));
+    update_sketch_moved = std::move(update_sketch);
+
+    // compact sketch copy
+    compact_tuple_sketch_int_alloc compact_sketch_copy(compact_sketch);
+    compact_sketch_copy = compact_sketch;
+    compact_tuple_sketch_int_alloc compact_sketch_moved(std::move(compact_sketch_copy));
+    compact_sketch_moved = std::move(compact_sketch);
   }
   REQUIRE(test_allocator_total_bytes == 0);
   REQUIRE(test_allocator_net_allocations == 0);


---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@datasketches.apache.org
For additional commands, e-mail: commits-help@datasketches.apache.org