Added a utility to shrink scalar resource while keeping its meta-data. This is particularly useful when performing fine-grained allocation of resources by "chopping off" some of the resources when possible. Note that some resources, e.g. MOUNT volumes, cannot be shrunk.
Review: https://reviews.apache.org/r/64798/ Project: http://git-wip-us.apache.org/repos/asf/mesos/repo Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/3f7b7f95 Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/3f7b7f95 Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/3f7b7f95 Branch: refs/heads/1.4.x Commit: 3f7b7f95de18c01996a507fd8b20bdacd6ca9787 Parents: 2324ec8 Author: Meng Zhu <[email protected]> Authored: Fri Dec 22 13:49:27 2017 -0800 Committer: Benjamin Mahler <[email protected]> Committed: Wed May 2 16:44:18 2018 -0700 ---------------------------------------------------------------------- include/mesos/resources.hpp | 7 +++++++ include/mesos/v1/resources.hpp | 7 +++++++ src/common/resources.cpp | 23 +++++++++++++++++++++++ src/v1/resources.cpp | 23 +++++++++++++++++++++++ 4 files changed, 60 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/mesos/blob/3f7b7f95/include/mesos/resources.hpp ---------------------------------------------------------------------- diff --git a/include/mesos/resources.hpp b/include/mesos/resources.hpp index 9f95949..688093f 100644 --- a/include/mesos/resources.hpp +++ b/include/mesos/resources.hpp @@ -310,6 +310,13 @@ public: // This must be called only when the resource is reserved! static const std::string& reservationRole(const Resource& resource); + // Shrinks a scalar type `resource` to the target size. + // Returns true if the resource was shrunk to the target size, + // or the resource is already within the target size. + // Returns false otherwise (i.e. the resource is indivisible. + // E.g. MOUNT volume). + static bool shrink(Resource* resource, const Value::Scalar& target); + // Returns the summed up Resources given a hashmap<Key, Resources>. // // NOTE: While scalar resources such as "cpus" sum correctly, http://git-wip-us.apache.org/repos/asf/mesos/blob/3f7b7f95/include/mesos/v1/resources.hpp ---------------------------------------------------------------------- diff --git a/include/mesos/v1/resources.hpp b/include/mesos/v1/resources.hpp index a621685..94125f8 100644 --- a/include/mesos/v1/resources.hpp +++ b/include/mesos/v1/resources.hpp @@ -310,6 +310,13 @@ public: // This must be called only when the resource is reserved! static const std::string& reservationRole(const Resource& resource); + // Shrinks a scalar type `resource` to the target size. + // Returns true if the resource was shrunk to the target size, + // or the resource is already within the target size. + // Returns false otherwise (i.e. the resource is indivisible. + // E.g. MOUNT volume). + static bool shrink(Resource* resource, const Value::Scalar& target); + // Returns the summed up Resources given a hashmap<Key, Resources>. // // NOTE: While scalar resources such as "cpus" sum correctly, http://git-wip-us.apache.org/repos/asf/mesos/blob/3f7b7f95/src/common/resources.cpp ---------------------------------------------------------------------- diff --git a/src/common/resources.cpp b/src/common/resources.cpp index 8d43889..b31e8a7 100644 --- a/src/common/resources.cpp +++ b/src/common/resources.cpp @@ -1150,6 +1150,29 @@ const string& Resources::reservationRole(const Resource& resource) return resource.reservations().rbegin()->role(); } + +bool Resources::shrink(Resource* resource, const Value::Scalar& target) +{ + if (resource->scalar() <= target) { + return true; // Already within target. + } + + Resource copy = *resource; + copy.mutable_scalar()->CopyFrom(target); + + // Some resources (e.g. MOUNT disk) are indivisible. We use + // a containement check to verify this. Specifically, if a + // contains a smaller version of itself, then it can safely + // be chopped into a smaller amount. + if (Resources(*resource).contains(copy)) { + resource->CopyFrom(copy); + return true; + } + + return false; +} + + ///////////////////////////////////////////////// // Public member functions. ///////////////////////////////////////////////// http://git-wip-us.apache.org/repos/asf/mesos/blob/3f7b7f95/src/v1/resources.cpp ---------------------------------------------------------------------- diff --git a/src/v1/resources.cpp b/src/v1/resources.cpp index 508f3f8..781fef6 100644 --- a/src/v1/resources.cpp +++ b/src/v1/resources.cpp @@ -1181,6 +1181,29 @@ const string& Resources::reservationRole(const Resource& resource) return resource.reservations().rbegin()->role(); } + +bool Resources::shrink(Resource* resource, const Value::Scalar& target) +{ + if (resource->scalar() <= target) { + return true; // Already within target. + } + + Resource copy = *resource; + copy.mutable_scalar()->CopyFrom(target); + + // Some resources (e.g. MOUNT disk) are indivisible. We use + // a containement check to verify this. Specifically, if a + // contains a smaller version of itself, then it can safely + // be chopped into a smaller amount. + if (Resources(*resource).contains(copy)) { + resource->CopyFrom(copy); + return true; + } + + return false; +} + + ///////////////////////////////////////////////// // Public member functions. /////////////////////////////////////////////////
