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 2019/12/20 20:53:01 UTC

[incubator-datasketches-cpp] 01/01: added move constructor and move assignment

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

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

commit 4ae02924465e8075fef41b5b7c3ffef44d59a604
Author: AlexanderSaydakov <Al...@users.noreply.github.com>
AuthorDate: Fri Dec 20 12:52:46 2019 -0800

    added move constructor and move assignment
---
 kll/include/kll_sketch.hpp   | 98 +++++++++++++++++++++++++++++++++-----------
 kll/test/kll_sketch_test.cpp | 20 +++++++++
 2 files changed, 93 insertions(+), 25 deletions(-)

diff --git a/kll/include/kll_sketch.hpp b/kll/include/kll_sketch.hpp
index 280a59f..c450797 100644
--- a/kll/include/kll_sketch.hpp
+++ b/kll/include/kll_sketch.hpp
@@ -167,8 +167,10 @@ class kll_sketch {
 
     explicit kll_sketch(uint16_t k = DEFAULT_K);
     kll_sketch(const kll_sketch& other);
+    kll_sketch(kll_sketch&& other) noexcept;
     ~kll_sketch();
-    kll_sketch& operator=(kll_sketch other);
+    kll_sketch& operator=(const kll_sketch& other);
+    kll_sketch& operator=(kll_sketch&& other);
     void update(const T& value);
     void update(T&& value);
     void merge(const kll_sketch& other);
@@ -371,36 +373,78 @@ kll_sketch<T, C, S, A>::kll_sketch(uint16_t k) {
 }
 
 template<typename T, typename C, typename S, typename A>
-kll_sketch<T, C, S, A>::kll_sketch(const kll_sketch& other) {
-  k_ = other.k_;
-  m_ = other.m_;
-  min_k_ = other.min_k_;
-  n_ = other.n_;
-  num_levels_ = other.num_levels_;
-  levels_size_ = other.levels_size_;
+kll_sketch<T, C, S, A>::kll_sketch(const kll_sketch& other):
+k_(other.k_),
+m_(other.m_),
+min_k_(other.min_k_),
+n_(other.n_),
+num_levels_(other.num_levels_),
+levels_(nullptr),
+levels_size_(other.levels_size_),
+items_(nullptr),
+items_size_(other.items_size_),
+min_value_(nullptr),
+max_value_(nullptr),
+is_level_zero_sorted_(other.is_level_zero_sorted_)
+{
   levels_ = AllocU32().allocate(levels_size_);
   std::copy(&other.levels_[0], &other.levels_[levels_size_], levels_);
-  items_size_ = other.items_size_;
   items_ = A().allocate(items_size_);
   std::copy(other.items_, &other.items_[items_size_], items_);
-  min_value_ = A().allocate(1);
-  max_value_ = A().allocate(1);
-  new (min_value_) T(*other.min_value_);
-  new (max_value_) T(*other.max_value_);
-  is_level_zero_sorted_ = other.is_level_zero_sorted_;
+  min_value_ = new (A().allocate(1)) T(*other.min_value_);
+  max_value_ = new (A().allocate(1)) T(*other.max_value_);
+}
+
+template<typename T, typename C, typename S, typename A>
+kll_sketch<T, C, S, A>::kll_sketch(kll_sketch&& other) noexcept:
+k_(other.k_),
+m_(other.m_),
+min_k_(other.min_k_),
+n_(other.n_),
+num_levels_(other.num_levels_),
+levels_(other.levels_),
+levels_size_(other.levels_size_),
+items_(other.items_),
+items_size_(other.items_size_),
+min_value_(other.min_value_),
+max_value_(other.max_value_),
+is_level_zero_sorted_(other.is_level_zero_sorted_)
+{
+  other.levels_ = nullptr;
+  other.items_ = nullptr;
+  other.min_value_ = nullptr;
+  other.max_value_ = nullptr;
+}
+
+template<typename T, typename C, typename S, typename A>
+kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(const kll_sketch& other) {
+  kll_sketch<T, C, S, A> copy(other);
+  std::swap(k_, copy.k_);
+  std::swap(m_, copy.m_);
+  std::swap(min_k_, copy.min_k_);
+  std::swap(n_, copy.n_);
+  std::swap(num_levels_, copy.num_levels_);
+  std::swap(levels_, copy.levels_);
+  std::swap(levels_size_, copy.levels_size_);
+  std::swap(items_, copy.items_);
+  std::swap(items_size_, copy.items_size_);
+  std::swap(min_value_, copy.min_value_);
+  std::swap(max_value_, copy.max_value_);
+  std::swap(is_level_zero_sorted_, copy.is_level_zero_sorted_);
+  return *this;
 }
 
 template<typename T, typename C, typename S, typename A>
-kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(kll_sketch other) {
+kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(kll_sketch&& other) {
   std::swap(k_, other.k_);
   std::swap(m_, other.m_);
   std::swap(min_k_, other.min_k_);
   std::swap(n_, other.n_);
   std::swap(num_levels_, other.num_levels_);
-  std::swap(levels_size_, other.levels_size_);
   std::swap(levels_, other.levels_);
-  std::swap(items_size_, other.items_size_);
+  std::swap(levels_size_, other.levels_size_);
   std::swap(items_, other.items_);
+  std::swap(items_size_, other.items_size_);
   std::swap(min_value_, other.min_value_);
   std::swap(max_value_, other.max_value_);
   std::swap(is_level_zero_sorted_, other.is_level_zero_sorted_);
@@ -409,17 +453,21 @@ kll_sketch<T, C, S, A>& kll_sketch<T, C, S, A>::operator=(kll_sketch other) {
 
 template<typename T, typename C, typename S, typename A>
 kll_sketch<T, C, S, A>::~kll_sketch() {
-  const uint32_t begin = levels_[0];
-  const uint32_t end = begin + get_num_retained();
-  for (uint32_t i = begin; i < end; i++) items_[i].~T();
-  if (!is_empty()) {
+  if (levels_ != nullptr) AllocU32().deallocate(levels_, levels_size_);
+  if (items_ != nullptr) {
+    const uint32_t begin = levels_[0];
+    const uint32_t end = begin + get_num_retained();
+    for (uint32_t i = begin; i < end; i++) items_[i].~T();
+    A().deallocate(items_, items_size_);
+  }
+  if (min_value_ != nullptr) {
     min_value_->~T();
+    A().deallocate(min_value_, 1);
+  }
+  if (max_value_ != nullptr) {
     max_value_->~T();
+    A().deallocate(max_value_, 1);
   }
-  AllocU32().deallocate(levels_, levels_size_);
-  A().deallocate(items_, items_size_);
-  A().deallocate(min_value_, 1);
-  A().deallocate(max_value_, 1);
 }
 
 template<typename T, typename C, typename S, typename A>
diff --git a/kll/test/kll_sketch_test.cpp b/kll/test/kll_sketch_test.cpp
index 6a6335b..a695472 100644
--- a/kll/test/kll_sketch_test.cpp
+++ b/kll/test/kll_sketch_test.cpp
@@ -71,6 +71,7 @@ class kll_sketch_test: public CppUnit::TestFixture {
   CPPUNIT_TEST(sketch_of_strings_bytes);
   CPPUNIT_TEST(sketch_of_strings_single_item_bytes);
   CPPUNIT_TEST(copy);
+  CPPUNIT_TEST(move);
   CPPUNIT_TEST_SUITE_END();
 
 
@@ -602,6 +603,25 @@ public:
     }
   }
 
+  void move() {
+    kll_sketch<int> sketch1;
+    const int n(100);
+    for (int i = 0; i < n; i++) sketch1.update(i);
+
+    // move constructor
+    kll_sketch<int> sketch2(std::move(sketch1));
+    for (int i = 0; i < n; i++) {
+      CPPUNIT_ASSERT_EQUAL((double) i / n, sketch2.get_rank(i));
+    }
+
+    // move assignment
+    kll_sketch<int> sketch3;
+    sketch3 = std::move(sketch2);
+    for (int i = 0; i < n; i++) {
+      CPPUNIT_ASSERT_EQUAL((double) i / n, sketch3.get_rank(i));
+    }
+  }
+
 };
 
 CPPUNIT_TEST_SUITE_REGISTRATION(kll_sketch_test);


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