You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mesos.apache.org by nn...@apache.org on 2015/02/12 21:19:07 UTC

[2/6] mesos git commit: Moved allocation related sources into a separate directory.

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/master/drf_sorter.hpp
----------------------------------------------------------------------
diff --git a/src/master/drf_sorter.hpp b/src/master/drf_sorter.hpp
deleted file mode 100644
index 8a16d28..0000000
--- a/src/master/drf_sorter.hpp
+++ /dev/null
@@ -1,129 +0,0 @@
-/**
- * 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 __DRF_SORTER_HPP__
-#define __DRF_SORTER_HPP__
-
-#include <set>
-#include <string>
-
-#include <mesos/resources.hpp>
-
-#include <stout/hashmap.hpp>
-
-#include "master/sorter.hpp"
-
-
-namespace mesos {
-namespace master {
-namespace allocator {
-
-struct Client
-{
-  Client(const std::string& _name, double _share, uint64_t _allocations)
-    : name(_name), share(_share), allocations(_allocations) {}
-
-  std::string name;
-  double share;
-
-  // We store the number of times this client has been chosen for
-  // allocation so that we can fairly share the resources across
-  // clients that have the same share. Note that this information is
-  // not persisted across master failovers, but since the point is to
-  // equalize the 'allocations' across clients of the same 'share'
-  // having allocations restart at 0 after a master failover should be
-  // sufficient (famous last words.)
-  uint64_t allocations;
-};
-
-
-struct DRFComparator
-{
-  virtual ~DRFComparator() {}
-  virtual bool operator () (const Client& client1, const Client& client2);
-};
-
-
-class DRFSorter : public Sorter
-{
-public:
-  virtual ~DRFSorter() {}
-
-  virtual void add(const std::string& name, double weight = 1);
-
-  virtual void remove(const std::string& name);
-
-  virtual void activate(const std::string& name);
-
-  virtual void deactivate(const std::string& name);
-
-  virtual void allocated(const std::string& name,
-                         const Resources& resources);
-
-  virtual void update(const std::string& name,
-                      const Resources& oldAllocation,
-                      const Resources& newAllocation);
-
-  virtual void unallocated(const std::string& name,
-                           const Resources& resources);
-
-  virtual Resources allocation(const std::string& name);
-
-  virtual void add(const Resources& resources);
-
-  virtual void remove(const Resources& resources);
-
-  virtual std::list<std::string> sort();
-
-  virtual bool contains(const std::string& name);
-
-  virtual int count();
-
-private:
-  // Recalculates the share for the client and moves
-  // it in 'clients' accordingly.
-  void update(const std::string& name);
-
-  // Returns the dominant resource share for the client.
-  double calculateShare(const std::string& name);
-
-  // Returns an iterator to the specified client, if
-  // it exists in this Sorter.
-  std::set<Client, DRFComparator>::iterator find(const std::string& name);
-
-  // If true, start() will recalculate all shares.
-  bool dirty;
-
-  // A set of Clients (names and shares) sorted by share.
-  std::set<Client, DRFComparator> clients;
-
-  // Maps client names to the resources they have been allocated.
-  hashmap<std::string, Resources> allocations;
-
-  // Maps client names to the weights that should be applied to their shares.
-  hashmap<std::string, double> weights;
-
-  // Total resources.
-  Resources resources;
-};
-
-} // namespace allocator {
-} // namespace master {
-} // namespace mesos {
-
-#endif // __DRF_SORTER_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/master/hierarchical_allocator_process.hpp
----------------------------------------------------------------------
diff --git a/src/master/hierarchical_allocator_process.hpp b/src/master/hierarchical_allocator_process.hpp
deleted file mode 100644
index 75e0730..0000000
--- a/src/master/hierarchical_allocator_process.hpp
+++ /dev/null
@@ -1,922 +0,0 @@
-/**
- * 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 __HIERARCHICAL_ALLOCATOR_PROCESS_HPP__
-#define __HIERARCHICAL_ALLOCATOR_PROCESS_HPP__
-
-#include <algorithm>
-#include <vector>
-
-#include <mesos/resources.hpp>
-
-#include <process/delay.hpp>
-#include <process/id.hpp>
-#include <process/timeout.hpp>
-
-#include <stout/check.hpp>
-#include <stout/duration.hpp>
-#include <stout/hashmap.hpp>
-#include <stout/stopwatch.hpp>
-#include <stout/stringify.hpp>
-
-#include "master/allocator.hpp"
-#include "master/drf_sorter.hpp"
-#include "master/master.hpp"
-#include "master/sorter.hpp"
-
-namespace mesos {
-namespace master {
-namespace allocator {
-
-// Forward declarations.
-class Filter;
-
-
-// We forward declare the hierarchical allocator process so that we
-// can typedef an instantiation of it with DRF sorters.
-template <typename RoleSorter, typename FrameworkSorter>
-class HierarchicalAllocatorProcess;
-
-typedef HierarchicalAllocatorProcess<DRFSorter, DRFSorter>
-HierarchicalDRFAllocatorProcess;
-
-typedef MesosAllocator<HierarchicalDRFAllocatorProcess>
-HierarchicalDRFAllocator;
-
-
-// Implements the basic allocator algorithm - first pick a role by
-// some criteria, then pick one of their frameworks to allocate to.
-template <typename RoleSorter, typename FrameworkSorter>
-class HierarchicalAllocatorProcess : public MesosAllocatorProcess
-{
-public:
-  HierarchicalAllocatorProcess();
-
-  virtual ~HierarchicalAllocatorProcess();
-
-  process::PID<HierarchicalAllocatorProcess> self();
-
-  void initialize(
-      const Flags& flags,
-      const lambda::function<
-          void(const FrameworkID&,
-               const hashmap<SlaveID, Resources>&)>& offerCallback,
-      const hashmap<std::string, RoleInfo>& roles);
-
-  void addFramework(
-      const FrameworkID& frameworkId,
-      const FrameworkInfo& frameworkInfo,
-      const Resources& used);
-
-  void removeFramework(
-      const FrameworkID& frameworkId);
-
-  void activateFramework(
-      const FrameworkID& frameworkId);
-
-  void deactivateFramework(
-      const FrameworkID& frameworkId);
-
-  void addSlave(
-      const SlaveID& slaveId,
-      const SlaveInfo& slaveInfo,
-      const Resources& total,
-      const hashmap<FrameworkID, Resources>& used);
-
-  void removeSlave(
-      const SlaveID& slaveId);
-
-  void deactivateSlave(
-      const SlaveID& slaveId);
-
-  void activateSlave(
-      const SlaveID& slaveId);
-
-  void updateWhitelist(
-      const Option<hashset<std::string> >& whitelist);
-
-  void requestResources(
-      const FrameworkID& frameworkId,
-      const std::vector<Request>& requests);
-
-  void updateAllocation(
-      const FrameworkID& frameworkId,
-      const SlaveID& slaveId,
-      const std::vector<Offer::Operation>& operations);
-
-  void recoverResources(
-      const FrameworkID& frameworkId,
-      const SlaveID& slaveId,
-      const Resources& resources,
-      const Option<Filters>& filters);
-
-  void reviveOffers(
-      const FrameworkID& frameworkId);
-
-protected:
-  // Useful typedefs for dispatch/delay/defer to self()/this.
-  typedef HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter> Self;
-  typedef HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter> This;
-
-  // Callback for doing batch allocations.
-  void batch();
-
-  // Allocate any allocatable resources.
-  void allocate();
-
-  // Allocate resources just from the specified slave.
-  void allocate(const SlaveID& slaveId);
-
-  // Allocate resources from the specified slaves.
-  void allocate(const hashset<SlaveID>& slaveIds);
-
-  // Remove a filter for the specified framework.
-  void expire(const FrameworkID& frameworkId, Filter* filter);
-
-  // Checks whether the slave is whitelisted.
-  bool isWhitelisted(const SlaveID& slaveId);
-
-  // Returns true if there is a filter for this framework
-  // on this slave.
-  bool isFiltered(
-      const FrameworkID& frameworkId,
-      const SlaveID& slaveId,
-      const Resources& resources);
-
-  bool allocatable(const Resources& resources);
-
-  bool initialized;
-
-  Flags flags;
-
-  lambda::function<
-      void(const FrameworkID&,
-           const hashmap<SlaveID, Resources>&)> offerCallback;
-
-  struct Framework
-  {
-    std::string role;
-    bool checkpoint;  // Whether the framework desires checkpointing.
-
-    hashset<Filter*> filters; // Active filters for the framework.
-  };
-
-  hashmap<FrameworkID, Framework> frameworks;
-
-  struct Slave
-  {
-    Resources total;
-    Resources available;
-
-    bool activated;  // Whether to offer resources.
-    bool checkpoint; // Whether slave supports checkpointing.
-
-    std::string hostname;
-  };
-
-  hashmap<SlaveID, Slave> slaves;
-
-  hashmap<std::string, RoleInfo> roles;
-
-  // Slaves to send offers for.
-  Option<hashset<std::string> > whitelist;
-
-  // There are two levels of sorting, hence "hierarchical".
-  // Level 1 sorts across roles:
-  //   Reserved resources are excluded from fairness calculation,
-  //   since they are forcibly pinned to a role.
-  // Level 2 sorts across frameworks within a particular role:
-  //   Both reserved resources and unreserved resources are used
-  //   in the fairness calculation. This is because reserved
-  //   resources can be allocated to any framework in the role.
-  RoleSorter* roleSorter;
-  hashmap<std::string, FrameworkSorter*> frameworkSorters;
-};
-
-
-// Used to represent "filters" for resources unused in offers.
-class Filter
-{
-public:
-  virtual ~Filter() {}
-
-  virtual bool filter(const SlaveID& slaveId, const Resources& resources) = 0;
-};
-
-
-class RefusedFilter: public Filter
-{
-public:
-  RefusedFilter(
-      const SlaveID& _slaveId,
-      const Resources& _resources,
-      const process::Timeout& _timeout)
-    : slaveId(_slaveId), resources(_resources), timeout(_timeout) {}
-
-  virtual bool filter(const SlaveID& _slaveId, const Resources& _resources)
-  {
-    return slaveId == _slaveId &&
-           resources.contains(_resources) && // Refused resources are superset.
-           timeout.remaining() > Seconds(0);
-  }
-
-  const SlaveID slaveId;
-  const Resources resources;
-  const process::Timeout timeout;
-};
-
-
-template <class RoleSorter, class FrameworkSorter>
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::HierarchicalAllocatorProcess() // NOLINT(whitespace/line_length)
-  : ProcessBase(process::ID::generate("hierarchical-allocator")),
-    initialized(false) {}
-
-
-template <class RoleSorter, class FrameworkSorter>
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::~HierarchicalAllocatorProcess() // NOLINT(whitespace/line_length)
-{}
-
-
-template <class RoleSorter, class FrameworkSorter>
-process::PID<HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter> >
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::self()
-{
-  return process::PID<HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter> >(this); // NOLINT(whitespace/line_length)
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::initialize(
-    const Flags& _flags,
-    const lambda::function<
-        void(const FrameworkID&,
-             const hashmap<SlaveID, Resources>&)>& _offerCallback,
-    const hashmap<std::string, RoleInfo>& _roles)
-{
-  flags = _flags;
-  offerCallback = _offerCallback;
-  roles = _roles;
-  initialized = true;
-
-  roleSorter = new RoleSorter();
-  foreachpair (const std::string& name, const RoleInfo& roleInfo, roles) {
-    roleSorter->add(name, roleInfo.weight());
-    frameworkSorters[name] = new FrameworkSorter();
-  }
-
-  if (roleSorter->count() == 0) {
-    LOG(ERROR) << "No roles specified, cannot allocate resources!";
-  }
-
-  VLOG(1) << "Initialized hierarchical allocator process";
-
-  delay(flags.allocation_interval, self(), &Self::batch);
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::addFramework(
-    const FrameworkID& frameworkId,
-    const FrameworkInfo& frameworkInfo,
-    const Resources& used)
-{
-  CHECK(initialized);
-
-  const std::string& role = frameworkInfo.role();
-
-  CHECK(roles.contains(role));
-
-  CHECK(!frameworkSorters[role]->contains(frameworkId.value()));
-  frameworkSorters[role]->add(frameworkId.value());
-
-  // TODO(bmahler): Validate that the reserved resources have the
-  // framework's role.
-
-  // Update the allocation to this framework.
-  roleSorter->allocated(role, used.unreserved());
-  frameworkSorters[role]->add(used);
-  frameworkSorters[role]->allocated(frameworkId.value(), used);
-
-  frameworks[frameworkId] = Framework();
-  frameworks[frameworkId].role = frameworkInfo.role();
-  frameworks[frameworkId].checkpoint = frameworkInfo.checkpoint();
-
-  LOG(INFO) << "Added framework " << frameworkId;
-
-  allocate();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::removeFramework(
-    const FrameworkID& frameworkId)
-{
-  CHECK(initialized);
-
-  CHECK(frameworks.contains(frameworkId));
-  const std::string& role = frameworks[frameworkId].role;
-
-  // Might not be in 'frameworkSorters[role]' because it was previously
-  // deactivated and never re-added.
-  if (frameworkSorters[role]->contains(frameworkId.value())) {
-    Resources allocation =
-      frameworkSorters[role]->allocation(frameworkId.value());
-
-    roleSorter->unallocated(role, allocation.unreserved());
-    frameworkSorters[role]->remove(allocation);
-    frameworkSorters[role]->remove(frameworkId.value());
-  }
-
-  // Do not delete the filters contained in this
-  // framework's 'filters' hashset yet, see comments in
-  // HierarchicalAllocatorProcess::reviveOffers and
-  // HierarchicalAllocatorProcess::expire.
-  frameworks.erase(frameworkId);
-
-  LOG(INFO) << "Removed framework " << frameworkId;
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::activateFramework(
-    const FrameworkID& frameworkId)
-{
-  CHECK(initialized);
-
-  CHECK(frameworks.contains(frameworkId));
-  const std::string& role = frameworks[frameworkId].role;
-
-  frameworkSorters[role]->activate(frameworkId.value());
-
-  LOG(INFO) << "Activated framework " << frameworkId;
-
-  allocate();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::deactivateFramework(
-    const FrameworkID& frameworkId)
-{
-  CHECK(initialized);
-
-  CHECK(frameworks.contains(frameworkId));
-  const std::string& role = frameworks[frameworkId].role;
-
-  frameworkSorters[role]->deactivate(frameworkId.value());
-
-  // Note that the Sorter *does not* remove the resources allocated
-  // to this framework. For now, this is important because if the
-  // framework fails over and is activated, we still want a record
-  // of the resources that it is using. We might be able to collapse
-  // the added/removed and activated/deactivated in the future.
-
-  // Do not delete the filters contained in this
-  // framework's 'filters' hashset yet, see comments in
-  // HierarchicalAllocatorProcess::reviveOffers and
-  // HierarchicalAllocatorProcess::expire.
-  frameworks[frameworkId].filters.clear();
-
-  LOG(INFO) << "Deactivated framework " << frameworkId;
-}
-
-
-
-// TODO(bmahler): Generalize this.
-template <typename Iterable>
-Resources sum(const Iterable& resources)
-{
-  Resources total;
-  foreach (const Resources& r, resources) {
-    total += r;
-  }
-  return total;
-}
-
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::addSlave(
-    const SlaveID& slaveId,
-    const SlaveInfo& slaveInfo,
-    const Resources& total,
-    const hashmap<FrameworkID, Resources>& used)
-{
-  CHECK(initialized);
-  CHECK(!slaves.contains(slaveId));
-
-  roleSorter->add(total.unreserved());
-
-  foreachpair (const FrameworkID& frameworkId,
-               const Resources& allocated,
-               used) {
-    if (frameworks.contains(frameworkId)) {
-      const std::string& role = frameworks[frameworkId].role;
-
-      // TODO(bmahler): Validate that the reserved resources have the
-      // framework's role.
-
-      roleSorter->allocated(role, allocated.unreserved());
-      frameworkSorters[role]->add(allocated);
-      frameworkSorters[role]->allocated(frameworkId.value(), allocated);
-    }
-  }
-
-  slaves[slaveId] = Slave();
-  slaves[slaveId].total = total;
-  slaves[slaveId].available = total - sum(used.values());
-  slaves[slaveId].activated = true;
-  slaves[slaveId].checkpoint = slaveInfo.checkpoint();
-  slaves[slaveId].hostname = slaveInfo.hostname();
-
-  LOG(INFO) << "Added slave " << slaveId << " (" << slaves[slaveId].hostname
-            << ") with " << slaves[slaveId].total
-            << " (and " << slaves[slaveId].available << " available)";
-
-  allocate(slaveId);
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::removeSlave(
-    const SlaveID& slaveId)
-{
-  CHECK(initialized);
-  CHECK(slaves.contains(slaveId));
-
-  // TODO(bmahler): Per MESOS-621, this should remove the allocations
-  // that any frameworks have on this slave. Otherwise the caller may
-  // "leak" allocated resources accidentally if they forget to recover
-  // all the resources. Fixing this would require more information
-  // than what we currently track in the allocator.
-
-  roleSorter->remove(slaves[slaveId].total.unreserved());
-
-  slaves.erase(slaveId);
-
-  // Note that we DO NOT actually delete any filters associated with
-  // this slave, that will occur when the delayed
-  // HierarchicalAllocatorProcess::expire gets invoked (or the framework
-  // that applied the filters gets removed).
-
-  LOG(INFO) << "Removed slave " << slaveId;
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::activateSlave(
-    const SlaveID& slaveId)
-{
-  CHECK(initialized);
-  CHECK(slaves.contains(slaveId));
-
-  slaves[slaveId].activated = true;
-
-  LOG(INFO)<< "Slave " << slaveId << " reactivated";
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::deactivateSlave(
-    const SlaveID& slaveId)
-{
-  CHECK(initialized);
-  CHECK(slaves.contains(slaveId));
-
-  slaves[slaveId].activated = false;
-
-  LOG(INFO) << "Slave " << slaveId << " deactivated";
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::updateWhitelist(
-    const Option<hashset<std::string> >& _whitelist)
-{
-  CHECK(initialized);
-
-  whitelist = _whitelist;
-
-  if (whitelist.isSome()) {
-    LOG(INFO) << "Updated slave whitelist: " << stringify(whitelist.get());
-
-    if (whitelist.get().empty()) {
-      LOG(WARNING) << "Whitelist is empty, no offers will be made!";
-    }
-  } else {
-    LOG(INFO) << "Advertising offers for all slaves";
-  }
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::requestResources(
-    const FrameworkID& frameworkId,
-    const std::vector<Request>& requests)
-{
-  CHECK(initialized);
-
-  LOG(INFO) << "Received resource request from framework " << frameworkId;
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::updateAllocation(
-    const FrameworkID& frameworkId,
-    const SlaveID& slaveId,
-    const std::vector<Offer::Operation>& operations)
-{
-  CHECK(initialized);
-  CHECK(slaves.contains(slaveId));
-  CHECK(frameworks.contains(frameworkId));
-
-  // The total resources on the slave are composed of both allocated
-  // and available resources:
-  //
-  //    total = available + allocated
-  //
-  // Here we apply offer operations to the allocated resources, which
-  // in turns leads to an update of the total. The available resources
-  // remain unchanged.
-
-  FrameworkSorter* frameworkSorter =
-    frameworkSorters[frameworks[frameworkId].role];
-
-  Resources allocation = frameworkSorter->allocation(frameworkId.value());
-
-  // Update the allocated resources.
-  Try<Resources> updatedAllocation = allocation.apply(operations);
-  CHECK_SOME(updatedAllocation);
-
-  frameworkSorter->update(
-      frameworkId.value(),
-      allocation,
-      updatedAllocation.get());
-
-  roleSorter->update(
-      frameworks[frameworkId].role,
-      allocation.unreserved(),
-      updatedAllocation.get().unreserved());
-
-  // Update the total resources.
-  Try<Resources> updatedTotal = slaves[slaveId].total.apply(operations);
-  CHECK_SOME(updatedTotal);
-
-  slaves[slaveId].total = updatedTotal.get();
-
-  // TODO(bmahler): Validate that the available resources are
-  // unaffected. This requires augmenting the sorters with
-  // SlaveIDs for allocations, so that we can do:
-  //
-  //   CHECK_EQ(slaves[slaveId].total - updatedAllocation,
-  //            slaves[slaveId].available);
-
-  // TODO(jieyu): Do not log if there is no update.
-  LOG(INFO) << "Updated allocation of framework " << frameworkId
-            << " on slave " << slaveId
-            << " from " << allocation << " to " << updatedAllocation.get();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::recoverResources(
-    const FrameworkID& frameworkId,
-    const SlaveID& slaveId,
-    const Resources& resources,
-    const Option<Filters>& filters)
-{
-  CHECK(initialized);
-
-  if (resources.empty()) {
-    return;
-  }
-
-  // Updated resources allocated to framework (if framework still
-  // exists, which it might not in the event that we dispatched
-  // Master::offer before we received
-  // MesosAllocatorProcess::removeFramework or
-  // MesosAllocatorProcess::deactivateFramework, in which case we will
-  // have already recovered all of its resources).
-  if (frameworks.contains(frameworkId)) {
-    const std::string& role = frameworks[frameworkId].role;
-
-    CHECK(frameworkSorters.contains(role));
-
-    if (frameworkSorters[role]->contains(frameworkId.value())) {
-      frameworkSorters[role]->unallocated(frameworkId.value(), resources);
-      frameworkSorters[role]->remove(resources);
-      roleSorter->unallocated(role, resources.unreserved());
-    }
-  }
-
-  // Update resources allocatable on slave (if slave still exists,
-  // which it might not in the event that we dispatched Master::offer
-  // before we received Allocator::removeSlave).
-  if (slaves.contains(slaveId)) {
-    slaves[slaveId].available += resources;
-
-    LOG(INFO) << "Recovered " << resources
-              << " (total allocatable: " << slaves[slaveId].available
-              << ") on slave " << slaveId
-              << " from framework " << frameworkId;
-  }
-
-  // No need to install the filter if 'filters' is none.
-  if (filters.isNone()) {
-    return;
-  }
-
-  // No need to install the filter if slave/framework does not exist.
-  if (!frameworks.contains(frameworkId) || !slaves.contains(slaveId)) {
-    return;
-  }
-
-  // Create a refused resources filter.
-  Try<Duration> seconds = Duration::create(filters.get().refuse_seconds());
-
-  if (seconds.isError()) {
-    LOG(WARNING) << "Using the default value of 'refuse_seconds' to create "
-                 << "the refused resources filter because the input value "
-                 << "is invalid: " << seconds.error();
-
-    seconds = Duration::create(Filters().refuse_seconds());
-  } else if (seconds.get() < Duration::zero()) {
-    LOG(WARNING) << "Using the default value of 'refuse_seconds' to create "
-                 << "the refused resources filter because the input value "
-                 << "is negative";
-
-    seconds = Duration::create(Filters().refuse_seconds());
-  }
-
-  CHECK_SOME(seconds);
-
-  if (seconds.get() != Duration::zero()) {
-    VLOG(1) << "Framework " << frameworkId
-            << " filtered slave " << slaveId
-            << " for " << seconds.get();
-
-    // Create a new filter and delay its expiration.
-    Filter* filter = new RefusedFilter(
-        slaveId,
-        resources,
-        process::Timeout::in(seconds.get()));
-
-    frameworks[frameworkId].filters.insert(filter);
-
-    delay(seconds.get(), self(), &Self::expire, frameworkId, filter);
-  }
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::reviveOffers(
-    const FrameworkID& frameworkId)
-{
-  CHECK(initialized);
-
-  frameworks[frameworkId].filters.clear();
-
-  // We delete each actual Filter when
-  // HierarchicalAllocatorProcess::expire gets invoked. If we delete the
-  // Filter here it's possible that the same Filter (i.e., same
-  // address) could get reused and HierarchicalAllocatorProcess::expire
-  // would expire that filter too soon. Note that this only works
-  // right now because ALL Filter types "expire".
-
-  LOG(INFO) << "Removed filters for framework " << frameworkId;
-
-  allocate();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::batch()
-{
-  allocate();
-  delay(flags.allocation_interval, self(), &Self::batch);
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::allocate()
-{
-  Stopwatch stopwatch;
-  stopwatch.start();
-
-  allocate(slaves.keys());
-
-  VLOG(1) << "Performed allocation for " << slaves.size() << " slaves in "
-            << stopwatch.elapsed();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::allocate(
-    const SlaveID& slaveId)
-{
-  Stopwatch stopwatch;
-  stopwatch.start();
-
-  // TODO(bmahler): Add initializer list constructor for hashset.
-  hashset<SlaveID> slaves;
-  slaves.insert(slaveId);
-  allocate(slaves);
-
-  VLOG(1) << "Performed allocation for slave " << slaveId << " in "
-          << stopwatch.elapsed();
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::allocate(
-    const hashset<SlaveID>& slaveIds_)
-{
-  if (roleSorter->count() == 0) {
-    LOG(ERROR) << "No roles specified, cannot allocate resources!";
-    return;
-  }
-
-  // Compute the offerable resources, per framework:
-  //   (1) For reserved resources on the slave, allocate these to a
-  //       framework having the corresponding role.
-  //   (2) For unreserved resources on the slave, allocate these
-  //       to a framework of any role.
-  hashmap<FrameworkID, hashmap<SlaveID, Resources> > offerable;
-
-  // Randomize the order in which slaves' resources are allocated.
-  // TODO(vinod): Implement a smarter sorting algorithm.
-  std::vector<SlaveID> slaveIds(slaveIds_.begin(), slaveIds_.end());
-  std::random_shuffle(slaveIds.begin(), slaveIds.end());
-
-  foreach (const SlaveID& slaveId, slaveIds) {
-    // Don't send offers for non-whitelisted and deactivated slaves.
-    if (!isWhitelisted(slaveId) || !slaves[slaveId].activated) {
-      continue;
-    }
-
-    foreach (const std::string& role, roleSorter->sort()) {
-      foreach (const std::string& frameworkId_,
-               frameworkSorters[role]->sort()) {
-        FrameworkID frameworkId;
-        frameworkId.set_value(frameworkId_);
-
-        Resources unreserved = slaves[slaveId].available.unreserved();
-        Resources resources = unreserved;
-        if (role != "*") {
-          resources += slaves[slaveId].available.reserved(role);
-        }
-
-        // If the resources are not allocatable, ignore.
-        if (!allocatable(resources)) {
-          continue;
-        }
-
-        // If the framework filters these resources, ignore.
-        if (isFiltered(frameworkId, slaveId, resources)) {
-          continue;
-        }
-
-        VLOG(2) << "Allocating " << resources << " on slave " << slaveId
-                << " to framework " << frameworkId;
-
-        // Note that we perform "coarse-grained" allocation,
-        // meaning that we always allocate the entire remaining
-        // slave resources to a single framework.
-        offerable[frameworkId][slaveId] = resources;
-        slaves[slaveId].available -= resources;
-
-        // Reserved resources are only accounted for in the framework
-        // sorter, since the reserved resources are not shared across
-        // roles.
-        frameworkSorters[role]->add(resources);
-        frameworkSorters[role]->allocated(frameworkId_, resources);
-        roleSorter->allocated(role, unreserved);
-      }
-    }
-  }
-
-  if (offerable.empty()) {
-    VLOG(1) << "No resources available to allocate!";
-  } else {
-    // Now offer the resources to each framework.
-    foreachkey (const FrameworkID& frameworkId, offerable) {
-      offerCallback(frameworkId, offerable[frameworkId]);
-    }
-  }
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-void
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::expire(
-    const FrameworkID& frameworkId,
-    Filter* filter)
-{
-  // The filter might have already been removed (e.g., if the
-  // framework no longer exists or in
-  // HierarchicalAllocatorProcess::reviveOffers) but not yet deleted (to
-  // keep the address from getting reused possibly causing premature
-  // expiration).
-  if (frameworks.contains(frameworkId) &&
-      frameworks[frameworkId].filters.contains(filter)) {
-    frameworks[frameworkId].filters.erase(filter);
-  }
-
-  delete filter;
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-bool
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::isWhitelisted(
-    const SlaveID& slaveId)
-{
-  CHECK(slaves.contains(slaveId));
-
-  return whitelist.isNone() ||
-         whitelist.get().contains(slaves[slaveId].hostname);
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-bool
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::isFiltered(
-    const FrameworkID& frameworkId,
-    const SlaveID& slaveId,
-    const Resources& resources)
-{
-  CHECK(frameworks.contains(frameworkId));
-  CHECK(slaves.contains(slaveId));
-
-  // Do not offer a non-checkpointing slave's resources to a checkpointing
-  // framework. This is a short term fix until the following is resolved:
-  // https://issues.apache.org/jira/browse/MESOS-444.
-  if (frameworks[frameworkId].checkpoint && !slaves[slaveId].checkpoint) {
-    VLOG(1) << "Filtered " << resources
-            << " on non-checkpointing slave " << slaveId
-            << " for checkpointing framework " << frameworkId;
-    return true;
-  }
-
-  foreach (Filter* filter, frameworks[frameworkId].filters) {
-    if (filter->filter(slaveId, resources)) {
-      VLOG(1) << "Filtered " << resources
-              << " on slave " << slaveId
-              << " for framework " << frameworkId;
-      return true;
-    }
-  }
-  return false;
-}
-
-
-template <class RoleSorter, class FrameworkSorter>
-bool
-HierarchicalAllocatorProcess<RoleSorter, FrameworkSorter>::allocatable(
-    const Resources& resources)
-{
-  Option<double> cpus = resources.cpus();
-  Option<Bytes> mem = resources.mem();
-
-  return (cpus.isSome() && cpus.get() >= MIN_CPUS) ||
-         (mem.isSome() && mem.get() >= MIN_MEM);
-}
-
-} // namespace allocator {
-} // namespace master {
-} // namespace mesos {
-
-#endif // __HIERARCHICAL_ALLOCATOR_PROCESS_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/master/main.cpp
----------------------------------------------------------------------
diff --git a/src/master/main.cpp b/src/master/main.cpp
index 765062f..63408f4 100644
--- a/src/master/main.cpp
+++ b/src/master/main.cpp
@@ -46,15 +46,16 @@
 #include "logging/flags.hpp"
 #include "logging/logging.hpp"
 
-#include "master/allocator.hpp"
 #include "master/contender.hpp"
 #include "master/detector.hpp"
-#include "master/drf_sorter.hpp"
-#include "master/hierarchical_allocator_process.hpp"
 #include "master/master.hpp"
 #include "master/registrar.hpp"
 #include "master/repairer.hpp"
 
+#include "master/allocator/allocator.hpp"
+#include "master/allocator/mesos/hierarchical.hpp"
+#include "master/allocator/sorter/drf/sorter.hpp"
+
 #include "module/manager.hpp"
 
 #include "state/in_memory.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/master/master.cpp
----------------------------------------------------------------------
diff --git a/src/master/master.cpp b/src/master/master.cpp
index 9e75b6c..a567a34 100644
--- a/src/master/master.cpp
+++ b/src/master/master.cpp
@@ -73,10 +73,11 @@
 #include "logging/flags.hpp"
 #include "logging/logging.hpp"
 
-#include "master/allocator.hpp"
 #include "master/flags.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "module/manager.hpp"
 
 #include "watcher/whitelist_watcher.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/master/sorter.hpp
----------------------------------------------------------------------
diff --git a/src/master/sorter.hpp b/src/master/sorter.hpp
deleted file mode 100644
index 1561201..0000000
--- a/src/master/sorter.hpp
+++ /dev/null
@@ -1,105 +0,0 @@
-/**
- * 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 __SORTER_HPP__
-#define __SORTER_HPP__
-
-#include <list>
-#include <string>
-
-#include <mesos/resources.hpp>
-
-namespace mesos {
-namespace master {
-namespace allocator {
-
-// Sorters implement the logic for determining the
-// order in which users or frameworks should receive
-// resource allocations.
-//
-// TODO(bmahler): The total and allocated resources are currently
-// aggregated across slaves, which only works for scalar resources.
-// Also, persistent disks are a bit tricky because there will be
-// duplicated persistence IDs within the resources. Consider storing
-// maps keyed off of the slave ID to fix these issues.
-//
-// TODO(bmahler): Templatize this on Client, so that callers can
-// don't need to do string conversion, e.g. FrameworkID, string role,
-// etc.
-class Sorter
-{
-public:
-  virtual ~Sorter() {}
-
-  // Adds a client to allocate resources to. A client
-  // may be a user or a framework.
-  virtual void add(const std::string& client, double weight = 1) = 0;
-
-  // Removes a client.
-  virtual void remove(const std::string& client) = 0;
-
-  // Readds a client to the sort after deactivate.
-  virtual void activate(const std::string& client) = 0;
-
-  // Removes a client from the sort, so it won't get allocated to.
-  virtual void deactivate(const std::string& client) = 0;
-
-  // Specify that resources have been allocated to the given client.
-  virtual void allocated(const std::string& client,
-                         const Resources& resources) = 0;
-
-  // Updates a portion of the allocation for the client, in order to
-  // augment the resources with additional metadata (e.g., volumes)
-  // This means that the new allocation must not affect the static
-  // roles, or the overall quantities of resources!
-  virtual void update(const std::string& client,
-                      const Resources& oldAllocation,
-                      const Resources& newAllocation) = 0;
-
-  // Specify that resources have been unallocated from the given client.
-  virtual void unallocated(const std::string& client,
-                           const Resources& resources) = 0;
-
-  // Returns the resources that have been allocated to this client.
-  virtual Resources allocation(const std::string& client) = 0;
-
-  // Add resources to the total pool of resources this
-  // Sorter should consider.
-  virtual void add(const Resources& resources) = 0;
-
-  // Remove resources from the total pool.
-  virtual void remove(const Resources& resources) = 0;
-
-  // Returns a list of all clients, in the order that they
-  // should be allocated to, according to this Sorter's policy.
-  virtual std::list<std::string> sort() = 0;
-
-  // Returns true if this Sorter contains the specified client,
-  // either active or deactivated.
-  virtual bool contains(const std::string& client) = 0;
-
-  // Returns the number of clients this Sorter contains,
-  // either active or deactivated.
-  virtual int count() = 0;
-};
-
-} // namespace allocator {
-} // namespace master {
-} // namespace mesos {
-
-#endif // __SORTER_HPP__

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/cluster.hpp
----------------------------------------------------------------------
diff --git a/src/tests/cluster.hpp b/src/tests/cluster.hpp
index 1ea763a..ccd68db 100644
--- a/src/tests/cluster.hpp
+++ b/src/tests/cluster.hpp
@@ -52,15 +52,16 @@
 
 #include "log/tool/initialize.hpp"
 
-#include "master/allocator.hpp"
 #include "master/contender.hpp"
 #include "master/detector.hpp"
-#include "master/hierarchical_allocator_process.hpp"
 #include "master/flags.hpp"
 #include "master/master.hpp"
 #include "master/registrar.hpp"
 #include "master/repairer.hpp"
 
+#include "master/allocator/allocator.hpp"
+#include "master/allocator/mesos/hierarchical.hpp"
+
 #include "slave/flags.hpp"
 #include "slave/gc.hpp"
 #include "slave/slave.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/fault_tolerance_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/fault_tolerance_tests.cpp b/src/tests/fault_tolerance_tests.cpp
index 0a477ed..efa5c57 100644
--- a/src/tests/fault_tolerance_tests.cpp
+++ b/src/tests/fault_tolerance_tests.cpp
@@ -39,9 +39,10 @@
 
 #include "common/protobuf_utils.hpp"
 
-#include "master/allocator.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "sched/constants.hpp"
 
 #include "slave/constants.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/hierarchical_allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/hierarchical_allocator_tests.cpp b/src/tests/hierarchical_allocator_tests.cpp
index 7b041f0..eeecfb6 100644
--- a/src/tests/hierarchical_allocator_tests.cpp
+++ b/src/tests/hierarchical_allocator_tests.cpp
@@ -33,10 +33,11 @@
 #include <stout/hashset.hpp>
 #include <stout/utils.hpp>
 
-#include "master/allocator.hpp"
 #include "master/constants.hpp"
 #include "master/flags.hpp"
-#include "master/hierarchical_allocator_process.hpp"
+
+#include "master/allocator/allocator.hpp"
+#include "master/allocator/mesos/hierarchical.hpp"
 
 using namespace mesos;
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/master_allocator_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_allocator_tests.cpp b/src/tests/master_allocator_tests.cpp
index ccbff64..648a7a1 100644
--- a/src/tests/master_allocator_tests.cpp
+++ b/src/tests/master_allocator_tests.cpp
@@ -33,12 +33,13 @@
 #include <stout/some.hpp>
 #include <stout/strings.hpp>
 
-#include "master/allocator.hpp"
 #include "master/constants.hpp"
 #include "master/detector.hpp"
-#include "master/hierarchical_allocator_process.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+#include "master/allocator/mesos/hierarchical.hpp"
+
 #include "tests/containerizer.hpp"
 #include "tests/mesos.hpp"
 

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/master_authorization_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_authorization_tests.cpp b/src/tests/master_authorization_tests.cpp
index 39c54be..fadbd38 100644
--- a/src/tests/master_authorization_tests.cpp
+++ b/src/tests/master_authorization_tests.cpp
@@ -31,9 +31,10 @@
 #include <stout/gtest.hpp>
 #include <stout/try.hpp>
 
-#include "master/allocator.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "messages/messages.hpp"
 
 #include "slave/slave.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/master_slave_reconciliation_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_slave_reconciliation_tests.cpp b/src/tests/master_slave_reconciliation_tests.cpp
index 9f9ee6c..5156898 100644
--- a/src/tests/master_slave_reconciliation_tests.cpp
+++ b/src/tests/master_slave_reconciliation_tests.cpp
@@ -32,9 +32,10 @@
 
 #include "common/protobuf_utils.hpp"
 
-#include "master/allocator.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "slave/slave.hpp"
 
 #include "tests/containerizer.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/master_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/master_tests.cpp b/src/tests/master_tests.cpp
index a5051cb..b821038 100644
--- a/src/tests/master_tests.cpp
+++ b/src/tests/master_tests.cpp
@@ -43,10 +43,11 @@
 #include <stout/strings.hpp>
 #include <stout/try.hpp>
 
-#include "master/allocator.hpp"
 #include "master/flags.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "slave/constants.hpp"
 #include "slave/gc.hpp"
 #include "slave/flags.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/mesos.hpp
----------------------------------------------------------------------
diff --git a/src/tests/mesos.hpp b/src/tests/mesos.hpp
index 266cac3..60c7004 100644
--- a/src/tests/mesos.hpp
+++ b/src/tests/mesos.hpp
@@ -45,10 +45,11 @@
 
 #include "messages/messages.hpp" // For google::protobuf::Message.
 
-#include "master/allocator.hpp"
 #include "master/detector.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "slave/slave.hpp"
 
 #include "slave/containerizer/containerizer.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/rate_limiting_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/rate_limiting_tests.cpp b/src/tests/rate_limiting_tests.cpp
index 718d950..784ac76 100644
--- a/src/tests/rate_limiting_tests.cpp
+++ b/src/tests/rate_limiting_tests.cpp
@@ -25,10 +25,11 @@
 
 #include <process/metrics/metrics.hpp>
 
-#include "master/allocator.hpp"
 #include "master/flags.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/allocator.hpp"
+
 #include "tests/mesos.hpp"
 
 using namespace mesos;

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/resource_offers_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/resource_offers_tests.cpp b/src/tests/resource_offers_tests.cpp
index 6f9a435..1ba73ba 100644
--- a/src/tests/resource_offers_tests.cpp
+++ b/src/tests/resource_offers_tests.cpp
@@ -26,9 +26,10 @@
 #include <stout/strings.hpp>
 #include <stout/uuid.hpp>
 
-#include "master/hierarchical_allocator_process.hpp"
 #include "master/master.hpp"
 
+#include "master/allocator/mesos/hierarchical.hpp"
+
 #include "slave/slave.hpp"
 
 #include "tests/mesos.hpp"

http://git-wip-us.apache.org/repos/asf/mesos/blob/3093759f/src/tests/sorter_tests.cpp
----------------------------------------------------------------------
diff --git a/src/tests/sorter_tests.cpp b/src/tests/sorter_tests.cpp
index c6e5db8..7ba32b7 100644
--- a/src/tests/sorter_tests.cpp
+++ b/src/tests/sorter_tests.cpp
@@ -28,7 +28,7 @@
 
 #include <stout/gtest.hpp>
 
-#include "master/drf_sorter.hpp"
+#include "master/allocator/sorter/drf/sorter.hpp"
 
 using namespace mesos;