You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by bm...@apache.org on 2016/07/22 19:10:14 UTC
mesos git commit: Cleanup the allocator port fragmentation logic.
Repository: mesos
Updated Branches:
refs/heads/master 16fe3472d -> 17a1e58d3
Cleanup the allocator port fragmentation logic.
1) Renamed makePortRanges to createPorts, this function creates a
"ports(*)" resource for the given ranges.
2) Added a new helper function 'fragment()', it fragments the
given range bounds into a number of subranges.
3) Rename makeRange to createRange and updated its parameter
to uint64_t to match the protobuf field.
Review: https://reviews.apache.org/r/50062/
Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/17a1e58d
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/17a1e58d
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/17a1e58d
Branch: refs/heads/master
Commit: 17a1e58d3f48d866ac5132cc28b2f33c2e287aac
Parents: 16fe347
Author: Guangya Liu <gy...@gmail.com>
Authored: Fri Jul 22 11:58:03 2016 -0700
Committer: Benjamin Mahler <bm...@apache.org>
Committed: Fri Jul 22 12:10:06 2016 -0700
----------------------------------------------------------------------
src/tests/hierarchical_allocator_tests.cpp | 109 ++++++++++++++++++------
1 file changed, 83 insertions(+), 26 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mesos/blob/17a1e58d/src/tests/hierarchical_allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/hierarchical_allocator_tests.cpp b/src/tests/hierarchical_allocator_tests.cpp
index befb94a..bb6947f 100644
--- a/src/tests/hierarchical_allocator_tests.cpp
+++ b/src/tests/hierarchical_allocator_tests.cpp
@@ -82,38 +82,88 @@ struct Allocation
hashmap<SlaveID, Resources> resources;
};
-static Resource
-makePortRanges(const ::mesos::Value::Range& bounds, unsigned numRanges)
+
+// Creates a "ports(*)" resource for the given ranges.
+static Resource createPorts(const ::mesos::Value::Ranges& ranges)
{
- unsigned numPorts = bounds.end() - bounds.begin();
- unsigned step = numPorts / numRanges;
- ::mesos::Value::Ranges ranges;
+ Value value;
+ value.set_type(Value::RANGES);
+ value.mutable_ranges()->CopyFrom(ranges);
- ranges.mutable_range()->Reserve(numRanges);
+ Resource resource;
+ resource.set_role("*");
+ resource.set_name("ports");
+ resource.set_type(Value::RANGES);
+ resource.mutable_ranges()->CopyFrom(value.ranges());
- for (unsigned i = 0; i < numRanges; ++i) {
- Value::Range *range = ranges.add_range();
- unsigned start = bounds.begin() + (i * step);
- unsigned end = start + 1;
+ return resource;
+}
+
+
+// Fragments the given range bounds into a number of subranges.
+// Returns an Error if 'numRanges' is too large. E.g.
+//
+// [1-10], 1 -> [1-10]
+// [1-10], 2 -> [1-1,3-10]
+// [1-10], 3 -> [1-1,3-3,5-10]
+// [1-10], 4 -> [1-1,3-3,5-5,7-10]
+// [1-10], 5 -> [1-1,3-3,5-5,7-7,9-10]
+// [1-10], 6 -> Error
+//
+static Try<::mesos::Value::Ranges> fragment(
+ const ::mesos::Value::Range& bounds,
+ size_t numRanges)
+{
+ uint64_t numValues = bounds.end() - bounds.begin() + 1;
+
+ // Compute the max number of ranges.
+ //
+ // If `numValues` is even, then the maximum number of ranges is
+ // `numValues / 2`:
+ // [1-2] -> 2 values, maximum 1 range: [1-2]
+ // [1-4] -> 4 values, maximum 2 ranges: [1-1,3-4]
+ // [1-6] -> 6 values, maximum 3 ranges: [1-1,3-3,5-6]
+ //
+ // If `numValues` is odd, then the maximum number of ranges is
+ // `(numValues + 1) / 2`:
+ // [1-1] -> 1 values, maximum 1 range: [1-1]
+ // [1-3] -> 3 values, maximum 2 ranges: [1-1,3-3]
+ // [1-5] -> 5 values, maximum 3 ranges: [1-1,3-3,5-5]
+ //
+ uint64_t maxRanges;
+ if (numValues % 2 == 0) {
+ maxRanges = numValues / 2;
+ } else {
+ maxRanges = (numValues + 1) / 2;
+ }
- range->set_begin(start);
- range->set_end(end);
+ if (numRanges > maxRanges) {
+ return Error("Requested more distinct ranges than possible");
}
- Value values;
- Resource resource;
+ // See the documentation above for the fragmentation technique.
+ // We fragment from the front of the bounds until we have the
+ // desired number of ranges.
+ ::mesos::Value::Ranges ranges;
+ ranges.mutable_range()->Reserve(numRanges);
- values.set_type(Value::RANGES);
- values.mutable_ranges()->CopyFrom(ranges);
- resource.set_type(Value::RANGES);
- resource.set_role("*");
- resource.set_name("ports");
- resource.mutable_ranges()->CopyFrom(values.ranges());
+ for (size_t i = 0; i < numRanges; ++i) {
+ Value::Range* range = ranges.add_range();
- return resource;
+ range->set_begin(bounds.begin() + (i * 2));
+ range->set_end(range->begin());
+ }
+
+ // Make sure the last range covers the end of the bounds.
+ if (!ranges.range().empty()) {
+ ranges.mutable_range()->rbegin()->set_end(bounds.end());
+ }
+
+ return ranges;
}
-static ::mesos::Value::Range makeRange(unsigned begin, unsigned end)
+
+static ::mesos::Value::Range createRange(uint64_t begin, uint64_t end)
{
::mesos::Value::Range range;
range.set_begin(begin);
@@ -121,6 +171,7 @@ static ::mesos::Value::Range makeRange(unsigned begin, unsigned end)
return range;
}
+
struct Deallocation
{
FrameworkID frameworkId;
@@ -3455,8 +3506,11 @@ TEST_P(HierarchicalAllocator_BENCHMARK_Test, DeclineOffers)
Resources resources = Resources::parse(
"cpus:16;mem:2014;disk:1024").get();
- Resources ports = makePortRanges(makeRange(31000, 32000), 16);
- resources += ports;
+ Try<::mesos::Value::Ranges> ranges = fragment(createRange(31000, 32000), 16);
+ ASSERT_SOME(ranges);
+ ASSERT_EQ(16, ranges->range_size());
+
+ resources += createPorts(ranges.get());
watch.start();
@@ -3600,8 +3654,11 @@ TEST_P(HierarchicalAllocator_BENCHMARK_Test, ResourceLabels)
// aggregated easily by the master/allocator.
Resources resources = Resources::parse("mem:2014;disk:1024").get();
- Resources ports = makePortRanges(makeRange(31000, 32000), 16);
- resources += ports;
+ Try<::mesos::Value::Ranges> ranges = fragment(createRange(31000, 32000), 16);
+ ASSERT_SOME(ranges);
+ ASSERT_EQ(16, ranges->range_size());
+
+ resources += createPorts(ranges.get());
watch.start();