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

mzhu pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/mesos.git

commit 22152e48d8adfb60d714bcd4dc8b918ecc1db8a9
Author: Meng Zhu <[email protected]>
AuthorDate: Tue Mar 12 15:26:26 2019 -0700

    Added a `contains` method in `ResourceQuantities`.
    
    The method checks if the ResourceQuantities object
    contains another ResourceQuantities.
    
    Also added tests.
    
    Review: https://reviews.apache.org/r/70149
---
 src/common/resource_quantities.cpp      | 36 +++++++++++++++++++++++++++
 src/common/resource_quantities.hpp      |  2 ++
 src/tests/resource_quantities_tests.cpp | 44 +++++++++++++++++++++++++++++++++
 3 files changed, 82 insertions(+)

diff --git a/src/common/resource_quantities.cpp 
b/src/common/resource_quantities.cpp
index bfd99b0..6401323 100644
--- a/src/common/resource_quantities.cpp
+++ b/src/common/resource_quantities.cpp
@@ -139,6 +139,42 @@ Value::Scalar ResourceQuantities::get(const string& name) 
const
 }
 
 
+bool ResourceQuantities::contains(const ResourceQuantities& right) const
+{
+  size_t leftIndex = 0u;
+  size_t rightIndex = 0u;
+
+  // Since quantities are sorted in alphabetical order, we can walk them
+  // at the same time.
+  while (leftIndex < size() && rightIndex < right.size()) {
+    const pair<string, Value::Scalar>& left_ = quantities.at(leftIndex);
+    const pair<string, Value::Scalar>& right_ = 
right.quantities.at(rightIndex);
+
+    if (left_.first < right_.first) {
+      // Item exists in the left but not in the right.
+      ++leftIndex;
+    } else if (left_.first > right_.first) {
+      // Item exists in the right but not in the left.
+      return false;
+    } else {
+      // Item exists in both left and right.
+      if (left_.second < right_.second) {
+        return false;
+      }
+      ++leftIndex;
+      ++rightIndex;
+    }
+  }
+
+  // Right contains items that left does not have.
+  if (rightIndex < right.size()) {
+    return false;
+  }
+
+  return true;
+}
+
+
 ResourceQuantities& ResourceQuantities::operator+=(
     const ResourceQuantities& right)
 {
diff --git a/src/common/resource_quantities.hpp 
b/src/common/resource_quantities.hpp
index 11e3f42..fdd81ed 100644
--- a/src/common/resource_quantities.hpp
+++ b/src/common/resource_quantities.hpp
@@ -113,6 +113,8 @@ public:
   // If the given name is absent, return zero.
   Value::Scalar get(const std::string& name) const;
 
+  bool contains(const ResourceQuantities& quantities) const;
+
   ResourceQuantities& operator+=(const ResourceQuantities& quantities);
   ResourceQuantities& operator-=(const ResourceQuantities& quantities);
 
diff --git a/src/tests/resource_quantities_tests.cpp 
b/src/tests/resource_quantities_tests.cpp
index 674785c..5edbac3 100644
--- a/src/tests/resource_quantities_tests.cpp
+++ b/src/tests/resource_quantities_tests.cpp
@@ -245,6 +245,50 @@ TEST(QuantitiesTest, Subtraction)
 }
 
 
+TEST(QuantitiesTest, Contains)
+{
+  ResourceQuantities empty{};
+  EXPECT_TRUE(empty.contains(empty));
+
+  ResourceQuantities some =
+    CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1"));
+  EXPECT_TRUE(some.contains(empty));
+  EXPECT_FALSE(empty.contains(some));
+
+  // Self contains.
+  some = CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;mem:1"));
+  EXPECT_TRUE(some.contains(some));
+
+  // Superset and subset.
+  ResourceQuantities superset =
+    CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;mem:1;disk:1"));
+  ResourceQuantities subset =
+    CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;mem:1"));
+  EXPECT_TRUE(superset.contains(subset));
+  EXPECT_FALSE(subset.contains(superset));
+
+  // Intersected sets.
+  ResourceQuantities set1 =
+    CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;mem:1"));
+  ResourceQuantities set2 =
+    CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;disk:1"));
+  EXPECT_FALSE(set1.contains(set2));
+  EXPECT_FALSE(set2.contains(set1));
+
+  // Sets with no intersection.
+  set1 = CHECK_NOTERROR(ResourceQuantities::fromString("cpus:1;mem:1"));
+  set2 = CHECK_NOTERROR(ResourceQuantities::fromString("gpu:1;disk:1"));
+  EXPECT_FALSE(set1.contains(set2));
+  EXPECT_FALSE(set2.contains(set1));
+
+  // Same name, different scalars.
+  superset = CHECK_NOTERROR(ResourceQuantities::fromString("cpus:2;mem:2"));
+  subset = CHECK_NOTERROR(ResourceQuantities::fromString("cpus:2;mem:1"));
+  EXPECT_TRUE(superset.contains(subset));
+  EXPECT_FALSE(subset.contains(superset));
+}
+
+
 } // namespace tests {
 } // namespace internal {
 } // namespace mesos {

Reply via email to