Repository: mesos Updated Branches: refs/heads/master e983d6ae3 -> ebd2b0711
Updated Multimap and multihashmap so their API match hashmap and hashset. Review: https://reviews.apache.org/r/37714 Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/ebd2b071 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/ebd2b071 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/ebd2b071 Branch: refs/heads/master Commit: ebd2b0711ce9389a63f6fe9e60ea10525b9c52ed Parents: e983d6a Author: Alexander Rojas <[email protected]> Authored: Mon Sep 28 20:54:00 2015 -0400 Committer: Michael Park <[email protected]> Committed: Tue Sep 29 01:47:05 2015 -0400 ---------------------------------------------------------------------- .../stout/include/stout/multihashmap.hpp | 129 ++++++++++++------- .../3rdparty/stout/include/stout/multimap.hpp | 11 ++ .../3rdparty/stout/tests/multimap_tests.cpp | 53 ++++++++ 3 files changed, 148 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/ebd2b071/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp index d9e4031..5748c9e 100644 --- a/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp +++ b/3rdparty/libprocess/3rdparty/stout/include/stout/multihashmap.hpp @@ -16,49 +16,87 @@ #include <algorithm> // For find. #include <list> +#include <map> #include <set> #include <unordered_map> #include <utility> +#include <stout/foreach.hpp> // Implementation of a hash multimap via 'std::unordered_multimap' // but with a better interface. The rationale for creating this is -// that the std::multimap interface is painful to use (requires lots -// of iterator garbage, as well as the use of 'equal_range' which -// makes for cluttered code). -template <typename K, typename V> -class multihashmap : public std::unordered_multimap<K, V> +// that the std::unordered_multimap interface is painful to use +// (requires lots of iterator garbage, as well as the use of +// 'equal_range' which makes for cluttered code). +template <typename Key, + typename Value, + typename Hash = std::hash<Key>, + typename Equal = std::equal_to<Key>> +class multihashmap : public std::unordered_multimap<Key, Value, Hash, Equal> { public: - void put(const K& key, const V& value); - std::list<V> get(const K& key) const; - std::set<K> keys() const; - bool remove(const K& key); - bool remove(const K& key, const V& value); - bool contains(const K& key) const; - bool contains(const K& key, const V& value) const; + multihashmap() {} + multihashmap(const std::multimap<Key, Value>& multimap); + multihashmap(std::multimap<Key, Value>&& multimap); + multihashmap(std::initializer_list<std::pair<const Key, Value>> list); + + void put(const Key& key, const Value& value); + std::list<Value> get(const Key& key) const; + std::set<Key> keys() const; + bool remove(const Key& key); + bool remove(const Key& key, const Value& value); + bool contains(const Key& key) const; + bool contains(const Key& key, const Value& value) const; }; -template <typename K, typename V> -void multihashmap<K, V>::put(const K& key, const V& value) +template <typename Key, typename Value, typename Hash, typename Equal> +multihashmap<Key, Value, Hash, Equal>::multihashmap( + const std::multimap<Key, Value>& multimap) { - std::unordered_multimap<K, V>::insert(std::pair<K, V>(key, value)); + std::unordered_multimap<Key, Value, Hash, Equal>::reserve(multimap.size()); + + foreachpair (const Key& key, const Value& value, multimap) { + std::unordered_multimap<Key, Value, Hash, Equal>::emplace(key, value); + } +} + + +template <typename Key, typename Value, typename Hash, typename Equal> +multihashmap<Key, Value, Hash, Equal>::multihashmap( + std::multimap<Key, Value>&& multimap) +{ + std::unordered_multimap<Key, Value, Hash, Equal>::insert( + std::make_move_iterator(multimap.begin()), + std::make_move_iterator(multimap.end())); } -template <typename K, typename V> -std::list<V> multihashmap<K, V>::get(const K& key) const +template <typename Key, typename Value, typename Hash, typename Equal> +multihashmap<Key, Value, Hash, Equal>::multihashmap( + std::initializer_list<std::pair<const Key, Value>> list) + : std::unordered_multimap<Key, Value, Hash, Equal>(list) {} + + +template <typename Key, typename Value, typename Hash, typename Equal> +void multihashmap<Key, Value, Hash, Equal>::put( + const Key& key, + const Value& value) { - std::list<V> values; // Values to return. + std::unordered_multimap<Key, Value, Hash, Equal>::insert({key, value}); +} - std::pair<typename std::unordered_multimap<K, V>::const_iterator, - typename std::unordered_multimap<K, V>::const_iterator> range; - range = std::unordered_multimap<K, V>::equal_range(key); +template <typename Key, typename Value, typename Hash, typename Equal> +std::list<Value> multihashmap<Key, Value, Hash, Equal>::get( + const Key& key) const +{ + std::list<Value> values; // Values to return. + + auto range = + std::unordered_multimap<Key, Value, Hash, Equal>::equal_range(key); - typename std::unordered_multimap<K, V>::const_iterator i; - for (i = range.first; i != range.second; ++i) { + for (auto i = range.first; i != range.second; ++i) { values.push_back(i->second); } @@ -66,36 +104,35 @@ std::list<V> multihashmap<K, V>::get(const K& key) const } -template <typename K, typename V> -std::set<K> multihashmap<K, V>::keys() const +template <typename Key, typename Value, typename Hash, typename Equal> +std::set<Key> multihashmap<Key, Value, Hash, Equal>::keys() const { - std::set<K> keys; - foreachkey (const K& key, *this) { + std::set<Key> keys; + foreachkey (const Key& key, *this) { keys.insert(key); } return keys; } -template <typename K, typename V> -bool multihashmap<K, V>::remove(const K& key) +template <typename Key, typename Value, typename Hash, typename Equal> +bool multihashmap<Key, Value, Hash, Equal>::remove(const Key& key) { - return std::unordered_multimap<K, V>::erase(key) > 0; + return std::unordered_multimap<Key, Value, Hash, Equal>::erase(key) > 0; } -template <typename K, typename V> -bool multihashmap<K, V>::remove(const K& key, const V& value) +template <typename Key, typename Value, typename Hash, typename Equal> +bool multihashmap<Key, Value, Hash, Equal>::remove( + const Key& key, + const Value& value) { - std::pair<typename std::unordered_multimap<K, V>::iterator, - typename std::unordered_multimap<K, V>::iterator> range; - - range = std::unordered_multimap<K, V>::equal_range(key); + auto range = + std::unordered_multimap<Key, Value, Hash, Equal>::equal_range(key); - typename std::unordered_multimap<K, V>::iterator i; - for (i = range.first; i != range.second; ++i) { + for (auto i = range.first; i != range.second; ++i) { if (i->second == value) { - std::unordered_multimap<K, V>::erase(i); + std::unordered_multimap<Key, Value, Hash, Equal>::erase(i); return true; } } @@ -104,17 +141,19 @@ bool multihashmap<K, V>::remove(const K& key, const V& value) } -template <typename K, typename V> -bool multihashmap<K, V>::contains(const K& key) const +template <typename Key, typename Value, typename Hash, typename Equal> +bool multihashmap<Key, Value, Hash, Equal>::contains(const Key& key) const { - return multihashmap<K, V>::count(key) > 0; + return multihashmap<Key, Value, Hash, Equal>::count(key) > 0; } -template <typename K, typename V> -bool multihashmap<K, V>::contains(const K& key, const V& value) const +template <typename Key, typename Value, typename Hash, typename Equal> +bool multihashmap<Key, Value, Hash, Equal>::contains( + const Key& key, + const Value& value) const { - const std::list<V> values = get(key); + const std::list<Value> values = get(key); return std::find(values.begin(), values.end(), value) != values.end(); } http://git-wip-us.apache.org/repos/asf/mesos/blob/ebd2b071/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp b/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp index fb3e7a1..52d1eea 100644 --- a/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp +++ b/3rdparty/libprocess/3rdparty/stout/include/stout/multimap.hpp @@ -20,6 +20,8 @@ #include <set> #include <utility> +#include <stout/foreach.hpp> + // Implementation of a multimap via std::multimap but with a better // interface. The rationale for creating this is that the // std::multimap interface is painful to use (requires lots of @@ -29,6 +31,9 @@ template <typename K, typename V> class Multimap : public std::multimap<K, V> { public: + Multimap() {} + Multimap(std::initializer_list<std::pair<const K, V>> list); + void put(const K& key, const V& value); std::list<V> get(const K& key) const; std::set<K> keys() const; @@ -40,6 +45,12 @@ public: template <typename K, typename V> +Multimap<K, V>::Multimap(std::initializer_list<std::pair<const K, V>> list) + : std::multimap<K, V>(list) +{} + + +template <typename K, typename V> void Multimap<K, V>::put(const K& key, const V& value) { std::multimap<K, V>::insert(std::pair<K, V>(key, value)); http://git-wip-us.apache.org/repos/asf/mesos/blob/ebd2b071/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp ---------------------------------------------------------------------- diff --git a/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp b/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp index 535cd2d..271e0c8 100644 --- a/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp +++ b/3rdparty/libprocess/3rdparty/stout/tests/multimap_tests.cpp @@ -37,6 +37,59 @@ typedef ::testing::Types< TYPED_TEST_CASE(MultimapTest, MultimapTypes); +// Tests construction of multimaps passing initializer lists as parameters. +TYPED_TEST(MultimapTest, InitializerList) +{ + typedef TypeParam Map; + + Map map1({{"hello", 1}, {"Hello", 2}}); + EXPECT_EQ(2u, map1.size()); + + EXPECT_TRUE(Map{}.empty()); + + Map map2( + {{"foo", 102}, {"foo", 103}, {"bar", 102}, {"bar", 103}, {"baz", 1}}); + ASSERT_EQ(2u, map2.get("foo").size()); + ASSERT_EQ(2u, map2.get("bar").size()); + ASSERT_EQ(1u, map2.get("baz").size()); + ASSERT_EQ(5u, map2.size()); +} + + +// Tests conversion from std::multimap to our multimap type. +TYPED_TEST(MultimapTest, FromMultimap) +{ + typedef TypeParam Map; + + Multimap<typename Map::key_type, typename Map::mapped_type> map1( + {{"foo", 102}, {"foo", 103}, {"bar", 102}, {"bar", 103}, {"baz", 1}}); + + Map map2(map1); + + ASSERT_EQ(2u, map2.get("foo").size()); + ASSERT_EQ(2u, map2.get("bar").size()); + ASSERT_EQ(1u, map2.get("baz").size()); + ASSERT_EQ(5u, map2.size()); +} + + +// Tests move constructor from std::multimap. +TYPED_TEST(MultimapTest, FromRValueMultimap) +{ + typedef TypeParam Map; + + Multimap<typename Map::key_type, typename Map::mapped_type> map1( + {{"foo", 102}, {"foo", 103}, {"bar", 102}, {"bar", 103}, {"baz", 1}}); + + Map map2(std::move(map1)); + + ASSERT_EQ(2u, map2.get("foo").size()); + ASSERT_EQ(2u, map2.get("bar").size()); + ASSERT_EQ(1u, map2.get("baz").size()); + ASSERT_EQ(5u, map2.size()); +} + + TYPED_TEST(MultimapTest, Put) { typedef TypeParam Map;
