| /** |
| * 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. |
| */ |
| |
| #ifndef __MESOS_TYPE_UTILS_H__ |
| #define __MESOS_TYPE_UTILS_H__ |
| |
| #include <ostream> |
| |
| #include <boost/functional/hash.hpp> |
| |
| #include <mesos/mesos.hpp> |
| |
| #include <mesos/module/module.hpp> |
| |
| #include <mesos/scheduler/scheduler.hpp> |
| |
| #include <stout/hashmap.hpp> |
| #include <stout/stringify.hpp> |
| #include <stout/strings.hpp> |
| #include <stout/uuid.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/common/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 type_utils.hpp. Exposing type_utils.hpp |
| // allows us to build modules without having a dependency on mesos |
| // source tree (src/*). |
| |
| namespace mesos { |
| |
| bool operator==(const CommandInfo& left, const CommandInfo& right); |
| bool operator==(const CommandInfo::URI& left, const CommandInfo::URI& right); |
| bool operator==(const Credential& left, const Credential& right); |
| bool operator==(const Environment& left, const Environment& right); |
| bool operator==(const ExecutorInfo& left, const ExecutorInfo& right); |
| bool operator==(const MasterInfo& left, const MasterInfo& right); |
| |
| bool operator==( |
| const ResourceStatistics& left, |
| const ResourceStatistics& right); |
| |
| 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); |
| bool operator!=(const TaskStatus& left, const TaskStatus& right); |
| |
| inline bool operator==(const ContainerID& left, const ContainerID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const ExecutorID& left, const ExecutorID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const FrameworkID& left, const FrameworkID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const FrameworkInfo& left, const FrameworkInfo& right) |
| { |
| return (left.name() == right.name()) && (left.user() == right.user()); |
| } |
| |
| |
| inline bool operator==(const OfferID& left, const OfferID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const SlaveID& left, const SlaveID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const TaskID& left, const TaskID& right) |
| { |
| return left.value() == right.value(); |
| } |
| |
| |
| inline bool operator==(const TimeInfo& left, const TimeInfo& right) |
| { |
| return left.nanoseconds() == right.nanoseconds(); |
| } |
| |
| |
| inline bool operator==(const DurationInfo& left, const DurationInfo& right) |
| { |
| return left.nanoseconds() == right.nanoseconds(); |
| } |
| |
| |
| inline bool operator==(const ContainerID& left, const std::string& right) |
| { |
| return left.value() == right; |
| } |
| |
| |
| inline bool operator==(const ExecutorID& left, const std::string& right) |
| { |
| return left.value() == right; |
| } |
| |
| |
| inline bool operator==(const FrameworkID& left, const std::string& right) |
| { |
| return left.value() == right; |
| } |
| |
| |
| inline bool operator==(const OfferID& left, const std::string& right) |
| { |
| return left.value() == right; |
| } |
| |
| |
| inline bool operator==(const SlaveID& left, const std::string& right) |
| { |
| return left.value() == right; |
| } |
| |
| |
| inline bool operator==(const TaskID& left, const std::string& right) |
| { |
| return left.value() == 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) |
| { |
| // 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(); |
| } |
| |
| |
| inline bool operator!=(const ContainerID& left, const ContainerID& right) |
| { |
| return left.value() != right.value(); |
| } |
| |
| |
| inline bool operator!=(const ExecutorID& left, const ExecutorID& right) |
| { |
| return left.value() != right.value(); |
| } |
| |
| |
| inline bool operator!=(const FrameworkID& left, const FrameworkID& right) |
| { |
| return left.value() != right.value(); |
| } |
| |
| |
| inline bool operator!=(const SlaveID& left, const SlaveID& right) |
| { |
| return left.value() != right.value(); |
| } |
| |
| |
| 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(); |
| } |
| |
| |
| inline bool operator<(const ExecutorID& left, const ExecutorID& right) |
| { |
| return left.value() < right.value(); |
| } |
| |
| |
| inline bool operator<(const FrameworkID& left, const FrameworkID& right) |
| { |
| return left.value() < right.value(); |
| } |
| |
| |
| inline bool operator<(const OfferID& left, const OfferID& right) |
| { |
| return left.value() < right.value(); |
| } |
| |
| |
| inline bool operator<(const SlaveID& left, const SlaveID& right) |
| { |
| return left.value() < right.value(); |
| } |
| |
| |
| inline bool operator<(const TaskID& left, const TaskID& right) |
| { |
| return left.value() < right.value(); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const ContainerID& containerId) |
| { |
| return stream << containerId.value(); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const ContainerInfo& containerInfo) |
| { |
| return stream << containerInfo.DebugString(); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const ExecutorID& executorId) |
| { |
| return stream << executorId.value(); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const ExecutorInfo& executor) |
| { |
| return stream << executor.DebugString(); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const FrameworkID& frameworkId) |
| { |
| return stream << frameworkId.value(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const MasterInfo& master) |
| { |
| return stream << master.DebugString(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const OfferID& offerId) |
| { |
| return stream << offerId.value(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const RateLimits& limits) |
| { |
| return stream << limits.DebugString(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const SlaveID& slaveId) |
| { |
| return stream << slaveId.value(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const SlaveInfo& slave) |
| { |
| return stream << slave.DebugString(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const TaskID& taskId) |
| { |
| return stream << taskId.value(); |
| } |
| |
| |
| 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(); |
| } |
| |
| |
| inline std::ostream& operator<<(std::ostream& stream, const TaskState& state) |
| { |
| return stream << TaskState_Name(state); |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const std::vector<TaskID>& taskIds) |
| { |
| stream << "[ "; |
| for (auto it = taskIds.begin(); it != taskIds.end(); ++it) { |
| if (it != taskIds.begin()) { |
| stream << ", "; |
| } |
| stream << *it; |
| } |
| stream << " ]"; |
| return stream; |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const FrameworkInfo::Capability& capability) |
| { |
| return stream << FrameworkInfo::Capability::Type_Name(capability.type()); |
| } |
| |
| |
| 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, |
| const google::protobuf::RepeatedPtrField<T>& messages) |
| { |
| stream << "[ "; |
| for (auto it = messages.begin(); it != messages.end(); ++it) { |
| if (it != messages.begin()) { |
| stream << ", "; |
| } |
| stream << *it; |
| } |
| stream << " ]"; |
| return stream; |
| } |
| |
| |
| inline std::ostream& operator<<( |
| std::ostream& stream, |
| const hashmap<std::string, std::string>& map) |
| { |
| stream << stringify(map); |
| return stream; |
| } |
| |
| } // namespace mesos { |
| |
| namespace std { |
| |
| template <> |
| struct hash<mesos::CommandInfo_URI> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::CommandInfo_URI argument_type; |
| |
| result_type operator()(const argument_type& uri) const |
| { |
| size_t seed = 0; |
| |
| if (uri.extract()) { |
| seed += 11; |
| } |
| |
| if (uri.executable()) { |
| seed += 2003; |
| } |
| |
| boost::hash_combine(seed, uri.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::ContainerID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::ContainerID argument_type; |
| |
| result_type operator()(const argument_type& containerId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, containerId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::ExecutorID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::ExecutorID argument_type; |
| |
| result_type operator()(const argument_type& executorId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, executorId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::FrameworkID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::FrameworkID argument_type; |
| |
| result_type operator()(const argument_type& frameworkId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, frameworkId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::OfferID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::OfferID argument_type; |
| |
| result_type operator()(const argument_type& offerId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, offerId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::SlaveID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::SlaveID argument_type; |
| |
| result_type operator()(const argument_type& slaveId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, slaveId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::TaskID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::TaskID argument_type; |
| |
| result_type operator()(const argument_type& taskId) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, taskId.value()); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::TaskState> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::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::TaskStatus_Source> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::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::TaskStatus_Reason> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::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::Image::Type> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::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::FrameworkID, mesos::ExecutorID>> |
| { |
| typedef size_t result_type; |
| |
| typedef std::pair< |
| mesos::FrameworkID, mesos::ExecutorID> argument_type; |
| |
| result_type operator()(const argument_type& pair) const |
| { |
| size_t seed = 0; |
| boost::hash_combine(seed, std::hash<mesos::FrameworkID>()(pair.first)); |
| boost::hash_combine(seed, std::hash<mesos::ExecutorID>()(pair.second)); |
| return seed; |
| } |
| }; |
| |
| |
| template <> |
| struct hash<mesos::MachineID> |
| { |
| typedef size_t result_type; |
| |
| typedef mesos::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_TYPE_UTILS_H__ |