| 56 | |
| 57 | |
| 58 | Try<::mesos::Value::Ranges> fragment( |
| 59 | const ::mesos::Value::Range& bounds, |
| 60 | size_t numRanges) |
| 61 | { |
| 62 | uint64_t numValues = bounds.end() - bounds.begin() + 1; |
| 63 | |
| 64 | // Compute the max number of ranges. |
| 65 | // |
| 66 | // If `numValues` is even, then the maximum number of ranges is |
| 67 | // `numValues / 2`: |
| 68 | // [1-2] -> 2 values, maximum 1 range: [1-2] |
| 69 | // [1-4] -> 4 values, maximum 2 ranges: [1-1,3-4] |
| 70 | // [1-6] -> 6 values, maximum 3 ranges: [1-1,3-3,5-6] |
| 71 | // |
| 72 | // If `numValues` is odd, then the maximum number of ranges is |
| 73 | // `(numValues + 1) / 2`: |
| 74 | // [1-1] -> 1 values, maximum 1 range: [1-1] |
| 75 | // [1-3] -> 3 values, maximum 2 ranges: [1-1,3-3] |
| 76 | // [1-5] -> 5 values, maximum 3 ranges: [1-1,3-3,5-5] |
| 77 | // |
| 78 | uint64_t maxRanges; |
| 79 | if (numValues % 2 == 0) { |
| 80 | maxRanges = numValues / 2; |
| 81 | } else { |
| 82 | maxRanges = (numValues + 1) / 2; |
| 83 | } |
| 84 | |
| 85 | if (numRanges > maxRanges) { |
| 86 | return Error("Requested more distinct ranges than possible"); |
| 87 | } |
| 88 | |
| 89 | // See the documentation above for the fragmentation technique. |
| 90 | // We fragment from the front of the bounds until we have the |
| 91 | // desired number of ranges. |
| 92 | ::mesos::Value::Ranges ranges; |
| 93 | ranges.mutable_range()->Reserve(static_cast<int>(numRanges)); |
| 94 | |
| 95 | for (size_t i = 0; i < numRanges; ++i) { |
| 96 | Value::Range* range = ranges.add_range(); |
| 97 | |
| 98 | range->set_begin(bounds.begin() + (i * 2)); |
| 99 | range->set_end(range->begin()); |
| 100 | } |
| 101 | |
| 102 | // Make sure the last range covers the end of the bounds. |
| 103 | if (!ranges.range().empty()) { |
| 104 | ranges.mutable_range()->rbegin()->set_end(bounds.end()); |
| 105 | } |
| 106 | |
| 107 | return ranges; |
| 108 | } |
| 109 | |
| 110 | |
| 111 | ::mesos::Value::Range createRange(uint64_t begin, uint64_t end) |