[
https://issues.apache.org/jira/browse/MESOS-3404?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=14952863#comment-14952863
]
Benjamin Bannier commented on MESOS-3404:
-----------------------------------------
Here is the full list of duplicates found by duplo(-fork),
{code}
% duplo src/v1/*cpp src/common/*cpp
{code}
----
{code}
src/v1/attributes.cpp(30)
src/v1/resources.cpp(38)
using std::string;
using std::vector;
namespace mesos {
namespace v1 {
src/v1/attributes.cpp(29)
src/v1/values.cpp(41)
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
namespace v1 {
src/v1/attributes.cpp(26)
src/common/attributes.cpp(26)
#include <stout/foreach.hpp>
#include <stout/strings.hpp>
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
src/v1/attributes.cpp(36)
src/common/attributes.cpp(36)
std::ostream& operator<<(std::ostream& stream, const Attribute& attribute)
stream << attribute.name() << "=";
switch (attribute.type()) {
case Value::SCALAR: stream << attribute.scalar(); break;
case Value::RANGES: stream << attribute.ranges(); break;
case Value::SET: stream << attribute.set(); break;
case Value::TEXT: stream << attribute.text(); break;
default:
LOG(FATAL) << "Unexpected Value type: " << attribute.type();
break;
return stream;
bool Attributes::operator==(const Attributes& that) const
if (size() != that.size()) {
return false;
foreach (const Attribute& attribute, attributes) {
Option<Attribute> maybeAttribute = that.get(attribute);
if (maybeAttribute.isNone()) {
return false;
const Attribute& thatAttribute = maybeAttribute.get();
switch (attribute.type()) {
case Value::SCALAR:
if (!(attribute.scalar() == thatAttribute.scalar())) {
return false;
break;
case Value::RANGES:
if (!(attribute.ranges() == thatAttribute.ranges())) {
return false;
break;
case Value::TEXT:
if (!(attribute.text() == thatAttribute.text())) {
return false;
break;
case Value::SET:
LOG(FATAL) << "Sets not supported for attributes";
return true;
const Option<Attribute> Attributes::get(const Attribute& thatAttribute) const
foreach (const Attribute& attribute, attributes) {
if (attribute.name() == thatAttribute.name() &&
attribute.type() == thatAttribute.type()) {
return attribute;
return None();
Attribute Attributes::parse(const string& name, const string& text)
Attribute attribute;
Try<Value> result = internal::values::parse(text);
if (result.isError()) {
LOG(FATAL) << "Failed to parse attribute " << name
<< " text " << text
<< " error " << result.error();
} else {
Value value = result.get();
attribute.set_name(name);
if (value.type() == Value::RANGES) {
attribute.set_type(Value::RANGES);
attribute.mutable_ranges()->MergeFrom(value.ranges());
} else if (value.type() == Value::TEXT) {
attribute.set_type(Value::TEXT);
attribute.mutable_text()->MergeFrom(value.text());
} else if (value.type() == Value::SCALAR) {
attribute.set_type(Value::SCALAR);
attribute.mutable_scalar()->MergeFrom(value.scalar());
} else {
LOG(FATAL) << "Bad type for attribute " << name
<< " text " << text
<< " type " << value.type();
return attribute;
Attributes Attributes::parse(const string& s)
Attributes attributes;
vector<string> tokens = strings::tokenize(s, ";\n");
for (size_t i = 0; i < tokens.size(); i++) {
const vector<string>& pairs = strings::split(tokens[i], ":", 2);
if (pairs.size() != 2 || pairs[0].empty() || pairs[1].empty()) {
LOG(FATAL) << "Invalid attribute key:value pair '" << tokens[i] << "'";
attributes.add(parse(pairs[0], pairs[1]));
return attributes;
bool Attributes::isValid(const Attribute& attribute)
if (!attribute.has_name() ||
attribute.name() == "" ||
!attribute.has_type() ||
!Value::Type_IsValid(attribute.type())) {
return false;
if (attribute.type() == Value::SCALAR) {
return attribute.has_scalar();
} else if (attribute.type() == Value::RANGES) {
return attribute.has_ranges();
} else if (attribute.type() == Value::TEXT) {
return attribute.has_text();
} else if (attribute.type() == Value::SET) {
return false;
return false;
template <>
Value::Scalar Attributes::get(
const string& name,
const Value::Scalar& scalar) const
foreach (const Attribute& attribute, attributes) {
if (attribute.name() == name &&
attribute.type() == Value::SCALAR) {
return attribute.scalar();
return scalar;
template <>
Value::Ranges Attributes::get(
const string& name,
const Value::Ranges& ranges) const
foreach (const Attribute& attribute, attributes) {
if (attribute.name() == name &&
attribute.type() == Value::RANGES) {
return attribute.ranges();
return ranges;
template <>
Value::Text Attributes::get(
const string& name,
const Value::Text& text) const
foreach (const Attribute& attribute, attributes) {
if (attribute.name() == name &&
attribute.type() == Value::TEXT) {
return attribute.text();
return text;
src/v1/attributes.cpp(29)
src/common/values.cpp(41)
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
src/v1/mesos.cpp(270)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(161)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/v1/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(104)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(39)
src/v1/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/v1/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(28)
src/common/type_utils.cpp(30)
bool operator==(const CommandInfo& left, const CommandInfo& right)
if (left.uris().size() != right.uris().size()) {
return false;
for (int i = 0; i < left.uris().size(); i++) {
bool found = false;
for (int j = 0; j < right.uris().size(); j++) {
if (left.uris().Get(i) == right.uris().Get(j)) {
found = true;
break;
if (!found) {
return false;
if (left.arguments().size() != right.arguments().size()) {
return false;
for (int i = 0; i < left.arguments().size(); i++) {
if (left.arguments().Get(i) != right.arguments().Get(i)) {
return false;
return left.environment() == right.environment() &&
left.value() == right.value() &&
left.user() == right.user() &&
left.shell() == right.shell();
bool operator==(const CommandInfo::URI& left, const CommandInfo::URI& right)
return left.value() == right.value() &&
left.executable() == right.executable() &&
left.extract() == right.extract();
bool operator==(const Credential& left, const Credential& right)
return left.principal() == right.principal() &&
left.secret() == right.secret();
bool operator==(
const Environment::Variable& left,
const Environment::Variable& right)
return left.name() == right.name() && left.value() == right.value();
bool operator==(const Environment& left, const Environment& right)
if (left.variables().size() != right.variables().size()) {
return false;
for (int i = 0; i < left.variables().size(); i++) {
bool found = false;
for (int j = 0; j < right.variables().size(); j++) {
if (left.variables().Get(i) == right.variables().Get(j)) {
found = true;
break;
if (!found) {
return false;
return true;
bool operator==(const Volume& left, const Volume& right)
return left.container_path() == right.container_path() &&
left.host_path() == right.host_path() &&
left.mode() == right.mode();
bool operator==(const URL& left, const URL& right)
return left.SerializeAsString() == right.SerializeAsString();
bool operator==(
const ContainerInfo::DockerInfo::PortMapping& left,
const ContainerInfo::DockerInfo::PortMapping& right)
return left.host_port() == right.host_port() &&
left.container_port() == right.container_port() &&
left.protocol() == right.protocol();
bool operator==(const Parameter& left, const Parameter& right)
return left.key() == right.key() && left.value() == right.value();
bool operator==(
const ContainerInfo::DockerInfo& left,
const ContainerInfo::DockerInfo& right)
if (left.port_mappings().size() != right.port_mappings().size()) {
return false;
for (int i = 0; i < left.port_mappings().size(); i++) {
bool found = false;
for (int j = 0; j < right.port_mappings().size(); j++) {
if (left.port_mappings().Get(i) == right.port_mappings().Get(j)) {
found = true;
break;
if (!found) {
return false;
if (left.parameters().size() != right.parameters().size()) {
return false;
for (int i = 0; i < left.parameters().size(); i++) {
bool found = false;
for (int j = 0; j < right.parameters().size(); j++) {
if (left.parameters().Get(i) == right.parameters().Get(j)) {
found = true;
break;
if (!found) {
return false;
return left.image() == right.image() &&
left.network() == right.network() &&
left.privileged() == right.privileged() &&
left.force_pull_image() == right.force_pull_image();
bool operator==(const ContainerInfo& left, const ContainerInfo& right)
if (left.volumes().size() != right.volumes().size()) {
return false;
for (int i = 0; i < left.volumes().size(); i++) {
bool found = false;
for (int j = 0; j < right.volumes().size(); j++) {
if (left.volumes().Get(i) == right.volumes().Get(j)) {
found = true;
break;
if (!found) {
return false;
return left.type() == right.type() &&
left.hostname() == right.hostname() &&
left.docker() == right.docker();
bool operator==(const Port& left, const Port& right)
return left.number() == right.number() &&
left.name() == right.name() &&
left.protocol() == right.protocol();
bool operator==(const Ports& left, const Ports& right)
if (left.ports().size() != right.ports().size()) {
return false;
for (int i = 0; i < left.ports().size(); i++) {
bool found = false;
for (int j = 0; j < right.ports().size(); j++) {
if (left.ports().Get(i) == right.ports().Get(j)) {
found = true;
break;
if (!found) {
return false;
return true;
bool operator==(const Label& left, const Label& right)
return left.key() == right.key() && left.value() == right.value();
bool operator==(const Labels& left, const Labels& right)
if (left.labels().size() != right.labels().size()) {
return false;
for (int i = 0; i < left.labels().size(); i++) {
bool found = false;
for (int j = 0; j < right.labels().size(); j++) {
if (left.labels().Get(i) == right.labels().Get(j)) {
found = true;
break;
if (!found) {
return false;
return true;
bool operator==(const DiscoveryInfo& left, const DiscoveryInfo& right)
return left.visibility() == right.visibility() &&
left.name() == right.name() &&
left.environment() == right.environment() &&
left.location() == right.location() &&
left.version() == right.version() &&
left.ports() == right.ports() &&
left.labels() == right.labels();
bool operator==(const ExecutorInfo& left, const ExecutorInfo& right)
return left.executor_id() == right.executor_id() &&
left.data() == right.data() &&
Resources(left.resources()) == Resources(right.resources()) &&
left.command() == right.command() &&
left.framework_id() == right.framework_id() &&
left.name() == right.name() &&
left.source() == right.source() &&
left.container() == right.container() &&
left.discovery() == right.discovery();
bool operator==(const MasterInfo& left, const MasterInfo& right)
return left.id() == right.id() &&
left.ip() == right.ip() &&
left.port() == right.port() &&
left.pid() == right.pid() &&
left.hostname() == right.hostname() &&
left.version() == right.version();
bool operator==(
const ResourceStatistics& left,
const ResourceStatistics& right)
return left.SerializeAsString() == right.SerializeAsString();
src/v1/mesos.cpp(330)
src/common/type_utils.cpp(332)
return left.hostname() == right.hostname() &&
Resources(left.resources()) == Resources(right.resources()) &&
Attributes(left.attributes()) == Attributes(right.attributes()) &&
left.id() == right.id() &&
src/v1/mesos.cpp(334)
src/common/type_utils.cpp(337)
left.port() == right.port();
bool operator==(const TaskStatus& left, const TaskStatus& right)
return left.task_id() == right.task_id() &&
left.state() == right.state() &&
left.data() == right.data() &&
left.message() == right.message() &&
src/v1/mesos.cpp(346)
src/common/type_utils.cpp(349)
left.timestamp() == right.timestamp() &&
left.executor_id() == right.executor_id() &&
left.healthy() == right.healthy() &&
left.source() == right.source() &&
left.reason() == right.reason() &&
left.uuid() == right.uuid();
bool operator!=(const TaskStatus& left, const TaskStatus& right)
return !(left == right);
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(240)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(206)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(161)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(270)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(240)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(206)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(179)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(161)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(104)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(104)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/mesos.cpp(39)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/v1/mesos.cpp(39)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/v1/resources.cpp(38)
src/v1/values.cpp(42)
using std::string;
using std::vector;
namespace mesos {
namespace v1 {
src/v1/resources.cpp(37)
src/common/http.cpp(37)
using std::set;
using std::string;
using std::vector;
namespace mesos {
src/v1/resources.cpp(18)
src/common/resources.cpp(18)
#include <stdint.h>
#include <set>
#include <string>
#include <vector>
#include <glog/logging.h>
src/v1/resources.cpp(30)
src/common/resources.cpp(30)
#include <stout/foreach.hpp>
#include <stout/hashmap.hpp>
#include <stout/lambda.hpp>
#include <stout/strings.hpp>
using std::map;
using std::ostream;
using std::set;
using std::string;
using std::vector;
namespace mesos {
src/v1/resources.cpp(49)
src/common/resources.cpp(48)
bool operator==(
const Resource::ReservationInfo& left,
const Resource::ReservationInfo& right)
return left.principal() == right.principal();
bool operator!=(
const Resource::ReservationInfo& left,
const Resource::ReservationInfo& right)
return !(left == right);
bool operator==(const Resource::DiskInfo& left, const Resource::DiskInfo& right)
if (left.has_persistence() != right.has_persistence()) {
return false;
if (left.has_persistence()) {
return left.persistence().id() == right.persistence().id();
return true;
bool operator!=(const Resource::DiskInfo& left, const Resource::DiskInfo& right)
return !(left == right);
bool operator==(const Resource& left, const Resource& right)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
if (left.has_revocable() != right.has_revocable()) {
return false;
if (left.type() == Value::SCALAR) {
return left.scalar() == right.scalar();
} else if (left.type() == Value::RANGES) {
return left.ranges() == right.ranges();
} else if (left.type() == Value::SET) {
return left.set() == right.set();
} else {
return false;
bool operator!=(const Resource& left, const Resource& right)
return !(left == right);
namespace internal {
static bool addable(const Resource& left, const Resource& right)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
if (left.has_disk() && left.disk().has_persistence()) {
return false;
if (left.has_revocable() != right.has_revocable()) {
return false;
return true;
static bool subtractable(const Resource& left, const Resource& right)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
if (left.has_disk() && left.disk().has_persistence() && left != right) {
return false;
if (left.has_revocable() != right.has_revocable()) {
return false;
return true;
static bool contains(const Resource& left, const Resource& right)
if (!subtractable(left, right)) {
return false;
if (left.type() == Value::SCALAR) {
return right.scalar() <= left.scalar();
} else if (left.type() == Value::RANGES) {
return right.ranges() <= left.ranges();
} else if (left.type() == Value::SET) {
return right.set() <= left.set();
} else {
return false;
Resource& operator+=(Resource& left, const Resource& right)
if (left.type() == Value::SCALAR) {
*left.mutable_scalar() += right.scalar();
} else if (left.type() == Value::RANGES) {
*left.mutable_ranges() += right.ranges();
} else if (left.type() == Value::SET) {
*left.mutable_set() += right.set();
return left;
Resource operator+(const Resource& left, const Resource& right)
Resource result = left;
result += right;
return result;
Resource& operator-=(Resource& left, const Resource& right)
if (left.type() == Value::SCALAR) {
*left.mutable_scalar() -= right.scalar();
} else if (left.type() == Value::RANGES) {
*left.mutable_ranges() -= right.ranges();
} else if (left.type() == Value::SET) {
*left.mutable_set() -= right.set();
return left;
Resource operator-(const Resource& left, const Resource& right)
Resource result = left;
result -= right;
return result;
Try<Resource> Resources::parse(
const string& name,
const string& value,
const string& role)
Try<Value> result = internal::values::parse(value);
if (result.isError()) {
return Error(
"Failed to parse resource " + name +
" value " + value + " error " + result.error());
Resource resource;
Value _value = result.get();
resource.set_name(name);
resource.set_role(role);
if (_value.type() == Value::SCALAR) {
resource.set_type(Value::SCALAR);
resource.mutable_scalar()->CopyFrom(_value.scalar());
} else if (_value.type() == Value::RANGES) {
resource.set_type(Value::RANGES);
resource.mutable_ranges()->CopyFrom(_value.ranges());
} else if (_value.type() == Value::SET) {
resource.set_type(Value::SET);
resource.mutable_set()->CopyFrom(_value.set());
} else {
return Error(
"Bad type for resource " + name + " value " + value +
" type " + Value::Type_Name(_value.type()));
return resource;
Try<Resources> Resources::parse(
const string& text,
const string& defaultRole)
Resources resources;
hashmap<string, Value_Type> nameTypes;
foreach (const string& token, strings::tokenize(text, ";")) {
vector<string> pair = strings::tokenize(token, ":");
if (pair.size() != 2) {
return Error("Bad value for resources, missing or extra ':' in " + token);
string name;
string role;
size_t openParen = pair[0].find("(");
if (openParen == string::npos) {
name = strings::trim(pair[0]);
role = defaultRole;
} else {
size_t closeParen = pair[0].find(")");
if (closeParen == string::npos || closeParen < openParen) {
return Error(
"Bad value for resources, mismatched parentheses in " + token);
name = strings::trim(pair[0].substr(0, openParen));
role = strings::trim(pair[0].substr(
openParen + 1,
closeParen - openParen - 1));
Try<Resource> resource = Resources::parse(name, pair[1], role);
if (resource.isError()) {
return Error(resource.error());
if (nameTypes.contains(name) && nameTypes[name] != resource.get().type()) {
return Error(
"Resources with the same name ('" + name + "') but different types "
"are not allowed");
} else if (!nameTypes.contains(name)) {
nameTypes[name] = resource.get().type();
resources += resource.get();
return resources;
Option<Error> Resources::validate(const Resource& resource)
if (resource.name().empty()) {
return Error("Empty resource name");
if (!Value::Type_IsValid(resource.type())) {
return Error("Invalid resource type");
if (resource.type() == Value::SCALAR) {
if (!resource.has_scalar() ||
resource.has_ranges() ||
resource.has_set()) {
return Error("Invalid scalar resource");
if (resource.scalar().value() < 0) {
return Error("Invalid scalar resource: value < 0");
} else if (resource.type() == Value::RANGES) {
if (resource.has_scalar() ||
!resource.has_ranges() ||
resource.has_set()) {
return Error("Invalid ranges resource");
for (int i = 0; i < resource.ranges().range_size(); i++) {
const Value::Range& range = resource.ranges().range(i);
if (range.begin() > range.end()) {
return Error("Invalid ranges resource: begin > end");
for (int j = i + 1; j < resource.ranges().range_size(); j++) {
if (range.begin() <= resource.ranges().range(j).begin() &&
resource.ranges().range(j).begin() <= range.end()) {
return Error("Invalid ranges resource: overlapping ranges");
} else if (resource.type() == Value::SET) {
if (resource.has_scalar() ||
resource.has_ranges() ||
!resource.has_set()) {
return Error("Invalid set resource");
for (int i = 0; i < resource.set().item_size(); i++) {
const string& item = resource.set().item(i);
for (int j = i + 1; j < resource.set().item_size(); j++) {
if (item == resource.set().item(j)) {
return Error("Invalid set resource: duplicated elements");
} else {
return Error("Unsupported resource type");
if (resource.has_disk() && resource.name() != "disk") {
return Error(
"DiskInfo should not be set for " + resource.name() + " resource");
if (resource.role() == "*" && resource.has_reservation()) {
return Error(
"Invalid reservation: role \"*\" cannot be dynamically reserved");
return None();
Option<Error> Resources::validate(
const google::protobuf::RepeatedPtrField<Resource>& resources)
foreach (const Resource& resource, resources) {
Option<Error> error = validate(resource);
if (error.isSome()) {
return Error(
"Resource '" + stringify(resource) +
"' is invalid: " + error.get().message);
return None();
bool Resources::isEmpty(const Resource& resource)
if (resource.type() == Value::SCALAR) {
return resource.scalar().value() == 0;
} else if (resource.type() == Value::RANGES) {
return resource.ranges().range_size() == 0;
} else if (resource.type() == Value::SET) {
return resource.set().item_size() == 0;
} else {
return false;
bool Resources::isPersistentVolume(const Resource& resource)
return resource.has_disk() && resource.disk().has_persistence();
bool Resources::isReserved(
const Resource& resource,
const Option<std::string>& role)
if (role.isSome()) {
return !isUnreserved(resource) && role.get() == resource.role();
} else {
return !isUnreserved(resource);
bool Resources::isUnreserved(const Resource& resource)
return resource.role() == "*" && !resource.has_reservation();
bool Resources::isDynamicallyReserved(const Resource& resource)
return resource.has_reservation();
bool Resources::isRevocable(const Resource& resource)
return resource.has_revocable();
Resources::Resources(const Resource& resource)
*this += resource;
Resources::Resources(const vector<Resource>& _resources)
foreach (const Resource& resource, _resources) {
*this += resource;
Resources::Resources(
const google::protobuf::RepeatedPtrField<Resource>& _resources)
foreach (const Resource& resource, _resources) {
*this += resource;
bool Resources::contains(const Resources& that) const
Resources remaining = *this;
foreach (const Resource& resource, that.resources) {
if (!remaining._contains(resource)) {
return false;
remaining -= resource;
return true;
bool Resources::contains(const Resource& that) const
return validate(that).isNone() && _contains(that);
Resources Resources::filter(
const lambda::function<bool(const Resource&)>& predicate) const
Resources result;
foreach (const Resource& resource, resources) {
if (predicate(resource)) {
result += resource;
return result;
hashmap<string, Resources> Resources::reserved() const
hashmap<string, Resources> result;
foreach (const Resource& resource, resources) {
if (isReserved(resource)) {
result[resource.role()] += resource;
return result;
Resources Resources::reserved(const string& role) const
return filter(lambda::bind(isReserved, lambda::_1, role));
Resources Resources::unreserved() const
return filter(isUnreserved);
Resources Resources::persistentVolumes() const
return filter(isPersistentVolume);
Resources Resources::revocable() const
return filter(isRevocable);
Resources Resources::flatten(
const string& role,
const Option<Resource::ReservationInfo>& reservation) const
Resources flattened;
foreach (Resource resource, resources) {
resource.set_role(role);
if (reservation.isNone()) {
resource.clear_reservation();
} else {
resource.mutable_reservation()->CopyFrom(reservation.get());
flattened += resource;
return flattened;
static bool any(const Resource&) { return true; }
Option<Resources> Resources::find(const Resource& target) const
Resources found;
Resources total = *this;
Resources remaining = Resources(target).flatten();
vector<lambda::function<bool(const Resource&)>> predicates = {
lambda::bind(isReserved, lambda::_1, target.role()),
isUnreserved,
any
foreach (const auto& predicate, predicates) {
foreach (const Resource& resource, total.filter(predicate)) {
Resources flattened = Resources(resource).flatten();
if (flattened.contains(remaining)) {
if (!resource.has_reservation()) {
return found + remaining.flatten(resource.role());
} else {
return found +
remaining.flatten(resource.role(), resource.reservation());
} else if (remaining.contains(flattened)) {
found += resource;
total -= resource;
remaining -= flattened;
break;
return None();
Option<Resources> Resources::find(const Resources& targets) const
Resources total;
foreach (const Resource& target, targets) {
Option<Resources> found = find(target);
if (found.isNone()) {
return None();
total += found.get();
return total;
Try<Resources> Resources::apply(const Offer::Operation& operation) const
Resources result = *this;
switch (operation.type()) {
case Offer::Operation::LAUNCH:
break;
case Offer::Operation::RESERVE: {
Option<Error> error = validate(operation.reserve().resources());
if (error.isSome()) {
return Error("Invalid RESERVE Operation: " + error.get().message);
foreach (const Resource& reserved, operation.reserve().resources()) {
if (!Resources::isReserved(reserved)) {
return Error("Invalid RESERVE Operation: Resource must be reserved");
} else if (!reserved.has_reservation()) {
return Error("Invalid RESERVE Operation: Missing 'reservation'");
Resources unreserved = Resources(reserved).flatten();
if (!result.contains(unreserved)) {
return Error("Invalid RESERVE Operation: " + stringify(result) +
" does not contain " + stringify(unreserved));
result -= unreserved;
result += reserved;
break;
case Offer::Operation::UNRESERVE: {
Option<Error> error = validate(operation.unreserve().resources());
if (error.isSome()) {
return Error("Invalid UNRESERVE Operation: " + error.get().message);
foreach (const Resource& reserved, operation.unreserve().resources()) {
if (!Resources::isReserved(reserved)) {
return Error("Invalid UNRESERVE Operation: Resource is not reserved");
} else if (!reserved.has_reservation()) {
return Error("Invalid UNRESERVE Operation: Missing 'reservation'");
if (!result.contains(reserved)) {
return Error("Invalid UNRESERVE Operation: " + stringify(result) +
" does not contain " + stringify(reserved));
Resources unreserved = Resources(reserved).flatten();
result -= reserved;
result += unreserved;
break;
case Offer::Operation::CREATE: {
Option<Error> error = validate(operation.create().volumes());
if (error.isSome()) {
return Error("Invalid CREATE Operation: " + error.get().message);
foreach (const Resource& volume, operation.create().volumes()) {
if (!volume.has_disk()) {
return Error("Invalid CREATE Operation: Missing 'disk'");
} else if (!volume.disk().has_persistence()) {
return Error("Invalid CREATE Operation: Missing 'persistence'");
Resource stripped = volume;
stripped.clear_disk();
if (!result.contains(stripped)) {
return Error("Invalid CREATE Operation: Insufficient disk resources");
result -= stripped;
result += volume;
break;
case Offer::Operation::DESTROY: {
Option<Error> error = validate(operation.destroy().volumes());
if (error.isSome()) {
return Error("Invalid DESTROY Operation: " + error.get().message);
foreach (const Resource& volume, operation.destroy().volumes()) {
if (!volume.has_disk()) {
return Error("Invalid DESTROY Operation: Missing 'disk'");
} else if (!volume.disk().has_persistence()) {
return Error("Invalid DESTROY Operation: Missing 'persistence'");
if (!result.contains(volume)) {
return Error(
"Invalid DESTROY Operation: Persistent volume does not exist");
Resource stripped = volume;
stripped.clear_disk();
result -= volume;
result += stripped;
break;
default:
return Error("Unknown offer operation " + stringify(operation.type()));
CHECK(result.cpus() == cpus() &&
result.mem() == mem() &&
result.disk() == disk() &&
result.ports() == ports());
return result;
template <>
Option<Value::Scalar> Resources::get(const string& name) const
Value::Scalar total;
bool found = false;
foreach (const Resource& resource, resources) {
if (resource.name() == name &&
resource.type() == Value::SCALAR) {
total += resource.scalar();
found = true;
if (found) {
return total;
return None();
template <>
Option<Value::Set> Resources::get(const string& name) const
Value::Set total;
bool found = false;
foreach (const Resource& resource, resources) {
if (resource.name() == name &&
resource.type() == Value::SET) {
total += resource.set();
found = true;
if (found) {
return total;
return None();
template <>
Option<Value::Ranges> Resources::get(const string& name) const
Value::Ranges total;
bool found = false;
foreach (const Resource& resource, resources) {
if (resource.name() == name &&
resource.type() == Value::RANGES) {
total += resource.ranges();
found = true;
if (found) {
return total;
return None();
Resources Resources::get(const string& name) const
return filter([=](const Resource& resource) {
return resource.name() == name;
});
Resources Resources::scalars() const
return filter([=](const Resource& resource) {
return resource.type() == Value::SCALAR;
});
set<string> Resources::names() const
set<string> result;
foreach (const Resource& resource, resources) {
result.insert(resource.name());
return result;
map<string, Value_Type> Resources::types() const
map<string, Value_Type> result;
foreach (const Resource& resource, resources) {
result[resource.name()] = resource.type();
return result;
Option<double> Resources::cpus() const
Option<Value::Scalar> value = get<Value::Scalar>("cpus");
if (value.isSome()) {
return value.get().value();
} else {
return None();
Option<Bytes> Resources::mem() const
Option<Value::Scalar> value = get<Value::Scalar>("mem");
if (value.isSome()) {
return Megabytes(static_cast<uint64_t>(value.get().value()));
} else {
return None();
Option<Bytes> Resources::disk() const
Option<Value::Scalar> value = get<Value::Scalar>("disk");
if (value.isSome()) {
return Megabytes(static_cast<uint64_t>(value.get().value()));
} else {
return None();
Option<Value::Ranges> Resources::ports() const
Option<Value::Ranges> value = get<Value::Ranges>("ports");
if (value.isSome()) {
return value.get();
} else {
return None();
Option<Value::Ranges> Resources::ephemeral_ports() const
Option<Value::Ranges> value = get<Value::Ranges>("ephemeral_ports");
if (value.isSome()) {
return value.get();
} else {
return None();
bool Resources::_contains(const Resource& that) const
foreach (const Resource& resource, resources) {
if (internal::contains(resource, that)) {
return true;
return false;
Resources::operator const google::protobuf::RepeatedPtrField<Resource>&() const
return resources;
bool Resources::operator==(const Resources& that) const
return this->contains(that) && that.contains(*this);
bool Resources::operator!=(const Resources& that) const
return !(*this == that);
Resources Resources::operator+(const Resource& that) const
Resources result = *this;
result += that;
return result;
Resources Resources::operator+(const Resources& that) const
Resources result = *this;
result += that;
return result;
Resources& Resources::operator+=(const Resource& that)
if (validate(that).isNone() && !isEmpty(that)) {
bool found = false;
foreach (Resource& resource, resources) {
if (internal::addable(resource, that)) {
resource += that;
found = true;
break;
if (!found) {
resources.Add()->CopyFrom(that);
return *this;
Resources& Resources::operator+=(const Resources& that)
foreach (const Resource& resource, that.resources) {
*this += resource;
return *this;
Resources Resources::operator-(const Resource& that) const
Resources result = *this;
result -= that;
return result;
Resources Resources::operator-(const Resources& that) const
Resources result = *this;
result -= that;
return result;
Resources& Resources::operator-=(const Resource& that)
if (validate(that).isNone() && !isEmpty(that)) {
for (int i = 0; i < resources.size(); i++) {
Resource* resource = resources.Mutable(i);
if (internal::subtractable(*resource, that)) {
*resource -= that;
if (validate(*resource).isSome() || isEmpty(*resource)) {
resources.DeleteSubrange(i, 1);
break;
return *this;
Resources& Resources::operator-=(const Resources& that)
foreach (const Resource& resource, that.resources) {
*this -= resource;
return *this;
ostream& operator<<(ostream& stream, const Volume& volume)
string volumeConfig = volume.container_path();
if (volume.has_host_path()) {
volumeConfig = volume.host_path() + ":" + volumeConfig;
if (volume.has_mode()) {
switch (volume.mode()) {
case Volume::RW: volumeConfig += ":rw"; break;
case Volume::RO: volumeConfig += ":ro"; break;
default:
LOG(FATAL) << "Unknown Volume mode: " << volume.mode();
break;
stream << volumeConfig;
return stream;
ostream& operator<<(ostream& stream, const Resource::DiskInfo& disk)
if (disk.has_persistence()) {
stream << disk.persistence().id();
if (disk.has_volume()) {
stream << ":" << disk.volume();
return stream;
ostream& operator<<(ostream& stream, const Resource& resource)
stream << resource.name();
stream << "(" << resource.role();
if (resource.has_reservation()) {
stream << ", " << resource.reservation().principal();
stream << ")";
if (resource.has_disk()) {
stream << "[" << resource.disk() << "]";
if (resource.has_revocable()) {
stream << "{REV}";
stream << ":";
switch (resource.type()) {
case Value::SCALAR: stream << resource.scalar(); break;
case Value::RANGES: stream << resource.ranges(); break;
case Value::SET: stream << resource.set(); break;
default:
LOG(FATAL) << "Unexpected Value type: " << resource.type();
break;
return stream;
ostream& operator<<(ostream& stream, const Resources& resources)
Resources::const_iterator it = resources.begin();
while (it != resources.end()) {
stream << *it;
if (++it != resources.end()) {
stream << "; ";
return stream;
src/v1/resources.cpp(1007)
src/common/resources.cpp(995)
if (value.isSome()) {
return Megabytes(static_cast<uint64_t>(value.get().value()));
} else {
return None();
src/v1/resources.cpp(1029)
src/common/resources.cpp(1017)
if (value.isSome()) {
return value.get();
} else {
return None();
src/v1/resources.cpp(910)
src/common/resources.cpp(887)
found = true;
if (found) {
return total;
return None();
template <>
src/v1/resources.cpp(932)
src/common/resources.cpp(909)
found = true;
if (found) {
return total;
return None();
src/v1/resources.cpp(197)
src/common/resources.cpp(145)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/resources.cpp(224)
src/common/resources.cpp(174)
return false;
if (left.has_revocable() != right.has_revocable()) {
return false;
return true;
src/v1/resources.cpp(932)
src/common/resources.cpp(887)
found = true;
if (found) {
return total;
return None();
src/v1/resources.cpp(146)
src/common/resources.cpp(91)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/resources.cpp(197)
src/common/resources.cpp(91)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/resources.cpp(996)
src/common/resources.cpp(1006)
if (value.isSome()) {
return Megabytes(static_cast<uint64_t>(value.get().value()));
} else {
return None();
src/v1/resources.cpp(1018)
src/common/resources.cpp(1028)
if (value.isSome()) {
return value.get();
} else {
return None();
src/v1/resources.cpp(888)
src/common/resources.cpp(909)
found = true;
if (found) {
return total;
return None();
template <>
src/v1/resources.cpp(910)
src/common/resources.cpp(931)
found = true;
if (found) {
return total;
return None();
src/v1/resources.cpp(146)
src/common/resources.cpp(196)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/resources.cpp(175)
src/common/resources.cpp(223)
return false;
if (left.has_revocable() != right.has_revocable()) {
return false;
return true;
src/v1/resources.cpp(888)
src/common/resources.cpp(931)
found = true;
if (found) {
return total;
return None();
src/v1/resources.cpp(92)
src/common/resources.cpp(145)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/resources.cpp(92)
src/common/resources.cpp(196)
if (left.name() != right.name() ||
left.type() != right.type() ||
left.role() != right.role()) {
return false;
if (left.has_reservation() != right.has_reservation()) {
return false;
if (left.has_reservation() && left.reservation() != right.reservation()) {
return false;
if (left.has_disk() != right.has_disk()) {
return false;
if (left.has_disk() && left.disk() != right.disk()) {
return false;
src/v1/values.cpp(41)
src/common/attributes.cpp(29)
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
src/v1/values.cpp(310)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(310)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(310)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(310)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(409)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(310)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(434)
src/common/type_utils.cpp(272)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(409)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(434)
src/common/type_utils.cpp(242)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(409)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(310)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(434)
src/common/type_utils.cpp(208)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(409)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(409)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(434)
src/common/type_utils.cpp(181)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(310)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(434)
src/common/type_utils.cpp(163)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(409)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(434)
src/common/type_utils.cpp(106)
found = true;
break;
if (!found) {
return false;
return true;
src/v1/values.cpp(409)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(434)
src/common/type_utils.cpp(41)
found = true;
break;
if (!found) {
return false;
src/v1/values.cpp(18)
src/common/values.cpp(18)
#include <stdint.h>
#include <algorithm>
#include <initializer_list>
#include <ostream>
#include <string>
#include <tuple>
#include <utility>
#include <vector>
#include <glog/logging.h>
#include <boost/lexical_cast.hpp>
src/v1/values.cpp(35)
src/common/values.cpp(35)
#include <stout/error.hpp>
#include <stout/foreach.hpp>
#include <stout/strings.hpp>
using std::max;
using std::min;
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
src/v1/values.cpp(48)
src/common/values.cpp(47)
ostream& operator<<(ostream& stream, const Value::Scalar& scalar)
return stream << scalar.value();
bool operator==(const Value::Scalar& left, const Value::Scalar& right)
return left.value() == right.value();
bool operator<=(const Value::Scalar& left, const Value::Scalar& right)
return left.value() <= right.value();
Value::Scalar operator+(const Value::Scalar& left, const Value::Scalar& right)
Value::Scalar result;
result.set_value(left.value() + right.value());
return result;
Value::Scalar operator-(const Value::Scalar& left, const Value::Scalar& right)
Value::Scalar result;
result.set_value(left.value() - right.value());
return result;
Value::Scalar& operator+=(Value::Scalar& left, const Value::Scalar& right)
left.set_value(left.value() + right.value());
return left;
Value::Scalar& operator-=(Value::Scalar& left, const Value::Scalar& right)
left.set_value(left.value() - right.value());
return left;
namespace internal {
struct Range
uint64_t start;
uint64_t end;
void coalesce(Value::Ranges* result, vector<Range> ranges)
if (ranges.empty()) {
result->clear_range();
return;
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);
});
CHECK(!ranges.empty());
int count = 1;
Range current = ranges.front();
foreach (const Range& range, ranges) {
if (range.start == current.start && range.end == current.end) {
continue;
if (range.start == current.start && range.end > current.end) {
current.end = range.end;
} else if (range.start > current.start) {
if (range.start <= current.end + 1) {
current.end = max(current.end, range.end);
} else {
ranges[count - 1] = current;
++count;
current = range;
ranges[count - 1] = current;
CHECK(count <= static_cast<int>(ranges.size()));
if (count < result->range_size()) {
result->mutable_range()->DeleteSubrange(
count, result->range_size() - count);
result->mutable_range()->Reserve(count);
for (int i = 0; i < count; ++i) {
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);
void coalesce(
Value::Ranges* result,
std::initializer_list<Value::Ranges> addedRanges)
size_t rangesSum = result->range_size();
foreach (const Value::Ranges& range, addedRanges) {
rangesSum += range.range_size();
vector<internal::Range> ranges;
ranges.reserve(rangesSum);
auto fill = [&ranges](const Value::Ranges& inputs) {
foreach (const Value::Range& range, inputs.range()) {
ranges.push_back({range.begin(), range.end()});
fill(*result);
foreach (const Value::Ranges& range, addedRanges) {
fill(range);
internal::coalesce(result, std::move(ranges));
void coalesce(Value::Ranges* result)
coalesce(result, {Value::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& removal)
vector<internal::Range> ranges;
ranges.reserve(_ranges->range_size());
foreach (const Value::Range& range, _ranges->range()) {
if (range.begin() >= removal.begin() && range.end() <= removal.end()) {
continue;
if (range.begin() < removal.begin() && range.end() > removal.end()) {
ranges.emplace_back(internal::Range{range.begin(), removal.begin() - 1});
ranges.emplace_back(internal::Range{removal.end() + 1, range.end()});
if (range.end() < removal.begin() || range.begin() > removal.end()) {
ranges.emplace_back(internal::Range{range.begin(), range.end()});
} else {
if (range.end() > removal.end()) {
ranges.emplace_back(internal::Range{removal.end() + 1, range.end()});
} else {
CHECK(range.begin() < removal.begin());
ranges.emplace_back(
internal::Range{range.begin(), removal.begin() - 1});
internal::coalesce(_ranges, std::move(ranges));
ostream& operator<<(ostream& stream, const Value::Ranges& ranges)
stream << "[";
for (int i = 0; i < ranges.range_size(); i++) {
stream << ranges.range(i).begin() << "-" << ranges.range(i).end();
if (i + 1 < ranges.range_size()) {
stream << ", ";
stream << "]";
return stream;
bool operator==(const Value::Ranges& _left, const Value::Ranges& _right)
Value::Ranges left;
coalesce(&left, {_left});
Value::Ranges right;
coalesce(&right, {_right});
if (left.range_size() == right.range_size()) {
for (int i = 0; i < left.range_size(); i++) {
bool found = false;
for (int j = 0; j < right.range_size(); j++) {
if (left.range(i).begin() == right.range(j).begin() &&
left.range(i).end() == right.range(j).end()) {
found = true;
break;
if (!found) {
return false;
return true;
return false;
bool operator<=(const Value::Ranges& _left, const Value::Ranges& _right)
Value::Ranges left;
coalesce(&left, {_left});
Value::Ranges right;
coalesce(&right, {_right});
for (int i = 0; i < left.range_size(); i++) {
bool matched = false;
for (int j = 0; j < right.range_size(); j++) {
if (left.range(i).begin() >= right.range(j).begin() &&
left.range(i).end() <= right.range(j).end()) {
matched = true;
break;
if (!matched) {
return false;
return true;
Value::Ranges operator+(const Value::Ranges& left, const Value::Ranges& right)
Value::Ranges result;
coalesce(&result, {left, right});
return result;
Value::Ranges operator-(const Value::Ranges& left, const Value::Ranges& right)
Value::Ranges result;
coalesce(&result, {left});
return result -= right;
Value::Ranges& operator+=(Value::Ranges& left, const Value::Ranges& right)
coalesce(&left, {right});
return left;
Value::Ranges& operator-=(Value::Ranges& left, const Value::Ranges& right)
coalesce(&left);
for (int i = 0; i < right.range_size(); ++i) {
remove(&left, right.range(i));
return left;
ostream& operator<<(ostream& stream, const Value::Set& set)
stream << "{";
for (int i = 0; i < set.item_size(); i++) {
stream << set.item(i);
if (i + 1 < set.item_size()) {
stream << ", ";
stream << "}";
return stream;
bool operator==(const Value::Set& left, const Value::Set& right)
if (left.item_size() == right.item_size()) {
for (int i = 0; i < left.item_size(); i++) {
bool found = false;
for (int j = 0; j < right.item_size(); j++) {
if (left.item(i) == right.item(i)) {
found = true;
break;
if (!found) {
return false;
return true;
return false;
bool operator<=(const Value::Set& left, const Value::Set& right)
if (left.item_size() <= right.item_size()) {
for (int i = 0; i < left.item_size(); i++) {
bool found = false;
for (int j = 0; j < right.item_size(); j++) {
if (left.item(i) == right.item(j)) {
found = true;
break;
if (!found) {
return false;
return true;
return false;
Value::Set operator+(const Value::Set& left, const Value::Set& right)
Value::Set result;
for (int i = 0; i < left.item_size(); i++) {
result.add_item(left.item(i));
for (int i = 0; i < right.item_size(); i++) {
bool found = false;
for (int j = 0; j < result.item_size(); j++) {
if (right.item(i) == result.item(j)) {
found = true;
break;
if (!found) {
result.add_item(right.item(i));
return result;
Value::Set operator-(const Value::Set& left, const Value::Set& right)
Value::Set result;
for (int i = 0; i < left.item_size(); i++) {
bool found = false;
for (int j = 0; j < right.item_size(); j++) {
if (left.item(i) == right.item(j)) {
found = true;
break;
if (!found) {
result.add_item(left.item(i));
return result;
Value::Set& operator+=(Value::Set& left, const Value::Set& right)
for (int i = 0; i < right.item_size(); i++) {
bool found = false;
for (int j = 0; j < left.item_size(); j++) {
if (right.item(i) == left.item(j)) {
found = true;
break;
if (!found) {
left.add_item(right.item(i));
return left;
Value::Set& operator-=(Value::Set& left, const Value::Set& right)
for (int i = 0; i < right.item_size(); i++) {
for (int j = 0; j < left.item_size(); j++) {
if (right.item(i) == left.item(j)) {
left.mutable_item()->DeleteSubrange(j, 1);
break;
return left;
ostream& operator<<(ostream& stream, const Value::Text& value)
return stream << value.value();
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;
string temp;
foreach (const char c, text) {
if (c != ' ') {
temp += c;
if (temp.length() == 0) {
return Error("Expecting non-empty string");
if (!strings::checkBracketsMatching(temp, '{', '}') ||
!strings::checkBracketsMatching(temp, '[', ']') ||
!strings::checkBracketsMatching(temp, '(', ')')) {
return Error("Mismatched brackets");
size_t index = temp.find('[');
if (index == 0) {
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) {
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 {
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&) {
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");
src/v1/values.cpp(434)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/v1/values.cpp(329)
src/common/values.cpp(297)
Value::Ranges left;
coalesce(&left, {_left});
Value::Ranges right;
coalesce(&right, {_right});
src/v1/values.cpp(483)
src/common/values.cpp(429)
for (int i = 0; i < left.item_size(); i++) {
bool found = false;
for (int j = 0; j < right.item_size(); j++) {
if (left.item(i) == right.item(j)) {
found = true;
break;
if (!found) {
src/v1/values.cpp(409)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/v1/values.cpp(434)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/v1/values.cpp(409)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/v1/values.cpp(297)
src/common/values.cpp(329)
Value::Ranges left;
coalesce(&left, {_left});
Value::Ranges right;
coalesce(&right, {_right});
src/v1/values.cpp(429)
src/common/values.cpp(483)
for (int i = 0; i < left.item_size(); i++) {
bool found = false;
for (int j = 0; j < right.item_size(); j++) {
if (left.item(i) == right.item(j)) {
found = true;
break;
if (!found) {
src/v1/values.cpp(310)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/v1/values.cpp(310)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
return false;
src/common/attributes.cpp(29)
src/common/values.cpp(41)
using std::ostream;
using std::string;
using std::vector;
namespace mesos {
src/common/http.cpp(37)
src/common/resources.cpp(37)
using std::set;
using std::string;
using std::vector;
namespace mesos {
src/common/type_utils.cpp(272)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(242)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(208)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(181)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(272)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(163)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(272)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(242)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(242)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(208)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(106)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(208)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(181)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(163)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(181)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(41)
src/common/values.cpp(310)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(163)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(106)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(106)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
return true;
src/common/type_utils.cpp(41)
src/common/values.cpp(409)
found = true;
break;
if (!found) {
return false;
src/common/type_utils.cpp(41)
src/common/values.cpp(434)
found = true;
break;
if (!found) {
return false;
Configuration:
Number of files: 13
Minimal block size: 4
Minimal characters in line: 3
Ignore preprocessor directives: 0
Ignore same filenames: 0
Results:
Lines of code: 2910
Duplicate lines of code: 1980
Total 174 duplicate block(s) found.
Time: 0.043474 seconds
{code}
> Merge duplicated code of Http V1
> --------------------------------
>
> Key: MESOS-3404
> URL: https://issues.apache.org/jira/browse/MESOS-3404
> Project: Mesos
> Issue Type: Bug
> Components: HTTP API
> Reporter: Klaus Ma
>
> After HTTP v1, there is a directory {{src/v1}} including all HTTP v1 related
> code; but there some duplicated logic/code. The target of this ticket is to
> draft a design to merge them. Refer to the following diff as an example:
> {code}
> klaus@klaus-ThinkPad-T420:~/Workspace/mesos-3063$ diff src/v1/values.cpp
> src/common/values.cpp
> 28,29c28,29
> < #include <mesos/v1/resources.hpp>
> < #include <mesos/v1/values.hpp>
> ---
> > #include <mesos/resources.hpp>
> > #include <mesos/values.hpp>
> 42d41
> < namespace v1 {
> 587d585
> < } // namespace v1 {
> {code}
--
This message was sent by Atlassian JIRA
(v6.3.4#6332)