You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by jo...@apache.org on 2015/09/25 02:48:02 UTC

[1/5] mesos git commit: Make common attributes symmetrical to v1 attributes.

Repository: mesos
Updated Branches:
  refs/heads/master 1e715819d -> cad6db903


Make common attributes symmetrical to v1 attributes.

This aids in verifying the files are kept in sync.
diff src/common/attributes.cpp src/v1/attributes.cpp should result
in only include and namespace differences.

Review: https://reviews.apache.org/r/38726


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/e28b2878
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/e28b2878
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/e28b2878

Branch: refs/heads/master
Commit: e28b2878f9efa41782ada235d9af2c0d2d0c1046
Parents: 1e71581
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Thu Sep 24 11:26:40 2015 -0700
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Thu Sep 24 17:47:00 2015 -0700

----------------------------------------------------------------------
 src/common/attributes.cpp | 8 ++++----
 1 file changed, 4 insertions(+), 4 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/e28b2878/src/common/attributes.cpp
----------------------------------------------------------------------
diff --git a/src/common/attributes.cpp b/src/common/attributes.cpp
index 8a8d624..3cce9ed 100644
--- a/src/common/attributes.cpp
+++ b/src/common/attributes.cpp
@@ -101,7 +101,7 @@ const Option<Attribute> Attributes::get(const Attribute& thatAttribute) const
 }
 
 
-Attribute Attributes::parse(const std::string& name, const std::string& text)
+Attribute Attributes::parse(const string& name, const string& text)
 {
   Attribute attribute;
   Try<Value> result = internal::values::parse(text);
@@ -180,7 +180,7 @@ bool Attributes::isValid(const Attribute& attribute)
 
 template <>
 Value::Scalar Attributes::get(
-    const std::string& name,
+    const string& name,
     const Value::Scalar& scalar) const
 {
   foreach (const Attribute& attribute, attributes) {
@@ -196,7 +196,7 @@ Value::Scalar Attributes::get(
 
 template <>
 Value::Ranges Attributes::get(
-    const std::string& name,
+    const string& name,
     const Value::Ranges& ranges) const
 {
   foreach (const Attribute& attribute, attributes) {
@@ -212,7 +212,7 @@ Value::Ranges Attributes::get(
 
 template <>
 Value::Text Attributes::get(
-    const std::string& name,
+    const string& name,
     const Value::Text& text) const
 {
   foreach (const Attribute& attribute, attributes) {


[4/5] mesos git commit: Make common type_utils symmetrical to v1 mesos.

Posted by jo...@apache.org.
Make common type_utils symmetrical to v1 mesos.

This aids in verifying the files are kept in sync.
diff src/common/type_utils.cpp src/v1/mesos.cpp should result
in only include and namespace differences.

Moved some things out of type_utils.cpp that are not part of the
public API. They were moved into messages.cpp.

Review: https://reviews.apache.org/r/38733


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/bd791cac
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/bd791cac
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/bd791cac

Branch: refs/heads/master
Commit: bd791cacf4efa8ced83ee4c3a7f627d376534937
Parents: b7d48db
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Thu Sep 24 14:16:32 2015 -0700
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Thu Sep 24 17:47:21 2015 -0700

----------------------------------------------------------------------
 include/mesos/type_utils.hpp |  5 +++
 include/mesos/v1/mesos.hpp   |  5 +++
 src/Makefile.am              |  1 +
 src/common/type_utils.cpp    | 49 --------------------------
 src/messages/messages.cpp    | 73 +++++++++++++++++++++++++++++++++++++++
 src/v1/mesos.cpp             |  4 ++-
 6 files changed, 87 insertions(+), 50 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/include/mesos/type_utils.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/type_utils.hpp b/include/mesos/type_utils.hpp
index 6cedf07..06bf55d 100644
--- a/include/mesos/type_utils.hpp
+++ b/include/mesos/type_utils.hpp
@@ -61,6 +61,11 @@ bool operator==(
 bool operator==(const SlaveInfo& left, const SlaveInfo& right);
 bool operator==(const Volume& left, const Volume& right);
 
+bool operator==(const Label& left, const Label& right);
+bool operator==(const Labels& left, const Labels& right);
+
+bool operator==(const DiscoveryInfo& left, const DiscoveryInfo& right);
+
 bool operator==(const URL& left, const URL& right);
 
 bool operator==(const TaskStatus& left, const TaskStatus& right);

http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/include/mesos/v1/mesos.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.hpp b/include/mesos/v1/mesos.hpp
index 260e112..e5a0e69 100644
--- a/include/mesos/v1/mesos.hpp
+++ b/include/mesos/v1/mesos.hpp
@@ -42,6 +42,11 @@ bool operator==(
 bool operator==(const AgentInfo& left, const AgentInfo& right);
 bool operator==(const Volume& left, const Volume& right);
 
+bool operator==(const Label& left, const Label& right);
+bool operator==(const Labels& left, const Labels& right);
+
+bool operator==(const DiscoveryInfo& left, const DiscoveryInfo& right);
+
 bool operator==(const URL& left, const URL& right);
 
 bool operator==(const TaskStatus& left, const TaskStatus& right);

http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/src/Makefile.am
----------------------------------------------------------------------
diff --git a/src/Makefile.am b/src/Makefile.am
index 776483b..f082484 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -480,6 +480,7 @@ libmesos_no_3rdparty_la_SOURCES =					\
 	master/allocator/allocator.cpp					\
 	master/allocator/sorter/drf/sorter.cpp				\
 	messages/flags.proto						\
+	messages/messages.cpp						\
 	messages/messages.proto						\
 	module/manager.cpp						\
 	sched/constants.cpp						\

http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/src/common/type_utils.cpp
----------------------------------------------------------------------
diff --git a/src/common/type_utils.cpp b/src/common/type_utils.cpp
index 5f74dab..0e11468 100644
--- a/src/common/type_utils.cpp
+++ b/src/common/type_utils.cpp
@@ -361,53 +361,4 @@ bool operator!=(const TaskStatus& left, const TaskStatus& right)
   return !(left == right);
 }
 
-
-namespace internal {
-
-bool operator==(const Task& left, const Task& right)
-{
-  // Order of task statuses is important.
-  if (left.statuses().size() != right.statuses().size()) {
-    return false;
-  }
-
-  for (int i = 0; i < left.statuses().size(); i++) {
-    if (left.statuses().Get(i) != right.statuses().Get(i)) {
-      return false;
-    }
-  }
-
-  return left.name() == right.name() &&
-    left.task_id() == right.task_id() &&
-    left.framework_id() == right.framework_id() &&
-    left.executor_id() == right.executor_id() &&
-    left.slave_id() == right.slave_id() &&
-    left.state() == right.state() &&
-    Resources(left.resources()) == Resources(right.resources()) &&
-    left.status_update_state() == right.status_update_state() &&
-    left.status_update_uuid() == right.status_update_uuid() &&
-    left.labels() == right.labels() &&
-    left.discovery() == right.discovery();
-}
-
-
-std::ostream& operator<<(
-    std::ostream& stream,
-    const StatusUpdate& update)
-{
-  stream << update.status().state()
-         << (update.has_uuid()
-             ? " (UUID: " + stringify(UUID::fromBytes(update.uuid()))
-             : "")
-         << ") for task " << update.status().task_id();
-
-  if (update.status().has_healthy()) {
-    stream << " in health state "
-           << (update.status().healthy() ? "healthy" : "unhealthy");
-  }
-
-  return stream << " of framework " << update.framework_id();
-}
-
-} // namespace internal {
 } // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/src/messages/messages.cpp
----------------------------------------------------------------------
diff --git a/src/messages/messages.cpp b/src/messages/messages.cpp
new file mode 100644
index 0000000..abf3ea3
--- /dev/null
+++ b/src/messages/messages.cpp
@@ -0,0 +1,73 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "messages/messages.hpp"
+
+#include <mesos/resources.hpp>
+#include <mesos/type_utils.hpp>
+
+namespace mesos {
+namespace internal {
+
+bool operator==(const Task& left, const Task& right)
+{
+  // Order of task statuses is important.
+  if (left.statuses().size() != right.statuses().size()) {
+    return false;
+  }
+
+  for (int i = 0; i < left.statuses().size(); i++) {
+    if (left.statuses().Get(i) != right.statuses().Get(i)) {
+      return false;
+    }
+  }
+
+  return left.name() == right.name() &&
+    left.task_id() == right.task_id() &&
+    left.framework_id() == right.framework_id() &&
+    left.executor_id() == right.executor_id() &&
+    left.slave_id() == right.slave_id() &&
+    left.state() == right.state() &&
+    Resources(left.resources()) == Resources(right.resources()) &&
+    left.status_update_state() == right.status_update_state() &&
+    left.status_update_uuid() == right.status_update_uuid() &&
+    left.labels() == right.labels() &&
+    left.discovery() == right.discovery();
+}
+
+
+std::ostream& operator<<(
+    std::ostream& stream,
+    const StatusUpdate& update)
+{
+  stream << update.status().state()
+         << (update.has_uuid()
+             ? " (UUID: " + stringify(UUID::fromBytes(update.uuid()))
+             : "")
+         << ") for task " << update.status().task_id();
+
+  if (update.status().has_healthy()) {
+    stream << " in health state "
+           << (update.status().healthy() ? "healthy" : "unhealthy");
+  }
+
+  return stream << " of framework " << update.framework_id();
+}
+
+} // namespace internal {
+} // namespace mesos {

http://git-wip-us.apache.org/repos/asf/mesos/blob/bd791cac/src/v1/mesos.cpp
----------------------------------------------------------------------
diff --git a/src/v1/mesos.cpp b/src/v1/mesos.cpp
index 631d6e5..e1ebb45 100644
--- a/src/v1/mesos.cpp
+++ b/src/v1/mesos.cpp
@@ -318,7 +318,9 @@ bool operator==(const MasterInfo& left, const MasterInfo& right)
 }
 
 
-bool operator==(const ResourceStatistics& left, const ResourceStatistics& right)
+bool operator==(
+    const ResourceStatistics& left,
+    const ResourceStatistics& right)
 {
   return left.SerializeAsString() == right.SerializeAsString();
 }


[2/5] mesos git commit: Make common values symmetrical to v1 values.

Posted by jo...@apache.org.
Make common values symmetrical to v1 values.

This aids in verifying the files are kept in sync.
diff src/common/values.cpp src/v1/values.cpp should result
in only include and namespace differences.

Review: https://reviews.apache.org/r/38727


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/5926e9de
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/5926e9de
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/5926e9de

Branch: refs/heads/master
Commit: 5926e9de8b2fcfffa84da2e49f80127e37d8ad37
Parents: e28b287
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Thu Sep 24 11:48:44 2015 -0700
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Thu Sep 24 17:47:09 2015 -0700

----------------------------------------------------------------------
 src/v1/values.cpp | 468 +++++++++++++++++++++++++++----------------------
 1 file changed, 260 insertions(+), 208 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/5926e9de/src/v1/values.cpp
----------------------------------------------------------------------
diff --git a/src/v1/values.cpp b/src/v1/values.cpp
index aaa9a7e..4f96d57 100644
--- a/src/v1/values.cpp
+++ b/src/v1/values.cpp
@@ -18,7 +18,12 @@
 
 #include <stdint.h>
 
-#include <iostream>
+#include <algorithm>
+#include <initializer_list>
+#include <ostream>
+#include <string>
+#include <tuple>
+#include <utility>
 #include <vector>
 
 #include <glog/logging.h>
@@ -41,98 +46,6 @@ using std::vector;
 namespace mesos {
 namespace v1 {
 
-namespace internal {
-namespace values {
-
-Try<Value> parse(const std::string& text)
-{
-  Value value;
-
-  // Remove any spaces from the text.
-  string temp;
-  foreach (const char c, text) {
-    if (c != ' ') {
-      temp += c;
-    }
-  }
-
-  if (temp.length() == 0) {
-    return Error("Expecting non-empty string");
-  }
-
-  // TODO(ynie): Find a better way to check brackets.
-  if (!strings::checkBracketsMatching(temp, '{', '}') ||
-      !strings::checkBracketsMatching(temp, '[', ']') ||
-      !strings::checkBracketsMatching(temp, '(', ')')) {
-    return Error("Mismatched brackets");
-  }
-
-  size_t index = temp.find('[');
-  if (index == 0) {
-    // This is a ranges.
-    Value::Ranges ranges;
-    const vector<string>& tokens = strings::tokenize(temp, "[]-,\n");
-    if (tokens.size() % 2 != 0) {
-      return Error("Expecting one or more \"ranges\"");
-    } else {
-      for (size_t i = 0; i < tokens.size(); i += 2) {
-        Value::Range *range = ranges.add_range();
-
-        int j = i;
-        try {
-          range->set_begin(boost::lexical_cast<uint64_t>((tokens[j++])));
-          range->set_end(boost::lexical_cast<uint64_t>(tokens[j++]));
-        } catch (const boost::bad_lexical_cast&) {
-          return Error(
-              "Expecting non-negative integers in '" + tokens[j - 1] + "'");
-        }
-      }
-
-      value.set_type(Value::RANGES);
-      value.mutable_ranges()->MergeFrom(ranges);
-      return value;
-    }
-  } else if (index == string::npos) {
-    size_t index = temp.find('{');
-    if (index == 0) {
-      // This is a set.
-      Value::Set set;
-      const vector<string>& tokens = strings::tokenize(temp, "{},\n");
-      for (size_t i = 0; i < tokens.size(); i++) {
-        set.add_item(tokens[i]);
-      }
-
-      value.set_type(Value::SET);
-      value.mutable_set()->MergeFrom(set);
-      return value;
-    } else if (index == string::npos) {
-      try {
-        Value::Scalar scalar;
-        scalar.set_value(boost::lexical_cast<double>(temp));
-        // This is a Scalar.
-        value.set_type(Value::SCALAR);
-        value.mutable_scalar()->MergeFrom(scalar);
-        return value;
-      } catch (const boost::bad_lexical_cast&) {
-        // This is a Text.
-        Value::Text text;
-        text.set_value(temp);
-        value.set_type(Value::TEXT);
-        value.mutable_text()->MergeFrom(text);
-        return value;
-      }
-    } else {
-      return Error("Unexpected '{' found");
-    }
-  }
-
-  return Error("Unexpected '[' found");
-}
-
-} // namespace values {
-} // namespace internal {
-
-
 ostream& operator<<(ostream& stream, const Value::Scalar& scalar)
 {
   return stream << scalar.value();
@@ -180,115 +93,189 @@ Value::Scalar& operator-=(Value::Scalar& left, const Value::Scalar& right)
   return left;
 }
 
-namespace ranges {
+namespace internal {
 
-static void add(Value::Ranges* result, int64_t begin, int64_t end)
+struct Range
+{
+  uint64_t start;
+  uint64_t end;
+};
+
+
+// Coalesces the vector of ranges provided and modifies `result` to contain the
+// solution.
+// The algorithm first sorts all the individual intervals so that we can iterate
+// over them sequentially.
+// The algorithm does a single pass, after the sort, and builds up the solution
+// in place. It then modifies the `result` with as few steps as possible. The
+// expensive part of this operation is modification of the protobuf, which is
+// why we prefer to build up the solution in a temporary vector.
+void coalesce(Value::Ranges* result, vector<Range> ranges)
 {
-  if (begin > end) {
+  // Exit early if empty.
+  if (ranges.empty()) {
+    result->clear_range();
     return;
   }
-  Value::Range* range = result->add_range();
-  range->set_begin(begin);
-  range->set_end(end);
+
+  std::sort(
+      ranges.begin(),
+      ranges.end(),
+      [](const Range& left, const Range& right) {
+        return std::tie(left.start, left.end) <
+               std::tie(right.start, right.end);
+      });
+
+  // We build up initial state of the current range.
+  CHECK(!ranges.empty());
+  int count = 1;
+  Range current = ranges.front();
+
+  // In a single pass, we compute the size of the end result, as well as modify
+  // in place the intermediate data structure to build up result as we
+  // solve it.
+  foreach (const Range& range, ranges) {
+    // Skip if this range is equivalent to the current range.
+    if (range.start == current.start && range.end == current.end) {
+      continue;
+    }
+
+    // If the current range just needs to be extended on the right.
+    if (range.start == current.start && range.end > current.end) {
+      current.end = range.end;
+    } else if (range.start > current.start) {
+      // If we are starting farther ahead, then there are 2 cases:
+      if (range.start <= current.end + 1) {
+        // 1. Ranges are overlapping and we can merge them.
+        current.end = max(current.end, range.end);
+      } else {
+        // 2. No overlap and we are adding a new range.
+        ranges[count - 1] = current;
+        ++count;
+        current = range;
+      }
+    }
+  }
+
+  // Record the state of the last range into of ranges vector.
+  ranges[count - 1] = current;
+
+  CHECK(count <= static_cast<int>(ranges.size()));
+
+  // Shrink result if it is too large by deleting trailing subrange.
+  if (count < result->range_size()) {
+    result->mutable_range()->DeleteSubrange(
+        count, result->range_size() - count);
+  }
+
+  // Resize enough space so we allocate the pointer array just once.
+  result->mutable_range()->Reserve(count);
+
+  // Copy the solution from ranges vector into result.
+  for (int i = 0; i < count; ++i) {
+    // result might be small and needs to be extended.
+    if (i >= result->range_size()) {
+      result->add_range();
+    }
+
+    CHECK(i < result->range_size());
+    result->mutable_range(i)->set_begin(ranges[i].start);
+    result->mutable_range(i)->set_end(ranges[i].end);
+  }
+
+  CHECK_EQ(result->range_size(), count);
 }
 
-} // namespace ranges {
+} // namespace internal {
 
 
-// Coalesce the given 'range' into already coalesced 'ranges'.
-static void coalesce(Value::Ranges* ranges, const Value::Range& range)
+// Coalesce the given addedRanges  into 'result' ranges.
+void coalesce(
+    Value::Ranges* result,
+    std::initializer_list<Value::Ranges> addedRanges)
 {
-  // Note that we assume that ranges has already been coalesced.
+  size_t rangesSum = result->range_size();
+  foreach (const Value::Ranges& range, addedRanges) {
+    rangesSum += range.range_size();
+  }
 
-  Value::Ranges result;
-  Value::Range temp = range;
-
-  for (int i = 0; i < ranges->range_size(); i++) {
-    const Value::Range& current = ranges->range(i);
-
-    // Check if current and range overlap. Note, we only need to
-    // compare with range and not with temp to check for overlap
-    // because we expect ranges to be coalesced to begin with!
-    if (current.begin() <= range.end() + 1 &&
-        current.end() >= range.begin() - 1) {
-      // current:   |   |
-      // range:       |   |
-      // range:   |   |
-      // Update temp with new boundaries.
-      temp.set_begin(min(temp.begin(), min(range.begin(), current.begin())));
-      temp.set_end(max(temp.end(), max(range.end(), current.end())));
-    } else { // No overlap.
-      result.add_range()->MergeFrom(current);
+  vector<internal::Range> ranges;
+  ranges.reserve(rangesSum);
+
+  // Merges ranges into a vector.
+  auto fill = [&ranges](const Value::Ranges& inputs) {
+    foreach (const Value::Range& range, inputs.range()) {
+      ranges.push_back({range.begin(), range.end()});
     }
+  };
+
+  // Merge both ranges into the vector;
+  fill(*result);
+  foreach (const Value::Ranges& range, addedRanges) {
+    fill(range);
   }
 
-  result.add_range()->MergeFrom(temp);
-  *ranges = result;
+  internal::coalesce(result, std::move(ranges));
 }
 
 
-// Coalesce the given un-coalesced 'uranges' into already coalesced 'ranges'.
-static void coalesce(Value::Ranges* ranges, const Value::Ranges& uranges)
+// Coalesce the given Value::Ranges 'ranges'.
+void coalesce(Value::Ranges* result)
 {
-  // Note that we assume that ranges has already been coalesced.
+  coalesce(result, {Value::Ranges()});
+}
 
-  for (int i = 0; i < uranges.range_size(); i++) {
-    coalesce(ranges, uranges.range(i));
-  }
+
+// Coalesce the given range 'addedRange' into 'result' ranges.
+void coalesce(Value::Ranges* result, const Value::Range& addedRange)
+{
+  Value::Ranges ranges;
+  Value::Range* range = ranges.add_range();
+  range->CopyFrom(addedRange);
+  coalesce(result, {ranges});
 }
 
 
-static void remove(Value::Ranges* ranges, const Value::Range& range)
+// Removes a range from already coalesced ranges.
+// The algorithms constructs a new vector of ranges which is then
+// coalesced into a Value::Ranges instance.
+static void remove(Value::Ranges* _ranges, const Value::Range& removal)
 {
-  // Note that we assume that ranges has already been coalesced.
+  vector<internal::Range> ranges;
+  ranges.reserve(_ranges->range_size());
 
-  Value::Ranges result;
+  foreach (const Value::Range& range, _ranges->range()) {
+    // Skip if the entire range is subsumed by `removal`.
+    if (range.begin() >= removal.begin() && range.end() <= removal.end()) {
+      continue;
+    }
+
+    // Divide if the range subsumes the `removal`.
+    if (range.begin() < removal.begin() && range.end() > removal.end()) {
+      // Front.
+      ranges.emplace_back(internal::Range{range.begin(), removal.begin() - 1});
+      // Back.
+      ranges.emplace_back(internal::Range{removal.end() + 1, range.end()});
+    }
 
-  for (int i = 0; i < ranges->range_size(); i++) {
-    const Value::Range& current = ranges->range(i);
-
-    // Note that these if/else if conditionals are in a particular
-    // order. In particular, the last two assume that the "subsumes"
-    // checks have already occurred.
-    if (range.begin() <= current.begin() && range.end() >= current.end()) {
-      // Range subsumes current.
-      // current:  |     |
-      // range:  |         |
-      // range:  |       |
-      // range:    |       |
-      // range:    |     |
-    } else if (range.begin() >= current.begin() &&
-               range.end() <= current.end()) {
-      // Range is subsumed by current.
-      // current:  |     |
-      // range:      | |
-      // range:    |   |
-      // range:      |   |
-      ranges::add(&result, current.begin(), range.begin() - 1);
-      ranges::add(&result, range.end() + 1, current.end());
-    } else if (range.begin() <= current.begin() &&
-               range.end() >= current.begin()) {
-      // Range overlaps to the left.
-      // current:  |     |
-      // range:  |     |
-      // range:  | |
-      ranges::add(&result, range.end() + 1, current.end());
-    } else if (range.begin() <= current.end() && range.end() >= current.end()) {
-      // Range overlaps to the right.
-      // current:  |     |
-      // range:      |      |
-      // range:          |  |
-      ranges::add(&result, current.begin(), range.begin() - 1);
+    // Fully Emplace if the range doesn't intersect.
+    if (range.end() < removal.begin() || range.begin() > removal.end()) {
+      ranges.emplace_back(internal::Range{range.begin(), range.end()});
     } else {
-      // Range doesn't overlap current.
-      // current:        |   |
-      // range:   |   |
-      // range:                |   |
-      ranges::add(&result, current.begin(), current.end());
+      // Trim if the range does intersect.
+      if (range.end() > removal.end()) {
+        // Trim front.
+        ranges.emplace_back(internal::Range{removal.end() + 1, range.end()});
+      } else {
+        // Trim back.
+        CHECK(range.begin() < removal.begin());
+        ranges.emplace_back(
+            internal::Range{range.begin(), removal.begin() - 1});
+      }
     }
   }
 
-  *ranges = result;
+  internal::coalesce(_ranges, std::move(ranges));
 }
 
 
@@ -309,10 +296,10 @@ ostream& operator<<(ostream& stream, const Value::Ranges& ranges)
 bool operator==(const Value::Ranges& _left, const Value::Ranges& _right)
 {
   Value::Ranges left;
-  coalesce(&left, _left);
+  coalesce(&left, {_left});
 
   Value::Ranges right;
-  coalesce(&right, _right);
+  coalesce(&right, {_right});
 
   if (left.range_size() == right.range_size()) {
     for (int i = 0; i < left.range_size(); i++) {
@@ -341,10 +328,10 @@ bool operator==(const Value::Ranges& _left, const Value::Ranges& _right)
 bool operator<=(const Value::Ranges& _left, const Value::Ranges& _right)
 {
   Value::Ranges left;
-  coalesce(&left, _left);
+  coalesce(&left, {_left});
 
   Value::Ranges right;
-  coalesce(&right, _right);
+  coalesce(&right, {_right});
 
   for (int i = 0; i < left.range_size(); i++) {
     // Make sure this range is a subset of a range in right.
@@ -368,10 +355,7 @@ bool operator<=(const Value::Ranges& _left, const Value::Ranges& _right)
 Value::Ranges operator+(const Value::Ranges& left, const Value::Ranges& right)
 {
   Value::Ranges result;
-
-  coalesce(&result, left);
-  coalesce(&result, right);
-
+  coalesce(&result, {left, right});
   return result;
 }
 
@@ -379,45 +363,24 @@ Value::Ranges operator+(const Value::Ranges& left, const Value::Ranges& right)
 Value::Ranges operator-(const Value::Ranges& left, const Value::Ranges& right)
 {
   Value::Ranges result;
-
-  coalesce(&result, left);
-  coalesce(&result, right);
-
-  for (int i = 0; i < right.range_size(); i++) {
-    remove(&result, right.range(i));
-  }
-
-  return result;
+  coalesce(&result, {left});
+  return result -= right;
 }
 
 
 Value::Ranges& operator+=(Value::Ranges& left, const Value::Ranges& right)
 {
-  Value::Ranges temp;
-
-  coalesce(&temp, left);
-
-  left = temp;
-
-  coalesce(&left, right);
-
+  coalesce(&left, {right});
   return left;
 }
 
 
 Value::Ranges& operator-=(Value::Ranges& left, const Value::Ranges& right)
 {
-  Value::Ranges temp;
-
-  coalesce(&temp, left);
-  coalesce(&temp, right);
-
-  left = temp;
-
-  for (int i = 0; i < right.range_size(); i++) {
+  coalesce(&left);
+  for (int i = 0; i < right.range_size(); ++i) {
     remove(&left, right.range(i));
   }
-
   return left;
 }
 
@@ -584,5 +547,94 @@ bool operator==(const Value::Text& left, const Value::Text& right)
   return left.value() == right.value();
 }
 
+
+namespace internal {
+namespace values {
+
+Try<Value> parse(const string& text)
+{
+  Value value;
+
+  // Remove any spaces from the text.
+  string temp;
+  foreach (const char c, text) {
+    if (c != ' ') {
+      temp += c;
+    }
+  }
+
+  if (temp.length() == 0) {
+    return Error("Expecting non-empty string");
+  }
+
+  // TODO(ynie): Find a better way to check brackets.
+  if (!strings::checkBracketsMatching(temp, '{', '}') ||
+      !strings::checkBracketsMatching(temp, '[', ']') ||
+      !strings::checkBracketsMatching(temp, '(', ')')) {
+    return Error("Mismatched brackets");
+  }
+
+  size_t index = temp.find('[');
+  if (index == 0) {
+    // This is a Value::Ranges.
+    value.set_type(Value::RANGES);
+    Value::Ranges* ranges = value.mutable_ranges();
+    const vector<string>& tokens = strings::tokenize(temp, "[]-,\n");
+    if (tokens.size() % 2 != 0) {
+      return Error("Expecting one or more \"ranges\"");
+    } else {
+      for (size_t i = 0; i < tokens.size(); i += 2) {
+        Value::Range* range = ranges->add_range();
+
+        int j = i;
+        try {
+          range->set_begin(boost::lexical_cast<uint64_t>((tokens[j++])));
+          range->set_end(boost::lexical_cast<uint64_t>(tokens[j++]));
+        } catch (const boost::bad_lexical_cast&) {
+          return Error(
+              "Expecting non-negative integers in '" + tokens[j - 1] + "'");
+        }
+      }
+
+      coalesce(ranges);
+
+      return value;
+    }
+  } else if (index == string::npos) {
+    size_t index = temp.find('{');
+    if (index == 0) {
+      // This is a set.
+      value.set_type(Value::SET);
+      Value::Set* set = value.mutable_set();
+      const vector<string>& tokens = strings::tokenize(temp, "{},\n");
+      for (size_t i = 0; i < tokens.size(); i++) {
+        set->add_item(tokens[i]);
+      }
+      return value;
+    } else if (index == string::npos) {
+      try {
+        // This is a scalar.
+        value.set_type(Value::SCALAR);
+        Value::Scalar* scalar = value.mutable_scalar();
+        scalar->set_value(boost::lexical_cast<double>(temp));
+        return value;
+      } catch (const boost::bad_lexical_cast&) {
+        // This is a text.
+        value.set_type(Value::TEXT);
+        Value::Text* text = value.mutable_text();
+        text->set_value(temp);
+        return value;
+      }
+    } else {
+      return Error("Unexpected '{' found");
+    }
+  }
+
+  return Error("Unexpected '[' found");
+}
+
+} // namespace values {
+} // namespace internal {
+
 } // namespace v1 {
 } // namespace mesos {


[3/5] mesos git commit: Make common resources symmetrical to v1 resources.

Posted by jo...@apache.org.
Make common resources symmetrical to v1 resources.

This aids in verifying the files are kept in sync.
diff src/common/resources.cpp src/v1/resources.cpp should result
in only include and namespace differences.

Review: https://reviews.apache.org/r/38731


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/b7d48db4
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/b7d48db4
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/b7d48db4

Branch: refs/heads/master
Commit: b7d48db4375b9a860f8ce35821b922faab8da370
Parents: 5926e9d
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Thu Sep 24 13:16:46 2015 -0700
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Thu Sep 24 17:47:15 2015 -0700

----------------------------------------------------------------------
 src/common/resources.cpp | 28 +++++++++++++++-------------
 1 file changed, 15 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/b7d48db4/src/common/resources.cpp
----------------------------------------------------------------------
diff --git a/src/common/resources.cpp b/src/common/resources.cpp
index abfc6f3..601388c 100644
--- a/src/common/resources.cpp
+++ b/src/common/resources.cpp
@@ -62,9 +62,7 @@ bool operator!=(
 }
 
 
-bool operator==(
-    const Resource::DiskInfo& left,
-    const Resource::DiskInfo& right)
+bool operator==(const Resource::DiskInfo& left, const Resource::DiskInfo& right)
 {
   // NOTE: We ignore 'volume' inside DiskInfo when doing comparison
   // because it describes how this resource will be used which has
@@ -83,9 +81,7 @@ bool operator==(
 }
 
 
-bool operator!=(
-    const Resource::DiskInfo& left,
-    const Resource::DiskInfo& right)
+bool operator!=(const Resource::DiskInfo& left, const Resource::DiskInfo& right)
 {
   return !(left == right);
 }
@@ -140,6 +136,8 @@ bool operator!=(const Resource& left, const Resource& right)
 }
 
 
+namespace internal {
+
 // Tests if we can add two Resource objects together resulting in one
 // valid Resource object. For example, two Resource objects with
 // different name, type or role are not addable.
@@ -256,6 +254,8 @@ static bool contains(const Resource& left, const Resource& right)
   }
 }
 
+} // namespace internal {
+
 
 Resource& operator+=(Resource& left, const Resource& right)
 {
@@ -599,7 +599,7 @@ bool Resources::contains(const Resource& that) const
 {
   // NOTE: We must validate 'that' because invalid resources can lead
   // to false positives here (e.g., "cpus:-1" will return true). This
-  // is because mesos::contains assumes resources are valid.
+  // is because 'contains' assumes resources are valid.
   return validate(that).isNone() && _contains(that);
 }
 
@@ -1037,7 +1037,7 @@ Option<Value::Ranges> Resources::ephemeral_ports() const
 bool Resources::_contains(const Resource& that) const
 {
   foreach (const Resource& resource, resources) {
-    if (mesos::contains(resource, that)) {
+    if (internal::contains(resource, that)) {
       return true;
     }
   }
@@ -1090,7 +1090,7 @@ Resources& Resources::operator+=(const Resource& that)
   if (validate(that).isNone() && !isEmpty(that)) {
     bool found = false;
     foreach (Resource& resource, resources) {
-      if (addable(resource, that)) {
+      if (internal::addable(resource, that)) {
         resource += that;
         found = true;
         break;
@@ -1139,7 +1139,7 @@ Resources& Resources::operator-=(const Resource& that)
     for (int i = 0; i < resources.size(); i++) {
       Resource* resource = resources.Mutable(i);
 
-      if (subtractable(*resource, that)) {
+      if (internal::subtractable(*resource, that)) {
         *resource -= that;
 
         // Remove the resource if it becomes invalid or zero. We need
@@ -1168,7 +1168,8 @@ Resources& Resources::operator-=(const Resources& that)
 }
 
 
-ostream& operator<<(ostream& stream, const Volume& volume) {
+ostream& operator<<(ostream& stream, const Volume& volume)
+{
   string volumeConfig = volume.container_path();
 
   if (volume.has_host_path()) {
@@ -1191,7 +1192,8 @@ ostream& operator<<(ostream& stream, const Volume& volume) {
 }
 
 
-ostream& operator<<(ostream& stream, const Resource::DiskInfo& disk) {
+ostream& operator<<(ostream& stream, const Resource::DiskInfo& disk)
+{
   if (disk.has_persistence()) {
     stream << disk.persistence().id();
   }
@@ -1243,7 +1245,7 @@ ostream& operator<<(ostream& stream, const Resource& resource)
 
 ostream& operator<<(ostream& stream, const Resources& resources)
 {
-  mesos::Resources::const_iterator it = resources.begin();
+  Resources::const_iterator it = resources.begin();
 
   while (it != resources.end()) {
     stream << *it;


[5/5] mesos git commit: Make common public header type_utils symmetrical to v1 mesos.

Posted by jo...@apache.org.
Make common public header type_utils symmetrical to v1 mesos.

This aids in verifying the files are kept in sync.
diff include/mesos/type_utils.cpp include/mesos/v1/mesos.cpp should
result in only include and namespace differences.

Review: https://reviews.apache.org/r/38738


Project: http://git-wip-us.apache.org/repos/asf/mesos/repo
Commit: http://git-wip-us.apache.org/repos/asf/mesos/commit/cad6db90
Tree: http://git-wip-us.apache.org/repos/asf/mesos/tree/cad6db90
Diff: http://git-wip-us.apache.org/repos/asf/mesos/diff/cad6db90

Branch: refs/heads/master
Commit: cad6db90392034d4e76778c4a9b24b92f8f00f3f
Parents: bd791ca
Author: Joris Van Remoortere <jo...@gmail.com>
Authored: Thu Sep 24 17:17:58 2015 -0700
Committer: Joris Van Remoortere <jo...@gmail.com>
Committed: Thu Sep 24 17:47:27 2015 -0700

----------------------------------------------------------------------
 include/mesos/module/module.hpp       |  11 ++
 include/mesos/scheduler/scheduler.hpp |  18 +++
 include/mesos/type_utils.hpp          |  28 +----
 include/mesos/v1/mesos.hpp            | 196 ++++++++++++++++++++++++-----
 include/mesos/v1/mesos.proto          |  75 -----------
 5 files changed, 198 insertions(+), 130 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/mesos/blob/cad6db90/include/mesos/module/module.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/module/module.hpp b/include/mesos/module/module.hpp
index e83be28..6ef106e 100644
--- a/include/mesos/module/module.hpp
+++ b/include/mesos/module/module.hpp
@@ -22,4 +22,15 @@
 // ONLY USEFUL AFTER RUNNING PROTOC.
 #include <mesos/module/module.pb.h>
 
+namespace mesos {
+
+inline std::ostream& operator<<(
+    std::ostream& stream,
+    const Modules& modules)
+{
+  return stream << modules.DebugString();
+}
+
+} // namespace mesos {
+
 #endif // __MESOS_MODULE_MODULE_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/cad6db90/include/mesos/scheduler/scheduler.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/scheduler/scheduler.hpp b/include/mesos/scheduler/scheduler.hpp
index 5c31191..30de72b 100644
--- a/include/mesos/scheduler/scheduler.hpp
+++ b/include/mesos/scheduler/scheduler.hpp
@@ -22,4 +22,22 @@
 // ONLY USEFUL AFTER RUNNING PROTOC.
 #include <mesos/scheduler/scheduler.pb.h>
 
+namespace mesos {
+
+inline std::ostream& operator<<(std::ostream& stream,
+                                const scheduler::Call::Type& type)
+{
+  return stream << scheduler::Call_Type_Name(type);
+}
+
+
+inline std::ostream& operator<<(
+    std::ostream& stream,
+    const scheduler::Event::Type& type)
+{
+  return stream << scheduler::Event_Type_Name(type);
+}
+
+} // namespace mesos {
+
 #endif // __SCHEDULER_PROTO_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/cad6db90/include/mesos/type_utils.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/type_utils.hpp b/include/mesos/type_utils.hpp
index 06bf55d..1076cbd 100644
--- a/include/mesos/type_utils.hpp
+++ b/include/mesos/type_utils.hpp
@@ -353,21 +353,6 @@ inline std::ostream& operator<<(std::ostream& stream, const TaskState& state)
 }
 
 
-inline std::ostream& operator<<(std::ostream& stream,
-                                const scheduler::Call::Type& type)
-{
-  return stream << scheduler::Call_Type_Name(type);
-}
-
-
-inline std::ostream& operator<<(
-    std::ostream& stream,
-    const scheduler::Event::Type& type)
-{
-  return stream << scheduler::Event_Type_Name(type);
-}
-
-
 inline std::ostream& operator<<(
     std::ostream& stream,
     const std::vector<TaskID>& taskIds)
@@ -417,12 +402,6 @@ inline std::ostream& operator<<(
 }
 
 
-inline std::ostream& operator<<(std::ostream& stream, const Modules& modules)
-{
-  return stream << modules.DebugString();
-}
-
-
 inline std::ostream& operator<<(
     std::ostream& stream,
     const hashmap<std::string, std::string>& map)
@@ -602,11 +581,11 @@ struct hash<mesos::TaskStatus_Reason>
 
 
 template <>
-struct hash<mesos::Image_Type>
+struct hash<mesos::Image::Type>
 {
   typedef size_t result_type;
 
-  typedef mesos::Image_Type argument_type;
+  typedef mesos::Image::Type argument_type;
 
   result_type operator()(const argument_type& imageType) const
   {
@@ -621,7 +600,8 @@ struct hash<std::pair<mesos::FrameworkID, mesos::ExecutorID>>
 {
   typedef size_t result_type;
 
-  typedef std::pair<mesos::FrameworkID, mesos::ExecutorID> argument_type;
+  typedef std::pair<
+      mesos::FrameworkID, mesos::ExecutorID> argument_type;
 
   result_type operator()(const argument_type& pair) const
   {

http://git-wip-us.apache.org/repos/asf/mesos/blob/cad6db90/include/mesos/v1/mesos.hpp
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.hpp b/include/mesos/v1/mesos.hpp
index e5a0e69..fe4c4b7 100644
--- a/include/mesos/v1/mesos.hpp
+++ b/include/mesos/v1/mesos.hpp
@@ -25,6 +25,19 @@
 
 #include <mesos/v1/mesos.pb.h> // ONLY USEFUL AFTER RUNNING PROTOC.
 
+#include <stout/strings.hpp>
+
+// This file includes definitions for operators on public protobuf
+// classes (defined in mesos.proto, module.proto, etc.) that don't
+// have these operators generated by the protobuf compiler. The
+// corresponding definitions are in src/v1/type_utils.cpp.
+//
+// Mesos modules need some of the protobuf classes defined in
+// mesos.proto, module.proto, etc., and require some of these
+// operators declared in mesos.hpp. Exposing mesos.hpp
+// allows us to build modules without having a dependency on mesos
+// source tree (src/*).
+
 namespace mesos {
 namespace v1 {
 
@@ -142,15 +155,18 @@ inline bool operator==(const TaskID& left, const std::string& right)
 }
 
 
-inline bool operator!=(const TimeInfo& left, const TimeInfo& right)
-{
-  return !(left == right);
-}
-
-
-inline bool operator!=(const DurationInfo& left, const DurationInfo& right)
+/**
+ * For machines to match, both the `hostname` and `ip` must be equivalent.
+ * Hostname is not case sensitive, so it is lowercased before comparison.
+ */
+inline bool operator==(const MachineID& left, const MachineID& right)
 {
-  return !(left == right);
+  // NOTE: Both fields default to the empty string if they are not specified,
+  // so the string comparisons are safe.
+  return left.has_hostname() == right.has_hostname() &&
+    strings::lower(left.hostname()) == strings::lower(right.hostname()) &&
+    left.has_ip() == right.has_ip() &&
+    left.ip() == right.ip();
 }
 
 
@@ -178,6 +194,18 @@ inline bool operator!=(const AgentID& left, const AgentID& right)
 }
 
 
+inline bool operator!=(const TimeInfo& left, const TimeInfo& right)
+{
+  return !(left == right);
+}
+
+
+inline bool operator!=(const DurationInfo& left, const DurationInfo& right)
+{
+  return !(left == right);
+}
+
+
 inline bool operator<(const ContainerID& left, const ContainerID& right)
 {
   return left.value() < right.value();
@@ -214,12 +242,6 @@ inline bool operator<(const TaskID& left, const TaskID& right)
 }
 
 
-inline std::ostream& operator<<(std::ostream& stream, const ACLs& acls)
-{
-  return stream << acls.DebugString();
-}
-
-
 inline std::ostream& operator<<(
     std::ostream& stream,
     const ContainerID& containerId)
@@ -260,23 +282,6 @@ inline std::ostream& operator<<(
 }
 
 
-inline std::ostream& operator<<(
-    std::ostream& stream,
-    const MachineID& machineId)
-{
-  if (machineId.has_hostname() && machineId.has_ip()) {
-    return stream << machineId.hostname() << " (" << machineId.ip() << ")";
-  }
-
-  // If only a hostname is present.
-  if (machineId.has_hostname()) {
-    return stream << machineId.hostname();
-  } else { // If there is no hostname, then there is an IP.
-    return stream << "(" << machineId.ip() << ")";
-  }
-}
-
-
 inline std::ostream& operator<<(std::ostream& stream, const MasterInfo& master)
 {
   return stream << master.DebugString();
@@ -313,6 +318,23 @@ inline std::ostream& operator<<(std::ostream& stream, const TaskID& taskId)
 }
 
 
+inline std::ostream& operator<<(
+    std::ostream& stream,
+    const MachineID& machineId)
+{
+  if (machineId.has_hostname() && machineId.has_ip()) {
+    return stream << machineId.hostname() << " (" << machineId.ip() << ")";
+  }
+
+  // If only a hostname is present.
+  if (machineId.has_hostname()) {
+    return stream << machineId.hostname();
+  } else { // If there is no hostname, then there is an IP.
+    return stream << "(" << machineId.ip() << ")";
+  }
+}
+
+
 inline std::ostream& operator<<(std::ostream& stream, const TaskInfo& task)
 {
   return stream << task.DebugString();
@@ -349,6 +371,14 @@ inline std::ostream& operator<<(
 }
 
 
+inline std::ostream& operator<<(
+    std::ostream& stream,
+    const Image::Type& imageType)
+{
+  return stream << Image::Type_Name(imageType);
+}
+
+
 template <typename T>
 inline std::ostream& operator<<(
     std::ostream& stream,
@@ -365,6 +395,15 @@ inline std::ostream& operator<<(
   return stream;
 }
 
+
+inline std::ostream& operator<<(
+    std::ostream& stream,
+    const hashmap<std::string, std::string>& map)
+{
+  stream << stringify(map);
+  return stream;
+}
+
 } // namespace v1 {
 } // namespace mesos {
 
@@ -490,6 +529,101 @@ struct hash<mesos::v1::TaskID>
   }
 };
 
+
+template <>
+struct hash<mesos::v1::TaskState>
+{
+  typedef size_t result_type;
+
+  typedef mesos::v1::TaskState argument_type;
+
+  result_type operator()(const argument_type& taskState) const
+  {
+    // Use the underlying type of the enum as hash value.
+    return static_cast<size_t>(taskState);
+  }
+};
+
+
+template <>
+struct hash<mesos::v1::TaskStatus_Source>
+{
+  typedef size_t result_type;
+
+  typedef mesos::v1::TaskStatus_Source argument_type;
+
+  result_type operator()(const argument_type& source) const
+  {
+    // Use the underlying type of the enum as hash value.
+    return static_cast<size_t>(source);
+  }
+};
+
+
+template <>
+struct hash<mesos::v1::TaskStatus_Reason>
+{
+  typedef size_t result_type;
+
+  typedef mesos::v1::TaskStatus_Reason argument_type;
+
+  result_type operator()(const argument_type& reason) const
+  {
+    // Use the underlying type of the enum as hash value.
+    return static_cast<size_t>(reason);
+  }
+};
+
+
+template <>
+struct hash<mesos::v1::Image::Type>
+{
+  typedef size_t result_type;
+
+  typedef mesos::v1::Image::Type argument_type;
+
+  result_type operator()(const argument_type& imageType) const
+  {
+    // Use the underlying type of the enum as hash value.
+    return static_cast<size_t>(imageType);
+  }
+};
+
+
+template <>
+struct hash<std::pair<mesos::v1::FrameworkID, mesos::v1::ExecutorID>>
+{
+  typedef size_t result_type;
+
+  typedef std::pair<
+      mesos::v1::FrameworkID, mesos::v1::ExecutorID> argument_type;
+
+  result_type operator()(const argument_type& pair) const
+  {
+    size_t seed = 0;
+    boost::hash_combine(seed, std::hash<mesos::v1::FrameworkID>()(pair.first));
+    boost::hash_combine(seed, std::hash<mesos::v1::ExecutorID>()(pair.second));
+    return seed;
+  }
+};
+
+
+template <>
+struct hash<mesos::v1::MachineID>
+{
+  typedef size_t result_type;
+
+  typedef mesos::v1::MachineID argument_type;
+
+  result_type operator()(const argument_type& machineId) const
+  {
+    size_t seed = 0;
+    boost::hash_combine(seed, strings::lower(machineId.hostname()));
+    boost::hash_combine(seed, machineId.ip());
+    return seed;
+  }
+};
+
 } // namespace std {
 
 #endif // __MESOS_V1_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/cad6db90/include/mesos/v1/mesos.proto
----------------------------------------------------------------------
diff --git a/include/mesos/v1/mesos.proto b/include/mesos/v1/mesos.proto
index 58e5a6b..eadbc9d 100644
--- a/include/mesos/v1/mesos.proto
+++ b/include/mesos/v1/mesos.proto
@@ -1222,81 +1222,6 @@ message Credentials {
 
 
 /**
- * ACLs used for authorization.
- */
-message ACL {
-
-  // Entity is used to describe a subject(s) or an object(s) of an ACL.
-  // NOTE:
-  // To allow everyone access to an Entity set its type to 'ANY'.
-  // To deny access to an Entity set its type to 'NONE'.
-  message Entity {
-    enum Type {
-      SOME = 0;
-      ANY = 1;
-      NONE = 2;
-    }
-    optional Type type = 1 [default = SOME];
-    repeated string values = 2; // Ignored for ANY/NONE.
-  }
-
-  // ACLs.
-  message RegisterFramework {
-    // Subjects.
-    required Entity principals = 1; // Framework principals.
-
-    // Objects.
-    required Entity roles = 2; // Roles for resource offers.
-  }
-
-  message RunTask {
-    // Subjects.
-    required Entity principals = 1; // Framework principals.
-
-    // Objects.
-    required Entity users = 2; // Users to run the tasks/executors as.
-  }
-
-  // Which principals are authorized to shutdown frameworks of other
-  // principals.
-  message ShutdownFramework {
-    // Subjects.
-    required Entity principals = 1;
-
-    // Objects.
-    required Entity framework_principals = 2;
-  }
-}
-
-
-/**
- * Collection of ACL.
- *
- * Each authorization request is evaluated against the ACLs in the order
- * they are defined.
- *
- * For simplicity, the ACLs for a given action are not aggregated even
- * when they have the same subjects or objects. The first ACL that
- * matches the request determines whether that request should be
- * permitted or not. An ACL matches iff both the subjects
- * (e.g., clients, principals) and the objects (e.g., urls, users,
- * roles) of the ACL match the request.
- *
- * If none of the ACLs match the request, the 'permissive' field
- * determines whether the request should be permitted or not.
- *
- * TODO(vinod): Do aggregation of ACLs when possible.
- *
- */
-message ACLs {
-  optional bool permissive = 1 [default = true];
-  repeated ACL.RegisterFramework register_frameworks = 2;
-  repeated ACL.RunTask run_tasks = 3;
-  repeated ACL.ShutdownFramework shutdown_frameworks = 4;
-}
-
-
-/**
  * Rate (queries per second, QPS) limit for messages from a framework to master.
  * Strictly speaking they are the combined rate from all frameworks of the same
  * principal.