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 9fe078d  move-friendly set difference
9fe078d is described below

commit 9fe078d9301f6cb6c17aa014b5460dc211896f18
Author: AlexanderSaydakov <[email protected]>
AuthorDate: Mon Jul 13 18:31:38 2020 -0700

    move-friendly set difference
---
 common/include/conditional_back_inserter.hpp     |  7 +++++-
 common/include/conditional_forward.hpp           | 30 ++++++++++++++++++++++++
 tuple/include/theta_comparators.hpp              |  6 ++---
 tuple/include/theta_set_difference_base.hpp      |  6 +++--
 tuple/include/theta_set_difference_base_impl.hpp | 16 ++++++++-----
 tuple/include/tuple_a_not_b.hpp                  |  3 ++-
 tuple/include/tuple_a_not_b_impl.hpp             |  5 ++--
 7 files changed, 58 insertions(+), 15 deletions(-)

diff --git a/common/include/conditional_back_inserter.hpp 
b/common/include/conditional_back_inserter.hpp
index 9b33833..8a2b38b 100644
--- a/common/include/conditional_back_inserter.hpp
+++ b/common/include/conditional_back_inserter.hpp
@@ -40,11 +40,16 @@ public:
     return *this;
   }
 
-  conditional_back_insert_iterator& operator=(typename 
Container::const_reference value) {
+  conditional_back_insert_iterator& operator=(const typename 
Container::value_type& value) {
     if (p(value)) std::back_insert_iterator<Container>::operator=(value);
     return *this;
   }
 
+  conditional_back_insert_iterator& operator=(typename Container::value_type&& 
value) {
+    if (p(value)) 
std::back_insert_iterator<Container>::operator=(std::move(value));
+    return *this;
+  }
+
   conditional_back_insert_iterator& operator*() { return *this; }
   conditional_back_insert_iterator& operator++() { return *this; }
   conditional_back_insert_iterator& operator++(int) { return *this; }
diff --git a/common/include/conditional_forward.hpp 
b/common/include/conditional_forward.hpp
index e0745ee..4648b85 100644
--- a/common/include/conditional_forward.hpp
+++ b/common/include/conditional_forward.hpp
@@ -35,6 +35,36 @@ fwd_type<T1, T2> conditional_forward(T2&& value) {
   return std::forward<fwd_type<T1, T2>>(std::forward<T2>(value));
 }
 
+// Forward container as iterators
+
+template<typename Container>
+auto forward_begin(Container&& c) ->
+typename std::enable_if<std::is_lvalue_reference<Container>::value, 
decltype(c.begin())>::type
+{
+  return c.begin();
+}
+
+template<typename Container>
+auto forward_begin(Container&& c) ->
+typename std::enable_if<!std::is_lvalue_reference<Container>::value, 
decltype(std::make_move_iterator(c.begin()))>::type
+{
+  return std::make_move_iterator(c.begin());
+}
+
+template<typename Container>
+auto forward_end(Container&& c) ->
+typename std::enable_if<std::is_lvalue_reference<Container>::value, 
decltype(c.end())>::type
+{
+  return c.end();
+}
+
+template<typename Container>
+auto forward_end(Container&& c) ->
+typename std::enable_if<!std::is_lvalue_reference<Container>::value, 
decltype(std::make_move_iterator(c.end()))>::type
+{
+  return std::make_move_iterator(c.end());
+}
+
 } /* namespace datasketches */
 
 #endif
diff --git a/tuple/include/theta_comparators.hpp 
b/tuple/include/theta_comparators.hpp
index a7520c1..e8a39b7 100644
--- a/tuple/include/theta_comparators.hpp
+++ b/tuple/include/theta_comparators.hpp
@@ -24,9 +24,9 @@ namespace datasketches {
 
 template<typename ExtractKey>
 struct compare_by_key {
-  template<typename Entry>
-  bool operator()(Entry&& a, Entry&& b) const {
-    return ExtractKey()(std::forward<Entry>(a)) < 
ExtractKey()(std::forward<Entry>(b));
+  template<typename Entry1, typename Entry2>
+  bool operator()(Entry1&& a, Entry2&& b) const {
+    return ExtractKey()(std::forward<Entry1>(a)) < 
ExtractKey()(std::forward<Entry2>(b));
   }
 };
 
diff --git a/tuple/include/theta_set_difference_base.hpp 
b/tuple/include/theta_set_difference_base.hpp
index 253fbba..0c84129 100644
--- a/tuple/include/theta_set_difference_base.hpp
+++ b/tuple/include/theta_set_difference_base.hpp
@@ -35,11 +35,13 @@ template<
 class theta_set_difference_base {
 public:
   using comparator = compare_by_key<ExtractKey>;
-  using hash_table = theta_update_sketch_base<Entry, ExtractKey, Allocator>;
+  using AllocU64 = typename std::allocator_traits<Allocator>::template 
rebind_alloc<uint64_t>;
+  using hash_table = theta_update_sketch_base<uint64_t, trivial_extract_key, 
AllocU64>;
 
   theta_set_difference_base(uint64_t seed);
 
-  CompactSketch compute(const Sketch& a, const Sketch& b, bool ordered) const;
+  template<typename SS>
+  CompactSketch compute(SS&& a, const Sketch& b, bool ordered) const;
 
 private:
   uint16_t seed_hash_;
diff --git a/tuple/include/theta_set_difference_base_impl.hpp 
b/tuple/include/theta_set_difference_base_impl.hpp
index 7273c9f..98c7ade 100644
--- a/tuple/include/theta_set_difference_base_impl.hpp
+++ b/tuple/include/theta_set_difference_base_impl.hpp
@@ -20,6 +20,7 @@
 #include <algorithm>
 
 #include "conditional_back_inserter.hpp"
+#include "conditional_forward.hpp"
 
 namespace datasketches {
 
@@ -29,7 +30,8 @@ seed_hash_(compute_seed_hash(seed))
 {}
 
 template<typename EN, typename EK, typename S, typename CS, typename A>
-CS theta_set_difference_base<EN, EK, S, CS, A>::compute(const S& a, const S& 
b, bool ordered) const {
+template<typename SS>
+CS theta_set_difference_base<EN, EK, S, CS, A>::compute(SS&& a, const S& b, 
bool ordered) const {
   if (a.is_empty() || a.get_num_retained() == 0 || b.is_empty()) return CS(a, 
ordered);
   if (a.get_seed_hash() != seed_hash_) throw std::invalid_argument("A seed 
hash mismatch");
   if (b.get_seed_hash() != seed_hash_) throw std::invalid_argument("B seed 
hash mismatch");
@@ -39,28 +41,30 @@ CS theta_set_difference_base<EN, EK, S, CS, 
A>::compute(const S& a, const S& b,
   bool is_empty = a.is_empty();
 
   if (b.get_num_retained() == 0) {
-    std::copy_if(a.begin(), a.end(), std::back_inserter(entries), 
key_less_than<uint64_t, EN, EK>(theta));
+    std::copy_if(forward_begin(std::forward<SS>(a)), 
forward_end(std::forward<SS>(a)), std::back_inserter(entries),
+        key_less_than<uint64_t, EN, EK>(theta));
   } else {
     if (a.is_ordered() && b.is_ordered()) { // sort-based
-      std::set_difference(a.begin(), a.end(), b.begin(), b.end(), 
conditional_back_inserter(entries, key_less_than<uint64_t, EN, EK>(theta)));
+      std::set_difference(forward_begin(std::forward<SS>(a)), 
forward_end(std::forward<SS>(a)), b.begin(), b.end(),
+          conditional_back_inserter(entries, key_less_than<uint64_t, EN, 
EK>(theta)), comparator());
     } else { // hash-based
       const uint8_t lg_size = lg_size_from_count(b.get_num_retained(), 
hash_table::REBUILD_THRESHOLD);
       hash_table table(lg_size, lg_size, hash_table::resize_factor::X1, 1, 0); 
// seed is not used here
       for (const auto& entry: b) {
         const uint64_t hash = EK()(entry);
         if (hash < theta) {
-          table.insert(table.find(hash).first, entry);
+          table.insert(table.find(hash).first, hash);
         } else if (b.is_ordered()) {
           break; // early stop
         }
       }
 
       // scan A lookup B
-      for (const auto& entry: a) {
+      for (auto& entry: a) {
         const uint64_t hash = EK()(entry);
         if (hash < theta) {
           auto result = table.find(hash);
-          if (!result.second) entries.push_back(entry);
+          if (!result.second) 
entries.push_back(conditional_forward<SS>(entry));
         } else if (a.is_ordered()) {
           break; // early stop
         }
diff --git a/tuple/include/tuple_a_not_b.hpp b/tuple/include/tuple_a_not_b.hpp
index 5883d73..923e2e1 100644
--- a/tuple/include/tuple_a_not_b.hpp
+++ b/tuple/include/tuple_a_not_b.hpp
@@ -44,7 +44,8 @@ public:
    * Computes the a-not-b set operation given two sketches.
    * @return the result of a-not-b
    */
-  CompactSketch compute(const Sketch& a, const Sketch& b, bool ordered = true) 
const;
+  template<typename FwdSketch>
+  CompactSketch compute(FwdSketch&& a, const Sketch& b, bool ordered = true) 
const;
 
 private:
   State state_;
diff --git a/tuple/include/tuple_a_not_b_impl.hpp 
b/tuple/include/tuple_a_not_b_impl.hpp
index ccc081d..4ba2e41 100644
--- a/tuple/include/tuple_a_not_b_impl.hpp
+++ b/tuple/include/tuple_a_not_b_impl.hpp
@@ -25,8 +25,9 @@ state_(seed)
 {}
 
 template<typename S, typename A>
-auto tuple_a_not_b<S, A>::compute(const Sketch& a, const Sketch& b, bool 
ordered) const -> CompactSketch {
-  return state_.compute(a, b, ordered);
+template<typename SS>
+auto tuple_a_not_b<S, A>::compute(SS&& a, const Sketch& b, bool ordered) const 
-> CompactSketch {
+  return state_.compute(std::forward<SS>(a), b, ordered);
 }
 
 } /* namespace datasketches */


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to