Apache Mesos
resources.hpp
Go to the documentation of this file.
1 // Licensed to the Apache Software Foundation (ASF) under one
2 // or more contributor license agreements. See the NOTICE file
3 // distributed with this work for additional information
4 // regarding copyright ownership. The ASF licenses this file
5 // to you under the Apache License, Version 2.0 (the
6 // "License"); you may not use this file except in compliance
7 // with the License. You may obtain a copy of the License at
8 //
9 // http://www.apache.org/licenses/LICENSE-2.0
10 //
11 // Unless required by applicable law or agreed to in writing, software
12 // distributed under the License is distributed on an "AS IS" BASIS,
13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 // See the License for the specific language governing permissions and
15 // limitations under the License.
16 
17 #ifndef __RESOURCES_HPP__
18 #define __RESOURCES_HPP__
19 
20 #include <map>
21 #include <iosfwd>
22 #include <set>
23 #include <string>
24 #include <vector>
25 
26 #include <boost/container/small_vector.hpp>
27 #include <boost/iterator/indirect_iterator.hpp>
28 
29 #include <google/protobuf/repeated_field.h>
30 
31 #include <mesos/mesos.hpp>
33 #include <mesos/type_utils.hpp>
34 #include <mesos/values.hpp>
35 
36 #include <stout/bytes.hpp>
37 #include <stout/check.hpp>
38 #include <stout/error.hpp>
39 #include <stout/foreach.hpp>
40 #include <stout/hashmap.hpp>
41 #include <stout/json.hpp>
42 #include <stout/lambda.hpp>
43 #include <stout/nothing.hpp>
44 #include <stout/option.hpp>
45 #include <stout/try.hpp>
46 
47 
48 // Resources come in three types: scalar, ranges, and sets. These are
49 // represented using protocol buffers. To make manipulation of
50 // resources easier within the Mesos core and for scheduler writers,
51 // we provide generic overloaded operators (see below) as well as a
52 // general Resources class that encapsulates a collection of protocol
53 // buffer Resource objects. The Resources class also provides a few
54 // static routines to allow parsing resources (e.g., from the command
55 // line), as well as determining whether or not a Resource object is
56 // valid. Note that many of these operations have not been optimized
57 // but instead just written for correct semantics.
58 
59 namespace mesos {
60 
61 // Forward declaration.
62 class ResourceConversion;
63 
64 
65 // Helper functions.
66 bool operator==(
67  const Resource::ReservationInfo& left,
68  const Resource::ReservationInfo& right);
69 
70 
71 bool operator!=(
72  const Resource::ReservationInfo& left,
73  const Resource::ReservationInfo& right);
74 
75 
76 // NOTE: Resource objects stored in the class are always valid, are in
77 // the "post-reservation-refinement" format, and kept combined if possible.
78 // It is the caller's responsibility to validate any Resource object or
79 // repeated Resource protobufs before constructing a Resources object.
80 // Otherwise, invalid Resource objects will be silently stripped.
81 // Invalid Resource objects will also be silently ignored when used in
82 // arithmetic operations (e.g., +=, -=, etc.).
83 class Resources
84 {
85 private:
86  // An internal abstraction to facilitate managing shared resources.
87  // It allows 'Resources' to group identical shared resource objects
88  // together into a single 'Resource_' object and tracked by its internal
89  // counter. Non-shared resource objects are not grouped.
90  //
91  // The rest of the private section is below the public section. We
92  // need to define Resource_ first because the public typedefs below
93  // depend on it.
94  class Resource_
95  {
96  public:
97  /*implicit*/ Resource_(const Resource& _resource)
98  : resource(_resource),
99  sharedCount(None())
100  {
101  // Setting the counter to 1 to denote "one copy" of the shared resource.
102  if (resource.has_shared()) {
103  sharedCount = 1;
104  }
105  }
106 
107  /*implicit*/ Resource_(Resource&& _resource)
108  : resource(std::move(_resource)),
109  sharedCount(None())
110  {
111  // Setting the counter to 1 to denote "one copy" of the shared resource.
112  if (resource.has_shared()) {
113  sharedCount = 1;
114  }
115  }
116 
117  Resource_(const Resource_& resource_) = default;
118  Resource_(Resource_&& resource_) = default;
119 
120  Resource_& operator=(const Resource_&) = default;
121  Resource_& operator=(Resource_&&) = default;
122 
123  // By implicitly converting to Resource we are able to keep Resource_
124  // logic internal and expose only the protobuf object.
125  operator const Resource&() const { return resource; }
126 
127  // Check whether this Resource_ object corresponds to a shared resource.
128  bool isShared() const { return sharedCount.isSome(); }
129 
130  // Validates this Resource_ object.
131  Option<Error> validate() const;
132 
133  // Check whether this Resource_ object is empty.
134  bool isEmpty() const;
135 
136  // The `Resource_` arithmetic, comparison operators and `contains()`
137  // method require the wrapped `resource` protobuf to have the same
138  // sharedness.
139  //
140  // For shared resources, the `resource` protobuf needs to be equal,
141  // and only the shared counters are adjusted or compared.
142  // For non-shared resources, the shared counters are none and the
143  // semantics of the Resource_ object's operators/contains() method
144  // are the same as those of the Resource objects.
145 
146  // Checks if this Resource_ is a superset of the given Resource_.
147  bool contains(const Resource_& that) const;
148 
149  // The arithmetic operators, viz. += and -= assume that the corresponding
150  // Resource objects are addable or subtractable already.
151  Resource_& operator+=(const Resource_& that);
152  Resource_& operator-=(const Resource_& that);
153 
154  bool operator==(const Resource_& that) const;
155  bool operator!=(const Resource_& that) const;
156 
157  // Friend classes and functions for access to private members.
158  friend class Resources;
159  friend std::ostream& operator<<(
160  std::ostream& stream, const Resource_& resource_);
161 
162  private:
163  // The protobuf Resource that is being managed.
164  Resource resource;
165 
166  // The counter for grouping shared 'resource' objects, None if the
167  // 'resource' is non-shared. This is an int so as to support arithmetic
168  // operations involving subtraction.
169  Option<int> sharedCount;
170  };
171 
172 public:
173  // We rename the type here to alert people about the fact that with
174  // `shared_ptr`, no mutation should be made without obtaining exclusive
175  // ownership. See `resourcesNoMutationWithoutExclusiveOwnership`.
176  using Resource_Unsafe = std::shared_ptr<Resource_>;
177 
190  static Try<Resource> parse(
191  const std::string& name,
192  const std::string& value,
193  const std::string& role);
194 
209  static Try<Resources> parse(
210  const std::string& text,
211  const std::string& defaultRole = "*");
212 
233  const JSON::Array& resourcesJSON,
234  const std::string& defaultRole = "*");
235 
254  const std::string& text,
255  const std::string& defaultRole = "*");
256 
270  const std::string& text,
271  const std::string& defaultRole = "*");
272 
285  static Option<Error> validate(const Resource& resource);
286 
304  static Option<Error> validate(
305  const google::protobuf::RepeatedPtrField<Resource>& resources);
306 
307  // NOTE: The following predicate functions assume that the given resource is
308  // validated, and is in the "post-reservation-refinement" format. That is,
309  // the reservation state is represented by `Resource.reservations` field,
310  // and `Resource.role` and `Resource.reservation` fields are not set.
311  //
312  // See 'Resource Format' section in `mesos.proto` for more details.
313 
314  // Tests if the given Resource object is empty.
315  static bool isEmpty(const Resource& resource);
316 
317  // Tests if the given Resource object is a persistent volume.
318  static bool isPersistentVolume(const Resource& resource);
319 
320  // Tests if the given Resource object is a disk of the specified type.
321  static bool isDisk(
322  const Resource& resource,
324 
325  // Tests if the given Resource object is reserved. If the role is
326  // specified, tests that it's reserved for the given role.
327  static bool isReserved(
328  const Resource& resource,
329  const Option<std::string>& role = None());
330 
331  // Tests if the given Resource object is allocatable to the given role.
332  // A resource object is allocatable to 'role' if:
333  // * it is reserved to an ancestor of that role in the hierarchy, OR
334  // * it is reserved to 'role' itself, OR
335  // * it is unreserved.
336  static bool isAllocatableTo(
337  const Resource& resource,
338  const std::string& role);
339 
340  // Tests if the given Resource object is unreserved.
341  static bool isUnreserved(const Resource& resource);
342 
343  // Tests if the given Resource object is dynamically reserved.
344  static bool isDynamicallyReserved(const Resource& resource);
345 
346  // Tests if the given Resource object is revocable.
347  static bool isRevocable(const Resource& resource);
348 
349  // Tests if the given Resource object is shared.
350  static bool isShared(const Resource& resource);
351 
352  // Returns true if the resource is allocated to the role subtree
353  // (i.e. either to the role itself or to its decedents).
354  static bool isAllocatedToRoleSubtree(
355  const Resource& resource, const std::string& role);
356 
357  // Returns true if the resource is reserved to the role subtree
358  // (i.e. either to the role itself or to its decedents).
359  static bool isReservedToRoleSubtree(
360  const Resource& resource, const std::string& role);
361 
362  // Tests if the given Resource object has refined reservations.
363  static bool hasRefinedReservations(const Resource& resource);
364 
365  // Tests if the given Resource object is provided by a resource provider.
366  static bool hasResourceProvider(const Resource& resource);
367 
368  // Returns the role to which the given Resource object is reserved for.
369  // This must be called only when the resource is reserved!
370  static const std::string& reservationRole(const Resource& resource);
371 
372  // Shrinks a scalar type `resource` to the target size.
373  // Returns true if the resource was shrunk to the target size,
374  // or the resource is already within the target size.
375  // Returns false otherwise (i.e. the resource is indivisible.
376  // E.g. MOUNT volume).
377  static bool shrink(Resource* resource, const Value::Scalar& target);
378 
379  // Returns the most refined reserved resource that can be
380  // reached by modifications to `a`'s or `b`'s reservations.
381  //
382  // Both `a` and `b` must refer to identical resource quantities.
383  static Resource getReservationAncestor(const Resource& a, const Resource& b);
384 
385  // Returns the most refined reserved resources that can be
386  // reached by modifications to `a`'s or `b`'s reservations.
387  //
388  // Both `a` and `b` must be non-empty, and must contain the
389  // same resources except for reservations.
391  const Resources& a, const Resources& b);
392 
393  // Returns the summed up Resources given a hashmap<Key, Resources>.
394  //
395  // NOTE: While scalar resources such as "cpus" sum correctly,
396  // non-scalar resources such as "ports" do not.
397  // e.g. "cpus:2" + "cpus:1" = "cpus:3"
398  // "ports:[0-100]" + "ports:[0-100]" = "ports:[0-100]"
399  //
400  // TODO(mpark): Deprecate this function once we introduce the
401  // concept of "cluster-wide" resources which provides correct
402  // semantics for summation over all types of resources. (e.g.
403  // non-scalar)
404  template <typename Key>
405  static Resources sum(const hashmap<Key, Resources>& _resources)
406  {
407  Resources result;
408 
409  foreachvalue (const Resources& resources, _resources) {
410  result += resources;
411  }
412 
413  return result;
414  }
415 
417 
418  // TODO(jieyu): Consider using C++11 initializer list.
419  /*implicit*/ Resources(const Resource& resource);
420  /*implicit*/ Resources(Resource&& resource);
421 
422  /*implicit*/
423  Resources(const std::vector<Resource>& _resources);
424  Resources(std::vector<Resource>&& _resources);
425 
426  /*implicit*/
427  Resources(const google::protobuf::RepeatedPtrField<Resource>& _resources);
428  Resources(google::protobuf::RepeatedPtrField<Resource>&& _resources);
429 
430  Resources(const Resources& that) = default;
431  Resources(Resources&& that) = default;
432 
434  {
435  if (this != &that) {
436  resourcesNoMutationWithoutExclusiveOwnership =
437  that.resourcesNoMutationWithoutExclusiveOwnership;
438  }
439  return *this;
440  }
441 
443  {
444  if (this != &that) {
445  resourcesNoMutationWithoutExclusiveOwnership =
446  std::move(that.resourcesNoMutationWithoutExclusiveOwnership);
447  }
448  return *this;
449  }
450 
451  bool empty() const
452  {
453  return resourcesNoMutationWithoutExclusiveOwnership.size() == 0;
454  }
455 
456  size_t size() const
457  {
458  return resourcesNoMutationWithoutExclusiveOwnership.size();
459  }
460 
461  // Checks if this Resources is a superset of the given Resources.
462  bool contains(const Resources& that) const;
463 
464  // Checks if this Resources contains the given Resource.
465  bool contains(const Resource& that) const;
466 
467  // Checks if the quantities of this `Resources` is a superset of the
468  // given `ResourceQuantities`. If a `Resource` object is `SCALAR` type,
469  // its quantity is its scalar value. For `RANGES` and `SET` type, their
470  // quantities are the number of different instances in the range or set.
471  // For example, "range:[1-5]" has a quantity of 5 and "set:{a,b}" has a
472  // quantity of 2.
473  bool contains(const ResourceQuantities& quantities) const;
474 
475  // Count the Resource objects that match the specified value.
476  //
477  // NOTE:
478  // - For a non-shared resource the count can be at most 1 because all
479  // non-shared Resource objects in Resources are unique.
480  // - For a shared resource the count can be greater than 1.
481  // - If the resource is not in the Resources object, the count is 0.
482  size_t count(const Resource& that) const;
483 
484  // Allocates the resources to the given role (by setting the
485  // `AllocationInfo.role`). Any existing allocation will be
486  // over-written.
487  void allocate(const std::string& role);
488 
489  // Unallocates the resources.
490  void unallocate();
491 
492  // Filter resources based on the given predicate.
494  const lambda::function<bool(const Resource&)>& predicate) const;
495 
496  // Returns the reserved resources, by role.
498 
499  // Returns the reserved resources for the role, if specified.
500  // Note that the "*" role represents unreserved resources,
501  // and will be ignored.
502  Resources reserved(const Option<std::string>& role = None()) const;
503 
504  // Returns resources allocatable to role. See `isAllocatableTo` for the
505  // definition of 'allocatableTo'.
506  Resources allocatableTo(const std::string& role) const;
507 
508  // Returns resources that are allocated to the role subtree
509  // (i.e. either to the role itself or to its decedents).
510  Resources allocatedToRoleSubtree(const std::string& role) const;
511 
512  // Returns resources that are reserved to the role subtree
513  // (i.e. either to the role itself or to its decedents).
514  Resources reservedToRoleSubtree(const std::string& role) const;
515 
516  // Returns the unreserved resources.
517  Resources unreserved() const;
518 
519  // Returns the persistent volumes.
521 
522  // Returns the revocable resources.
523  Resources revocable() const;
524 
525  // Returns the non-revocable resources, effectively !revocable().
526  Resources nonRevocable() const;
527 
528  // Returns the shared resources.
529  Resources shared() const;
530 
531  // Returns the non-shared resources.
532  Resources nonShared() const;
533 
534  // Returns the per-role allocations within these resource objects.
535  // This must be called only when the resources are allocated!
537 
538  // Returns a `Resources` object with the new reservation added to the back.
539  // The new reservation must be a valid refinement of the current reservation.
541  const Resource::ReservationInfo& reservation) const;
542 
543  // Returns a `Resources` object with the last reservation removed.
544  // Every resource in `Resources` must have `resource.reservations_size() > 0`.
546 
547  // Returns a `Resources` object with all of the reservations removed.
548  Resources toUnreserved() const;
549 
550  // Returns a Resources object that contains all the scalar resources
551  // but with all the meta-data fields, such as AllocationInfo,
552  // ReservationInfo and etc. cleared. Only scalar resources' name,
553  // type (SCALAR) and value are preserved.
554  //
555  // This is intended for code that would like to aggregate together
556  // Resource values without regard for metadata like whether the
557  // resource is reserved or the particular volume ID in use. For
558  // example, when calculating the total resources in a cluster,
559  // preserving such information has a major performance cost.
561 
562  // Finds a Resources object with the same amount of each resource
563  // type as "targets" from these Resources. The roles specified in
564  // "targets" set the preference order. For each resource type,
565  // resources are first taken from the specified role, then from '*',
566  // then from any other role.
567  // TODO(jieyu): 'find' contains some allocation logic for scalars and
568  // fixed set / range elements. However, this is not sufficient for
569  // schedulers that want, say, any N available ports. We should
570  // consider moving this to an internal "allocation" library for our
571  // example frameworks to leverage.
572  Option<Resources> find(const Resources& targets) const;
573 
574  // Applies a resource conversion by taking out the `consumed`
575  // resources and adding back the `converted` resources. Returns an
576  // Error if the conversion cannot be applied.
577  Try<Resources> apply(const ResourceConversion& conversion) const;
578 
579  // Finds a resource object with the same metadata (i.e. AllocationInfo,
580  // ReservationInfo, etc.) as the given one, ignoring the actual value.
581  // If multiple matching resources exist, the first match is returned.
582  Option<Resource> match(const Resource& resource) const;
583 
584  // Obtains the conversion from the given operation and applies the
585  // conversion. This method serves a syntax sugar for applying a
586  // resource conversion.
587  // TODO(jieyu): Consider remove this method once we updated all the
588  // call sites.
589  Try<Resources> apply(const Offer::Operation& operation) const;
590 
591  template <typename Iterable>
592  Try<Resources> apply(const Iterable& iterable) const
593  {
594  Resources result = *this;
595 
596  foreach (const auto& t, iterable) {
597  Try<Resources> converted = result.apply(t);
598  if (converted.isError()) {
599  return Error(converted.error());
600  }
601 
602  result = converted.get();
603  }
604 
605  return result;
606  }
607 
608  // Helpers to get resource values. We consider all roles here.
609  template <typename T>
610  Option<T> get(const std::string& name) const;
611 
612  // Get resources of the given name.
613  Resources get(const std::string& name) const;
614 
615  // Get all the resources that are scalars.
616  Resources scalars() const;
617 
618  // Get the set of unique resource names.
619  std::set<std::string> names() const;
620 
621  // Get the types of resources associated with each resource name.
622  // NOTE: Resources of the same name must have the same type, as
623  // enforced by Resources::parse().
624  std::map<std::string, Value_Type> types() const;
625 
626  // Helpers to get known resource types.
627  // TODO(vinod): Fix this when we make these types as first class
628  // protobufs.
629  Option<double> cpus() const;
630  Option<double> gpus() const;
631  Option<Bytes> mem() const;
632  Option<Bytes> disk() const;
633 
634  // TODO(vinod): Provide a Ranges abstraction.
636 
637  // TODO(jieyu): Consider returning an EphemeralPorts abstraction
638  // which holds the ephemeral ports allocation logic.
640 
641  // We use `boost::indirect_iterator` to expose `Resource` (implicitly
642  // converted from `Resource_`) iteration, while actually storing
643  // `Resource_Unsafe`.
644  //
645  // NOTE: Non-const `begin()` and `end()` intentionally return const
646  // iterators to prevent mutable access to the `Resource` objects.
647 
648  typedef boost::indirect_iterator<
649  boost::container::small_vector_base<Resource_Unsafe>::const_iterator>
651 
653  {
654  const auto& self = *this;
655  return self.begin();
656  }
657 
659  {
660  const auto& self = *this;
661  return self.end();
662  }
663 
665  {
666  return resourcesNoMutationWithoutExclusiveOwnership.begin();
667  }
668 
670  {
671  return resourcesNoMutationWithoutExclusiveOwnership.end();
672  }
673 
674  // Using this operator makes it easy to copy a resources object into
675  // a protocol buffer field.
676  // Note that the google::protobuf::RepeatedPtrField<Resource> is
677  // generated at runtime.
678  operator google::protobuf::RepeatedPtrField<Resource>() const;
679 
680  bool operator==(const Resources& that) const;
681  bool operator!=(const Resources& that) const;
682 
683  // NOTE: If any error occurs (e.g., input Resource is not valid or
684  // the first operand is not a superset of the second operand while
685  // doing subtraction), the semantics is as though the second operand
686  // was actually just an empty resource (as though you didn't do the
687  // operation at all).
688  Resources operator+(const Resource& that) const &;
689  Resources operator+(const Resource& that) &&;
690 
691  Resources operator+(Resource&& that) const &;
692  Resources operator+(Resource&& that) &&;
693 
694  Resources& operator+=(const Resource& that);
695  Resources& operator+=(Resource&& that);
696 
697  Resources operator+(const Resources& that) const &;
698  Resources operator+(const Resources& that) &&;
699 
700  Resources operator+(Resources&& that) const &;
701  Resources operator+(Resources&& that) &&;
702 
703  Resources& operator+=(const Resources& that);
704  Resources& operator+=(Resources&& that);
705 
706  Resources operator-(const Resource& that) const;
707  Resources operator-(const Resources& that) const;
708  Resources& operator-=(const Resource& that);
709  Resources& operator-=(const Resources& that);
710 
711  friend std::ostream& operator<<(
712  std::ostream& stream, const Resource_& resource_);
713 
714 private:
715  // Similar to 'contains(const Resource&)' but skips the validity
716  // check. This can be used to avoid the performance overhead of
717  // calling 'contains(const Resource&)' when the resource can be
718  // assumed valid (e.g. it's inside a Resources).
719  //
720  // TODO(jieyu): Measure performance overhead of validity check to
721  // ensure this is warranted.
722  bool _contains(const Resource_& that) const;
723 
724  // Similar to the public 'find', but only for a single Resource
725  // object. The target resource may span multiple roles, so this
726  // returns Resources.
727  Option<Resources> find(const Resource& target) const;
728 
729  // Validation-free versions of += and -= `Resource_` operators.
730  // These can be used when `r` is already validated.
731  //
732  // NOTE: `Resource` objects are implicitly converted to `Resource_`
733  // objects, so here the API can also accept a `Resource` object.
734  void add(const Resource_& r);
735  void add(Resource_&& r);
736 
737  // TODO(mzhu): Add move support.
738  void add(const Resource_Unsafe& that);
739 
740  void subtract(const Resource_& r);
741 
742  Resources& operator+=(const Resource_& that);
743  Resources& operator+=(Resource_&& that);
744 
745  Resources& operator-=(const Resource_& that);
746 
747  // Resources are stored using copy-on-write:
748  //
749  // (1) Copies are done by copying the `shared_ptr`. This
750  // makes read-only filtering (e.g. `unreserved()`)
751  // inexpensive as we do not have to perform copies
752  // of the resource objects.
753  //
754  // (2) When a write occurs:
755  // (a) If there's a single reference to the resource
756  // object, we mutate directly.
757  // (b) If there's more than a single reference to the
758  // resource object, we copy first, then mutate the copy.
759  //
760  // We name the `vector` field `resourcesNoMutationWithoutExclusiveOwnership`
761  // and typedef its item type to `Resource_Unsafe` to alert people
762  // regarding (2).
763  //
764  // TODO(mzhu): While naming the vector and its item type may help, this is
765  // still brittle and certainly not ideal. Explore more robust designs such as
766  // introducing a customized copy-on-write abstraction that hides direct
767  // setters and only allow mutations in a controlled fashion.
768  //
769  // TODO(mzhu): Consider using `boost::intrusive_ptr` for
770  // possibly better performance.
771  //
772  // We chose a size of 15 based on the fact that we have five first class
773  // resources (cpu, mem, disk, gpu and port). And 15 would allow one set of
774  // unreserved resources and two sets of reservations.
775  boost::container::small_vector<Resource_Unsafe, 15>
776  resourcesNoMutationWithoutExclusiveOwnership;
777 };
778 
779 
780 std::ostream& operator<<(
781  std::ostream& stream,
782  const Resources::Resource_& resource);
783 
784 
785 std::ostream& operator<<(std::ostream& stream, const Resource& resource);
786 
787 
788 std::ostream& operator<<(std::ostream& stream, const Resources& resources);
789 
790 
791 std::ostream& operator<<(
792  std::ostream& stream,
793  const google::protobuf::RepeatedPtrField<Resource>& resources);
794 
795 
797  const google::protobuf::RepeatedPtrField<Resource>& left,
798  const Resources& right)
799 {
800  return Resources(left) + right;
801 }
802 
803 
805  const google::protobuf::RepeatedPtrField<Resource>& left,
806  const Resources& right)
807 {
808  return Resources(left) - right;
809 }
810 
811 
812 inline bool operator==(
813  const google::protobuf::RepeatedPtrField<Resource>& left,
814  const Resources& right)
815 {
816  return Resources(left) == right;
817 }
818 
819 
820 template <typename Key>
823  const hashmap<Key, Resources>& right)
824 {
825  foreachpair (const Key& key, const Resources& resources, right) {
826  left[key] += resources;
827  }
828  return left;
829 }
830 
831 
832 template <typename Key>
834  const hashmap<Key, Resources>& left,
835  const hashmap<Key, Resources>& right)
836 {
837  hashmap<Key, Resources> result = left;
838  result += right;
839  return result;
840 }
841 
842 
843 // Tests if `right` is contained in `left`, note that most
844 // callers should just make use of `Resources::contains(...)`.
845 // However, if dealing only with singular `Resource` objects,
846 // this has lower overhead.
847 //
848 // NOTE: `left` and `right` must be valid resource objects.
849 bool contains(const Resource& left, const Resource& right);
850 
851 
857 {
858 public:
859  typedef lambda::function<Try<Nothing>(const Resources&)> PostValidation;
860 
862  const Resources& _consumed,
863  const Resources& _converted,
864  const Option<PostValidation>& _postValidation = None())
865  : consumed(_consumed),
866  converted(_converted),
867  postValidation(_postValidation) {}
868 
869  Try<Resources> apply(const Resources& resources) const;
870 
874 };
875 
876 } // namespace mesos {
877 
878 #endif // __RESOURCES_HPP__
ResourceConversion(const Resources &_consumed, const Resources &_converted, const Option< PostValidation > &_postValidation=None())
Definition: resources.hpp:861
static bool isEmpty(const Resource &resource)
size_t size() const
Definition: resources.hpp:456
std::map< std::string, Value_Type > types() const
Resources consumed
Definition: resources.hpp:871
std::shared_ptr< Resource_ > Resource_Unsafe
Definition: resources.hpp:176
Definition: errorbase.hpp:36
std::set< std::string > names() const
T & get()&
Definition: try.hpp:80
Definition: check.hpp:33
Definition: resource_quantities.hpp:63
const_iterator end()
Definition: resources.hpp:658
static bool isDynamicallyReserved(const Resource &resource)
static bool isAllocatedToRoleSubtree(const Resource &resource, const std::string &role)
size_t count(const Resource &that) const
Resources filter(const lambda::function< bool(const Resource &)> &predicate) const
Option< double > cpus() const
bool operator==(const Resource::ReservationInfo &left, const Resource::ReservationInfo &right)
Definition: resources.hpp:83
static bool isPersistentVolume(const Resource &resource)
Option< Value::Ranges > ephemeral_ports() const
Option< double > gpus() const
Definition: json.hpp:198
Option< Value::Ranges > ports() const
Try< Resources > apply(const ResourceConversion &conversion) const
Operation
Definition: cgroups.hpp:444
Future< Nothing > add(const T &metric)
Definition: metrics.hpp:95
STOUT_NODISCARD Resources pushReservation(const Resource::ReservationInfo &reservation) const
hashmap< std::string, Resources > reservations() const
static bool isShared(const Resource &resource)
static Resource getReservationAncestor(const Resource &a, const Resource &b)
Resources unreserved() const
Resources & operator=(const Resources &that)
Definition: resources.hpp:433
static Option< Error > validate(const Resource &resource)
Validates a Resource object.
static Try< Resource > parse(const std::string &name, const std::string &value, const std::string &role)
Returns a Resource with the given name, value, and role.
Definition: hashmap.hpp:38
const_iterator begin()
Definition: resources.hpp:652
bool operator!=(const Resource::ReservationInfo &left, const Resource::ReservationInfo &right)
lambda::function< Try< Nothing >const Resources &)> PostValidation
Definition: resources.hpp:859
static Try< std::vector< Resource > > fromJSON(const JSON::Array &resourcesJSON, const std::string &defaultRole="*")
Parses an input JSON array into a vector of Resource objects.
bool operator==(const Resources &that) const
friend std::ostream & operator<<(std::ostream &stream, const Resource_ &resource_)
Resources allocatableTo(const std::string &role) const
static Try< std::vector< Resource > > fromString(const std::string &text, const std::string &defaultRole="*")
Parse an input string into a vector of Resource objects.
Resources & operator-=(const Resource &that)
Resources createStrippedScalarQuantity() const
const_iterator begin() const
Definition: resources.hpp:664
STOUT_NODISCARD Resources popReservation() const
Resources & operator=(Resources &&that)
Definition: resources.hpp:442
Option< PostValidation > postValidation
Definition: resources.hpp:873
Definition: agent.hpp:25
static Try< std::vector< Resource > > fromSimpleString(const std::string &text, const std::string &defaultRole="*")
Parses an input text string into a vector of Resource objects.
Option< Resource > match(const Resource &resource) const
Resources toUnreserved() const
#define foreachpair(KEY, VALUE, ELEMS)
Definition: foreach.hpp:51
#define STOUT_NODISCARD
Definition: attributes.hpp:41
#define foreachvalue(VALUE, ELEMS)
Definition: foreach.hpp:77
Try< Resources > apply(const Iterable &iterable) const
Definition: resources.hpp:592
Resources reservedToRoleSubtree(const std::string &role) const
static Try error(const E &e)
Definition: try.hpp:43
const_iterator end() const
Definition: resources.hpp:669
static bool hasResourceProvider(const Resource &resource)
Represents a resource conversion, usually as a result of an offer operation.
Definition: resources.hpp:856
Resources scalars() const
Resources revocable() const
Resources persistentVolumes() const
Resources shared() const
bool empty() const
Definition: resources.hpp:451
bool operator!=(const Resources &that) const
static bool isReservedToRoleSubtree(const Resource &resource, const std::string &role)
Definition: none.hpp:27
bool isError() const
Definition: try.hpp:78
static bool shrink(Resource *resource, const Value::Scalar &target)
Resources nonShared() const
Type
Definition: capabilities.hpp:82
Option< Bytes > mem() const
static bool isDisk(const Resource &resource, const Resource::DiskInfo::Source::Type &type)
static bool isRevocable(const Resource &resource)
static bool isReserved(const Resource &resource, const Option< std::string > &role=None())
Resources operator+(const Resource &that) const &
static bool hasRefinedReservations(const Resource &resource)
Try< uint32_t > type(const std::string &path)
Resources & operator+=(const Resource &that)
void allocate(const std::string &role)
Resources reserved(const Option< std::string > &role=None()) const
Resources nonRevocable() const
Option< Resources > find(const Resources &targets) const
static bool isAllocatableTo(const Resource &resource, const std::string &role)
Resources allocatedToRoleSubtree(const std::string &role) const
Resources()
Definition: resources.hpp:416
static Resources sum(const hashmap< Key, Resources > &_resources)
Definition: resources.hpp:405
bool contains(const Resources &that) const
Resources converted
Definition: resources.hpp:872
static bool isUnreserved(const Resource &resource)
Option< Bytes > disk() const
Resources operator-(const Resource &that) const
boost::indirect_iterator< boost::container::small_vector_base< Resource_Unsafe >::const_iterator > const_iterator
Definition: resources.hpp:650
constexpr const char * name
Definition: shell.hpp:41
static const std::string & reservationRole(const Resource &resource)
hashmap< std::string, Resources > allocations() const