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

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

commit 8e742ebb72918ce349025fc6bf1ef03f2b3c7e4d
Author: Benno Evers <[email protected]>
AuthorDate: Fri Nov 8 14:05:06 2019 +0100

    Added function to compute a common reservation ancestor.
    
    Added a new function `Resources::getReservationAncestor()` to compute
    a common reservation ancestor between two `Resources`.
    
    Review: https://reviews.apache.org/r/71690/
---
 include/mesos/resources.hpp   | 14 +++++++++
 src/common/resources.cpp      | 34 ++++++++++++++++++++++
 src/tests/resources_tests.cpp | 66 +++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 114 insertions(+)

diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp
index dbfa9c9..da585db 100644
--- a/include/mesos/resources.hpp
+++ b/include/mesos/resources.hpp
@@ -376,6 +376,20 @@ public:
   // E.g. MOUNT volume).
   static bool shrink(Resource* resource, const Value::Scalar& target);
 
+  // Returns the most refined reserved resource that can be
+  // reached by modifications to `a`'s or `b`'s reservations.
+  //
+  // Both `a` and `b` must refer to identical resource quantities.
+  static Resource getReservationAncestor(const Resource& a, const Resource& b);
+
+  // Returns the most refined reserved resources that can be
+  // reached by modifications to `a`'s or `b`'s reservations.
+  //
+  // Both `a` and `b` must be non-empty, and must contain the
+  // same resources except for reservations.
+  static Resources getReservationAncestor(
+      const Resources& a, const Resources& b);
+
   // Returns the summed up Resources given a hashmap<Key, Resources>.
   //
   // NOTE: While scalar resources such as "cpus" sum correctly,
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index e3e1100..88c5696 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -1318,6 +1318,40 @@ bool Resources::shrink(Resource* resource, const 
Value::Scalar& target)
 }
 
 
+Resources Resources::getReservationAncestor(
+    const Resources& r1, const Resources& r2)
+{
+  CHECK(!r1.empty());
+  CHECK(!r2.empty());
+  CHECK(r1.toUnreserved() == r2.toUnreserved());
+
+  Resources result = r1.toUnreserved();
+  Resource ancestor = getReservationAncestor(*r1.begin(), *r2.begin());
+  foreach (
+      const Resource::ReservationInfo& reservation,
+      ancestor.reservations()) {
+    result = result.pushReservation(reservation);
+  }
+
+  return result;
+}
+
+
+Resource Resources::getReservationAncestor(
+    const Resource& r1, const Resource& r2)
+{
+  Resource ancestor = r1;
+  ancestor.clear_reservations();
+
+  const int size = std::min(r1.reservations_size(), r2.reservations_size());
+  for (int i = 0; i < size && r1.reservations(i) == r2.reservations(i); ++i) {
+    *ancestor.add_reservations() = r1.reservations(i);
+  }
+
+  return ancestor;
+}
+
+
 /////////////////////////////////////////////////
 // Public member functions.
 /////////////////////////////////////////////////
diff --git a/src/tests/resources_tests.cpp b/src/tests/resources_tests.cpp
index b585465..bd04431 100644
--- a/src/tests/resources_tests.cpp
+++ b/src/tests/resources_tests.cpp
@@ -3595,6 +3595,72 @@ TEST(ResourcesTest, Evolve)
 }
 
 
+TEST(ResourcesTest, ReservationAncestor)
+{
+  Resources baseResources = *Resources::parse("cpus:2;mem:10");
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(baseResources, baseResources));
+
+  Resources resources1 = baseResources.pushReservation(
+      createDynamicReservationInfo("foo"));
+
+  EXPECT_EQ(
+      resources1,
+      Resources::getReservationAncestor(resources1, resources1));
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(resources1, baseResources));
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(baseResources, resources1));
+
+  resources1 = resources1.pushReservation(
+      createDynamicReservationInfo("foo/bar"));
+
+  EXPECT_EQ(
+      resources1,
+      Resources::getReservationAncestor(resources1, resources1));
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(resources1, baseResources));
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(baseResources, resources1));
+
+  Resources resources2 = baseResources.pushReservation(
+      createDynamicReservationInfo("foo"));
+
+  EXPECT_EQ(
+      resources2,
+      Resources::getReservationAncestor(resources1, resources2));
+
+  EXPECT_EQ(
+      resources2,
+      Resources::getReservationAncestor(resources2, resources1));
+
+  EXPECT_NE(
+      resources1,
+      Resources::getReservationAncestor(baseResources, resources2));
+
+  EXPECT_EQ(
+      baseResources,
+      Resources::getReservationAncestor(baseResources, resources2));
+
+  Resources resources3 = resources2.pushReservation(
+      createDynamicReservationInfo("foo/baz"));
+
+  EXPECT_EQ(
+      resources2,
+      Resources::getReservationAncestor(resources1, resources3));
+}
+
+
 TEST(SharedResourcesTest, Printing)
 {
   Resources volume = createPersistentVolume(

Reply via email to