kudu-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ale...@apache.org
Subject [1/2] kudu git commit: [gutil] add LookupOrEmplace()
Date Mon, 10 Sep 2018 22:18:45 GMT
Repository: kudu
Updated Branches:
  refs/heads/master 953a09b82 -> edde4bebe


[gutil] add LookupOrEmplace()

Added LookupOrEmplace() which is similar to LookupOrInsert() but
uses the r-value mechanics.  Also, added unit tests for new
functionality.

Change-Id: I3a177f410c1d4ed33e6f44cb7d6c33d6141f84fc
Reviewed-on: http://gerrit.cloudera.org:8080/11401
Reviewed-by: Adar Dembo <adar@cloudera.com>
Tested-by: Kudu Jenkins


Project: http://git-wip-us.apache.org/repos/asf/kudu/repo
Commit: http://git-wip-us.apache.org/repos/asf/kudu/commit/38a48476
Tree: http://git-wip-us.apache.org/repos/asf/kudu/tree/38a48476
Diff: http://git-wip-us.apache.org/repos/asf/kudu/diff/38a48476

Branch: refs/heads/master
Commit: 38a48476ee98e180d09e71cd0547119ff43423e4
Parents: 953a09b
Author: Alexey Serbin <aserbin@cloudera.com>
Authored: Fri Sep 7 13:50:29 2018 -0700
Committer: Alexey Serbin <aserbin@cloudera.com>
Committed: Mon Sep 10 21:18:25 2018 +0000

----------------------------------------------------------------------
 src/kudu/gutil/map-util.h      | 15 ++++++++++
 src/kudu/util/map-util-test.cc | 59 +++++++++++++++++++++++++++++++++++++
 2 files changed, 74 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/kudu/blob/38a48476/src/kudu/gutil/map-util.h
----------------------------------------------------------------------
diff --git a/src/kudu/gutil/map-util.h b/src/kudu/gutil/map-util.h
index 82d266f..ef6baae 100644
--- a/src/kudu/gutil/map-util.h
+++ b/src/kudu/gutil/map-util.h
@@ -495,6 +495,21 @@ LookupOrInsert(Collection* const collection,
       collection, typename Collection::value_type(key, value));
 }
 
+// It's similar to LookupOrInsert() but uses the emplace and r-value mechanics
+// to achieve the desired results. The constructor of the new element is called
+// with exactly the same arguments as supplied to emplace, forwarded via
+// std::forward<Args>(args). The element may be constructed even if there
+// already is an element with the same key in the container, in which case the
+// newly constructed element will be destroyed immediately.
+// For details, see
+//   https://en.cppreference.com/w/cpp/container/map/emplace
+//   https://en.cppreference.com/w/cpp/container/unordered_map/emplace
+template <class Collection, class... Args>
+typename Collection::mapped_type&
+LookupOrEmplace(Collection* const collection, Args&&... args) {
+  return collection->emplace(std::forward<Args>(args)...).first->second;
+}
+
 // Counts the number of equivalent elements in the given "sequence", and stores
 // the results in "count_map" with element as the key and count as the value.
 //

http://git-wip-us.apache.org/repos/asf/kudu/blob/38a48476/src/kudu/util/map-util-test.cc
----------------------------------------------------------------------
diff --git a/src/kudu/util/map-util-test.cc b/src/kudu/util/map-util-test.cc
index b074007..78a3484 100644
--- a/src/kudu/util/map-util-test.cc
+++ b/src/kudu/util/map-util-test.cc
@@ -123,4 +123,63 @@ TEST(EmplaceTest, TestEmplace) {
   ASSERT_EQ("foobar", *FindOrDie(my_map, key2));
 }
 
+TEST(LookupOrEmplaceTest, IntMap) {
+  const string key = "mega";
+  map<string, int> int_map;
+
+  {
+    const auto& val = LookupOrEmplace(&int_map, key, 0);
+    ASSERT_EQ(0, val);
+    auto* val_ptr = FindOrNull(int_map, key);
+    ASSERT_NE(nullptr, val_ptr);
+    ASSERT_EQ(0, *val_ptr);
+  }
+
+  {
+    auto& val = LookupOrEmplace(&int_map, key, 10);
+    ASSERT_EQ(0, val);
+    ++val;
+    auto* val_ptr = FindOrNull(int_map, key);
+    ASSERT_NE(nullptr, val_ptr);
+    ASSERT_EQ(1, *val_ptr);
+  }
+
+  {
+    LookupOrEmplace(&int_map, key, 100) += 1000;
+    auto* val_ptr = FindOrNull(int_map, key);
+    ASSERT_NE(nullptr, val_ptr);
+    ASSERT_EQ(1001, *val_ptr);
+  }
+}
+
+TEST(LookupOrEmplaceTest, UniquePtrMap) {
+  constexpr int key = 0;
+  const string ref_str = "turbo";
+  map<int, unique_ptr<string>> uptr_map;
+
+  {
+    unique_ptr<string> val(new string(ref_str));
+    const auto& lookup_val = LookupOrEmplace(&uptr_map, key, std::move(val));
+    ASSERT_EQ(nullptr, val.get());
+    ASSERT_NE(nullptr, lookup_val.get());
+    ASSERT_EQ(ref_str, *lookup_val);
+  }
+
+  {
+    unique_ptr<string> val(new string("giga"));
+    auto& lookup_val = LookupOrEmplace(&uptr_map, key, std::move(val));
+    ASSERT_NE(nullptr, lookup_val.get());
+    ASSERT_EQ(ref_str, *lookup_val);
+    // Update the stored value.
+    *lookup_val = "giga";
+  }
+
+  {
+    unique_ptr<string> val(new string(ref_str));
+    const auto& lookup_val = LookupOrEmplace(&uptr_map, key, std::move(val));
+    ASSERT_NE(nullptr, lookup_val.get());
+    ASSERT_EQ("giga", *lookup_val);
+  }
+}
+
 } // namespace kudu


Mime
View raw message