<commit_before>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__

#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"

#include "opencv2/core/utility.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp"
#include "opencv2/core/opengl.hpp"
#include "opencv2/core/va_intel.hpp"

#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <float.h>
#include <cstring>
#include <cassert>

#define USE_SSE2  (cv::checkHardwareSupport(CV_CPU_SSE))
#define USE_SSE4_2  (cv::checkHardwareSupport(CV_CPU_SSE4_2))
#define USE_AVX  (cv::checkHardwareSupport(CV_CPU_AVX))
#define USE_AVX2  (cv::checkHardwareSupport(CV_CPU_AVX2))

#include "opencv2/core/hal/hal.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/sse_utils.hpp"
#include "opencv2/core/neon_utils.hpp"

#include "arithm_core.hpp"
#include "hal_replacement.hpp"

#ifdef HAVE_TEGRA_OPTIMIZATION
#include "opencv2/core/core_tegra.hpp"
#else
#define GET_OPTIMIZED(func) (func)
#endif

namespace cv
{

// -128.f ... 255.f
extern const float g_8x32fTab[];
#define CV_8TO32F(x)  cv::g_8x32fTab[(x)+128]

extern const ushort g_8x16uSqrTab[];
#define CV_SQR_8U(x)  cv::g_8x16uSqrTab[(x)+255]

extern const uchar g_Saturate8u[];
#define CV_FAST_CAST_8U(t)   (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256])
#define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
#define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))

template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a + b); }

template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a - b); }

template<> inline short OpAbsDiff<short>::operator ()(short a, short b) const
{ return saturate_cast<short>(std::abs(a - b)); }

template<> inline schar OpAbsDiff<schar>::operator ()(schar a, schar b) const
{ return saturate_cast<schar>(std::abs(a - b)); }

template<> inline uchar OpMin<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }

template<> inline uchar OpMax<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }

typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFuncC)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, int width, int height,
                       void*);

BinaryFunc getConvertFuncFp16(int ddepth, bool useHW);
BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);

/* default memory block for sparse array elements */
#define  CV_SPARSE_MAT_BLOCK     (1<<12)

/* initial hash table size */
#define  CV_SPARSE_HASH_SIZE0    (1<<10)

/* maximal average node_count/hash_size ratio beyond which hash table is resized */
#define  CV_SPARSE_HASH_RATIO    3

#if defined WIN32 || defined _WIN32
void deleteThreadAllocData();
#endif

inline Size getContinuousSize_( int flags, int cols, int rows, int widthScale )
{
    int64 sz = (int64)cols * rows * widthScale;
    return (flags & Mat::CONTINUOUS_FLAG) != 0 &&
        (int)sz == sz ? Size((int)sz, 1) : Size(cols * widthScale, rows);
}

inline Size getContinuousSize( const Mat& m1, int widthScale=1 )
{
    return getContinuousSize_(m1.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, const Mat& m4,
                               int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, const Mat& m4,
                               const Mat& m5, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags & m5.flags,
                              m1.cols, m1.rows, widthScale);
}

struct NoVec
{
    size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
};

enum { BLOCK_SIZE = 1024 };

#if defined HAVE_IPP && (IPP_VERSION_X100 >= 700)
#define ARITHM_USE_IPP 1
#else
#define ARITHM_USE_IPP 0
#endif

inline bool checkScalar(const Mat& sc, int atype, int sckind, int akind)
{
    if( sc.dims > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

inline bool checkScalar(InputArray sc, int atype, int sckind, int akind)
{
    if( sc.dims() > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize );

#ifdef CV_COLLECT_IMPL_DATA
struct ImplCollector
{
    ImplCollector()
    {
        useCollection   = false;
        implFlags       = 0;
    }
    bool useCollection; // enable/disable impl data collection

    int implFlags;
    std::vector<int>    implCode;
    std::vector<String> implFun;

    cv::Mutex mutex;
};
#endif

struct CoreTLSData
{
    CoreTLSData() :
//#ifdef HAVE_OPENCL
        device(0), useOpenCL(-1),
//#endif
        useIPP(-1)
    {
#ifdef HAVE_TEGRA_OPTIMIZATION
        useTegra = -1;
#endif
    }

    RNG rng;
//#ifdef HAVE_OPENCL
    int device;
    ocl::Queue oclQueue;
    int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
//#endif
    int useIPP; // 1 - use, 0 - do not use, -1 - auto/not initialized
#ifdef HAVE_TEGRA_OPTIMIZATION
    int useTegra; // 1 - use, 0 - do not use, -1 - auto/not initialized
#endif
};

TLSData<CoreTLSData>& getCoreTlsData();

#if defined(BUILD_SHARED_LIBS)
#if defined WIN32 || defined _WIN32 || defined WINCE
#define CL_RUNTIME_EXPORT __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#define CL_RUNTIME_EXPORT __attribute__ ((visibility ("default")))
#else
#define CL_RUNTIME_EXPORT
#endif
#else
#define CL_RUNTIME_EXPORT
#endif

extern bool __termination; // skip some cleanups, because process is terminating
                           // (for example, if ExitProcess() was already called)

cv::Mutex& getInitializationMutex();

// TODO Memory barriers?
#define CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, RET_VALUE) \
    static TYPE* volatile instance = NULL; \
    if (instance == NULL) \
    { \
        cv::AutoLock lock(cv::getInitializationMutex()); \
        if (instance == NULL) \
            instance = INITIALIZER; \
    } \
    return RET_VALUE;

#define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance)
#define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance)

}

#endif /*_CXCORE_INTERNAL_H_*/
<commit_msg>fix warning of build<commit_after>/*M///////////////////////////////////////////////////////////////////////////////////////
//
//  IMPORTANT: READ BEFORE DOWNLOADING, COPYING, INSTALLING OR USING.
//
//  By downloading, copying, installing or using the software you agree to this license.
//  If you do not agree to this license, do not download, install,
//  copy or use the software.
//
//
//                           License Agreement
//                For Open Source Computer Vision Library
//
// Copyright (C) 2000-2008, Intel Corporation, all rights reserved.
// Copyright (C) 2009, Willow Garage Inc., all rights reserved.
// Third party copyrights are property of their respective owners.
//
// Redistribution and use in source and binary forms, with or without modification,
// are permitted provided that the following conditions are met:
//
//   * Redistribution's of source code must retain the above copyright notice,
//     this list of conditions and the following disclaimer.
//
//   * Redistribution's in binary form must reproduce the above copyright notice,
//     this list of conditions and the following disclaimer in the documentation
//     and/or other materials provided with the distribution.
//
//   * The name of the copyright holders may not be used to endorse or promote products
//     derived from this software without specific prior written permission.
//
// This software is provided by the copyright holders and contributors "as is" and
// any express or implied warranties, including, but not limited to, the implied
// warranties of merchantability and fitness for a particular purpose are disclaimed.
// In no event shall the Intel Corporation or contributors be liable for any direct,
// indirect, incidental, special, exemplary, or consequential damages
// (including, but not limited to, procurement of substitute goods or services;
// loss of use, data, or profits; or business interruption) however caused
// and on any theory of liability, whether in contract, strict liability,
// or tort (including negligence or otherwise) arising in any way out of
// the use of this software, even if advised of the possibility of such damage.
//
//M*/

#ifndef __OPENCV_PRECOMP_H__
#define __OPENCV_PRECOMP_H__

#include "opencv2/opencv_modules.hpp"
#include "cvconfig.h"

#include "opencv2/core/utility.hpp"
#include "opencv2/core/core_c.h"
#include "opencv2/core/cuda.hpp"
#include "opencv2/core/opengl.hpp"
#include "opencv2/core/va_intel.hpp"

#include "opencv2/core/private.hpp"
#include "opencv2/core/private.cuda.hpp"
#ifdef HAVE_OPENCL
#include "opencv2/core/ocl.hpp"
#endif

#include <assert.h>
#include <ctype.h>
#include <float.h>
#include <limits.h>
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <algorithm>
#include <cmath>
#include <cstdlib>
#include <limits>
#include <float.h>
#include <cstring>
#include <cassert>

#define USE_SSE2  (cv::checkHardwareSupport(CV_CPU_SSE))
#define USE_SSE4_2  (cv::checkHardwareSupport(CV_CPU_SSE4_2))
#define USE_AVX  (cv::checkHardwareSupport(CV_CPU_AVX))
#define USE_AVX2  (cv::checkHardwareSupport(CV_CPU_AVX2))

#include "opencv2/core/hal/hal.hpp"
#include "opencv2/core/hal/intrin.hpp"
#include "opencv2/core/sse_utils.hpp"
#include "opencv2/core/neon_utils.hpp"

#include "arithm_core.hpp"
#include "hal_replacement.hpp"

#ifdef HAVE_TEGRA_OPTIMIZATION
#include "opencv2/core/core_tegra.hpp"
#else
#define GET_OPTIMIZED(func) (func)
#endif

namespace cv
{

// -128.f ... 255.f
extern const float g_8x32fTab[];
#define CV_8TO32F(x)  cv::g_8x32fTab[(x)+128]

extern const ushort g_8x16uSqrTab[];
#define CV_SQR_8U(x)  cv::g_8x16uSqrTab[(x)+255]

extern const uchar g_Saturate8u[];
#define CV_FAST_CAST_8U(t)   (assert(-256 <= (t) && (t) <= 512), cv::g_Saturate8u[(t)+256])
#define CV_MIN_8U(a,b)       ((a) - CV_FAST_CAST_8U((a) - (b)))
#define CV_MAX_8U(a,b)       ((a) + CV_FAST_CAST_8U((b) - (a)))

template<> inline uchar OpAdd<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a + b); }

template<> inline uchar OpSub<uchar>::operator ()(uchar a, uchar b) const
{ return CV_FAST_CAST_8U(a - b); }

template<> inline short OpAbsDiff<short>::operator ()(short a, short b) const
{ return saturate_cast<short>(std::abs(a - b)); }

template<> inline schar OpAbsDiff<schar>::operator ()(schar a, schar b) const
{ return saturate_cast<schar>(std::abs(a - b)); }

template<> inline uchar OpMin<uchar>::operator ()(uchar a, uchar b) const { return CV_MIN_8U(a, b); }

template<> inline uchar OpMax<uchar>::operator ()(uchar a, uchar b) const { return CV_MAX_8U(a, b); }

typedef void (*BinaryFunc)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, Size sz,
                       void*);

typedef void (*BinaryFuncC)(const uchar* src1, size_t step1,
                       const uchar* src2, size_t step2,
                       uchar* dst, size_t step, int width, int height,
                       void*);

BinaryFunc getConvertFuncFp16(int ddepth);
BinaryFunc getConvertFunc(int sdepth, int ddepth);
BinaryFunc getCopyMaskFunc(size_t esz);

/* default memory block for sparse array elements */
#define  CV_SPARSE_MAT_BLOCK     (1<<12)

/* initial hash table size */
#define  CV_SPARSE_HASH_SIZE0    (1<<10)

/* maximal average node_count/hash_size ratio beyond which hash table is resized */
#define  CV_SPARSE_HASH_RATIO    3

#if defined WIN32 || defined _WIN32
void deleteThreadAllocData();
#endif

inline Size getContinuousSize_( int flags, int cols, int rows, int widthScale )
{
    int64 sz = (int64)cols * rows * widthScale;
    return (flags & Mat::CONTINUOUS_FLAG) != 0 &&
        (int)sz == sz ? Size((int)sz, 1) : Size(cols * widthScale, rows);
}

inline Size getContinuousSize( const Mat& m1, int widthScale=1 )
{
    return getContinuousSize_(m1.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, const Mat& m4,
                               int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags,
                              m1.cols, m1.rows, widthScale);
}

inline Size getContinuousSize( const Mat& m1, const Mat& m2,
                               const Mat& m3, const Mat& m4,
                               const Mat& m5, int widthScale=1 )
{
    return getContinuousSize_(m1.flags & m2.flags & m3.flags & m4.flags & m5.flags,
                              m1.cols, m1.rows, widthScale);
}

struct NoVec
{
    size_t operator()(const void*, const void*, void*, size_t) const { return 0; }
};

enum { BLOCK_SIZE = 1024 };

#if defined HAVE_IPP && (IPP_VERSION_X100 >= 700)
#define ARITHM_USE_IPP 1
#else
#define ARITHM_USE_IPP 0
#endif

inline bool checkScalar(const Mat& sc, int atype, int sckind, int akind)
{
    if( sc.dims > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

inline bool checkScalar(InputArray sc, int atype, int sckind, int akind)
{
    if( sc.dims() > 2 || !sc.isContinuous() )
        return false;
    Size sz = sc.size();
    if(sz.width != 1 && sz.height != 1)
        return false;
    int cn = CV_MAT_CN(atype);
    if( akind == _InputArray::MATX && sckind != _InputArray::MATX )
        return false;
    return sz == Size(1, 1) || sz == Size(1, cn) || sz == Size(cn, 1) ||
           (sz == Size(1, 4) && sc.type() == CV_64F && cn <= 4);
}

void convertAndUnrollScalar( const Mat& sc, int buftype, uchar* scbuf, size_t blocksize );

#ifdef CV_COLLECT_IMPL_DATA
struct ImplCollector
{
    ImplCollector()
    {
        useCollection   = false;
        implFlags       = 0;
    }
    bool useCollection; // enable/disable impl data collection

    int implFlags;
    std::vector<int>    implCode;
    std::vector<String> implFun;

    cv::Mutex mutex;
};
#endif

struct CoreTLSData
{
    CoreTLSData() :
//#ifdef HAVE_OPENCL
        device(0), useOpenCL(-1),
//#endif
        useIPP(-1)
    {
#ifdef HAVE_TEGRA_OPTIMIZATION
        useTegra = -1;
#endif
    }

    RNG rng;
//#ifdef HAVE_OPENCL
    int device;
    ocl::Queue oclQueue;
    int useOpenCL; // 1 - use, 0 - do not use, -1 - auto/not initialized
//#endif
    int useIPP; // 1 - use, 0 - do not use, -1 - auto/not initialized
#ifdef HAVE_TEGRA_OPTIMIZATION
    int useTegra; // 1 - use, 0 - do not use, -1 - auto/not initialized
#endif
};

TLSData<CoreTLSData>& getCoreTlsData();

#if defined(BUILD_SHARED_LIBS)
#if defined WIN32 || defined _WIN32 || defined WINCE
#define CL_RUNTIME_EXPORT __declspec(dllexport)
#elif defined __GNUC__ && __GNUC__ >= 4
#define CL_RUNTIME_EXPORT __attribute__ ((visibility ("default")))
#else
#define CL_RUNTIME_EXPORT
#endif
#else
#define CL_RUNTIME_EXPORT
#endif

extern bool __termination; // skip some cleanups, because process is terminating
                           // (for example, if ExitProcess() was already called)

cv::Mutex& getInitializationMutex();

// TODO Memory barriers?
#define CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, RET_VALUE) \
    static TYPE* volatile instance = NULL; \
    if (instance == NULL) \
    { \
        cv::AutoLock lock(cv::getInitializationMutex()); \
        if (instance == NULL) \
            instance = INITIALIZER; \
    } \
    return RET_VALUE;

#define CV_SINGLETON_LAZY_INIT(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, instance)
#define CV_SINGLETON_LAZY_INIT_REF(TYPE, INITIALIZER) CV_SINGLETON_LAZY_INIT_(TYPE, INITIALIZER, *instance)

}

#endif /*_CXCORE_INTERNAL_H_*/
<|endoftext|>


<commit_before>// 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 __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__
#define __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__

#include <string>

#include <mesos/mesos.hpp>

#include <process/future.hpp>
#include <process/id.hpp>
#include <process/metrics/gauge.hpp>
#include <process/metrics/metrics.hpp>

#include <stout/duration.hpp>
#include <stout/hashmap.hpp>
#include <stout/hashset.hpp>
#include <stout/option.hpp>

#include "master/allocator/mesos/allocator.hpp"
#include "master/allocator/sorter/drf/sorter.hpp"

#include "master/constants.hpp"

namespace mesos {
namespace internal {
namespace master {
namespace allocator {

// 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;

namespace internal {

// Forward declarations.
class OfferFilter;
class InverseOfferFilter;

// Implements the basic allocator algorithm - first pick a role by
// some criteria, then pick one of their frameworks to allocate to.
class HierarchicalAllocatorProcess : public MesosAllocatorProcess
{
public:
  HierarchicalAllocatorProcess(
      const std::function<Sorter*()>& _roleSorterFactory,
      const std::function<Sorter*()>& _frameworkSorterFactory)
    : ProcessBase(process::ID::generate("hierarchical-allocator")),
      initialized(false),
      paused(true),
      metrics(*this),
      roleSorter(NULL),
      quotaRoleSorter(NULL),
      roleSorterFactory(_roleSorterFactory),
      frameworkSorterFactory(_frameworkSorterFactory) {}

  virtual ~HierarchicalAllocatorProcess() {}

  process::PID<HierarchicalAllocatorProcess> self() const
  {
    return process::PID<Self>(this);
  }

  void initialize(
      const Duration& allocationInterval,
      const lambda::function<
          void(const FrameworkID&,
               const hashmap<SlaveID, Resources>&)>& offerCallback,
      const lambda::function<
          void(const FrameworkID&,
               const hashmap<SlaveID, UnavailableResources>&)>&
        inverseOfferCallback,
      const hashmap<std::string, double>& weights);

  void recover(
      const int _expectedAgentCount,
      const hashmap<std::string, Quota>& quotas);

  void addFramework(
      const FrameworkID& frameworkId,
      const FrameworkInfo& frameworkInfo,
      const hashmap<SlaveID, Resources>& used);

  void removeFramework(
      const FrameworkID& frameworkId);

  void activateFramework(
      const FrameworkID& frameworkId);

  void deactivateFramework(
      const FrameworkID& frameworkId);

  void updateFramework(
      const FrameworkID& frameworkId,
      const FrameworkInfo& frameworkInfo);

  void addSlave(
      const SlaveID& slaveId,
      const SlaveInfo& slaveInfo,
      const Option<Unavailability>& unavailability,
      const Resources& total,
      const hashmap<FrameworkID, Resources>& used);

  void removeSlave(
      const SlaveID& slaveId);

  void updateSlave(
      const SlaveID& slave,
      const Resources& oversubscribed);

  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);

  process::Future<Nothing> updateAvailable(
      const SlaveID& slaveId,
      const std::vector<Offer::Operation>& operations);

  void updateUnavailability(
      const SlaveID& slaveId,
      const Option<Unavailability>& unavailability);

  void updateInverseOffer(
      const SlaveID& slaveId,
      const FrameworkID& frameworkId,
      const Option<UnavailableResources>& unavailableResources,
      const Option<mesos::master::InverseOfferStatus>& status,
      const Option<Filters>& filters);

  process::Future<
      hashmap<SlaveID, hashmap<FrameworkID, mesos::master::InverseOfferStatus>>>
    getInverseOfferStatuses();

  void recoverResources(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      const Resources& resources,
      const Option<Filters>& filters);

  void suppressOffers(
      const FrameworkID& frameworkId);

  void reviveOffers(
      const FrameworkID& frameworkId);

  void setQuota(
      const std::string& role,
      const Quota& quota);

  void removeQuota(
      const std::string& role);

  void updateWeights(
      const std::vector<WeightInfo>& weightInfos);

protected:
  // Useful typedefs for dispatch/delay/defer to self()/this.
  typedef HierarchicalAllocatorProcess Self;
  typedef HierarchicalAllocatorProcess This;

  // Idempotent helpers for pausing and resuming allocation.
  void pause();
  void resume();

  // 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);

  // Send inverse offers from the specified slaves.
  void deallocate(const hashset<SlaveID>& slaveIds);

  // Remove an offer filter for the specified framework.
  void expire(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      OfferFilter* offerFilter);

  // Remove an inverse offer filter for the specified framework.
  void expire(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      InverseOfferFilter* inverseOfferFilter);

  // Returns the weight of the specified role name.
  double roleWeight(const std::string& name);

  // Checks whether the slave is whitelisted.
  bool isWhitelisted(const SlaveID& slaveId);

  // Returns true if there is a resource offer filter for this framework
  // on this slave.
  bool isFiltered(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      const Resources& resources);

  // Returns true if there is an inverse offer filter for this framework
  // on this slave.
  bool isFiltered(
      const FrameworkID& frameworkID,
      const SlaveID& slaveID);

  bool allocatable(const Resources& resources);

  bool initialized;
  bool paused;

  // Recovery data.
  Option<int> expectedAgentCount;

  Duration allocationInterval;

  lambda::function<
      void(const FrameworkID&,
           const hashmap<SlaveID, Resources>&)> offerCallback;

  lambda::function<
      void(const FrameworkID&,
           const hashmap<SlaveID, UnavailableResources>&)> inverseOfferCallback;

  struct Metrics
  {
    explicit Metrics(const Self& process)
      : event_queue_dispatches(
            "allocator/event_queue_dispatches",
            process::defer(process.self(), &Self::_event_queue_dispatches))
    {
      process::metrics::add(event_queue_dispatches);
    }

    ~Metrics()
    {
      process::metrics::remove(event_queue_dispatches);
    }

    process::metrics::Gauge event_queue_dispatches;
  } metrics;

  struct Framework
  {
    std::string role;

    // Whether the framework suppresses offers.
    bool suppressed;

    // Whether the framework desires revocable resources.
    bool revocable;

    // Active offer and inverse offer filters for the framework.
    hashmap<SlaveID, hashset<OfferFilter*>> offerFilters;
    hashmap<SlaveID, hashset<InverseOfferFilter*>> inverseOfferFilters;
  };

  double _event_queue_dispatches()
  {
    return static_cast<double>(eventCount<process::DispatchEvent>());
  }

  hashmap<FrameworkID, Framework> frameworks;

  struct Slave
  {
    // Total amount of regular *and* oversubscribed resources.
    Resources total;

    // Regular *and* oversubscribed resources that are allocated.
    //
    // NOTE: We keep track of slave's allocated resources despite
    // having that information in sorters. This is because the
    // information in sorters is not accurate if some framework
    // hasn't reregistered. See MESOS-2919 for details.
    Resources allocated;

    // We track the total and allocated resources on the slave, the
    // available resources are computed as follows:
    //
    //   available = total - allocated
    //
    // Note that it's possible for the slave to be over-allocated!
    // In this case, allocated > total.

    bool activated;  // Whether to offer resources.

    std::string hostname;

    // Represents a scheduled unavailability due to maintenance for a specific
    // slave, and the responses from frameworks as to whether they will be able
    // to gracefully handle this unavailability.
    //
    // NOTE: We currently implement maintenance in the allocator to be able to
    // leverage state and features such as the FrameworkSorter and OfferFilter.
    struct Maintenance
    {
      Maintenance(const Unavailability& _unavailability)
        : unavailability(_unavailability) {}

      // The start time and optional duration of the event.
      Unavailability unavailability;

      // A mapping of frameworks to the inverse offer status associated with
      // this unavailability.
      //
      // NOTE: We currently lose this information during a master fail over
      // since it is not persisted or replicated. This is ok as the new master's
      // allocator will send out new inverse offers and re-collect the
      // information. This is similar to all the outstanding offers from an old
      // master being invalidated, and new offers being sent out.
      hashmap<FrameworkID, mesos::master::InverseOfferStatus> statuses;

      // Represents the "unit of accounting" for maintenance. When a
      // `FrameworkID` is present in the hashset it means an inverse offer has
      // been sent out. When it is not present it means no offer is currently
      // outstanding.
      hashset<FrameworkID> offersOutstanding;
    };

    // When the `maintenance` is set the slave is scheduled to be unavailable at
    // a given point in time, for an optional duration. This information is used
    // to send out `InverseOffers`.
    Option<Maintenance> maintenance;
  };

  hashmap<SlaveID, Slave> slaves;

  // Number of registered frameworks for each role. When a role's active
  // count drops to zero, it is removed from this map; the role is also
  // removed from `roleSorter` and its `frameworkSorter` is deleted.
  hashmap<std::string, int> activeRoles;

  // Configured weight for each role, if any; if a role does not
  // appear here, it has the default weight of 1.
  hashmap<std::string, double> weights;

  // Configured quota for each role, if any. Setting quota for a role
  // changes the order that the role's frameworks are offered
  // resources. Quota comes before fair share, hence setting quota moves
  // the role's frameworks towards the front of the allocation queue.
  //
  // NOTE: We currently associate quota with roles, but this may
  // change in the future.
  hashmap<std::string, Quota> quotas;

  // Slaves to send offers for.
  Option<hashset<std::string>> whitelist;

  // There are two stages of allocation. During the first stage resources
  // are allocated only to frameworks in roles with quota set. During the
  // second stage remaining resources that would not be required to satisfy
  // un-allocated quota are then allocated to all frameworks.
  //
  // Each stage comprises two levels of sorting, hence "hierarchical".
  // Level 1 sorts across roles:
  //   Currently, only the allocated portion of the reserved resources are
  //   accounted for fairness calculation.
  //
  // TODO(mpark): Reserved resources should be accounted for fairness
  // calculation whether they are allocated or not, since they model a long or
  // forever running task. That is, the effect of reserving resources is
  // equivalent to launching a task in that the resources that make up the
  // reservation are not available to other roles as non-revocable.
  //
  // Level 2 sorts across frameworks within a particular role:
  //   Reserved resources at this level are, and should be accounted for
  //   fairness calculation only if they are allocated. This is because
  //   reserved resources are fairly shared across the frameworks in the role.
  //
  // The allocator relies on `Sorter`s to employ a particular sorting
  // algorithm. Each level has its own sorter and hence may have different
  // fairness calculations.
  //
  // NOTE: The hierarchical allocator considers revocable resources as
  // regular resources when doing fairness calculations.
  //
  // TODO(vinod): Consider using a different fairness algorithm for
  // revocable resources.

  // A sorter for active roles. This sorter determines the order in which
  // roles are allocated resources during Level 1 of the second stage.
  Sorter* roleSorter;

  // A dedicated sorter for roles for which quota is set. This sorter
  // determines the order in which quota'ed roles are allocated resources
  // during Level 1 of the first stage. Quota'ed roles have resources
  // allocated up to their alloted quota (the first stage) prior to
  // non-quota'ed roles (the second stage).
  //
  // NOTE: A role appears in `quotaRoleSorter` if it has a quota (even if
  // no frameworks are currently registered in that role). In contrast,
  // `roleSorter` only contains entries for roles with one or more
  // registered frameworks.
  //
  // NOTE: We do not include revocable resources in the quota role sorter,
  // because the quota role sorter's job is to perform fair sharing between
  // the quota roles as it pertains to their level of quota satisfaction.
  // Since revocable resources do not increase a role's level of satisfaction
  // toward its quota, we choose to exclude them from the quota role sorter.
  Sorter* quotaRoleSorter;

  // A collection of sorters, one per active role. Each sorter determines
  // the order in which frameworks that belong to the same role are allocated
  // resources inside the role's share. These sorters are used during Level 2
  // for both the first and the second stages.
  hashmap<std::string, Sorter*> frameworkSorters;

  // Factory functions for sorters.
  //
  // NOTE: `quotaRoleSorter` currently reuses `roleSorterFactory`.
  const std::function<Sorter*()> roleSorterFactory;
  const std::function<Sorter*()> frameworkSorterFactory;
};

} // namespace internal {

// We map the templatized version of the `HierarchicalAllocatorProcess` to one
// that relies on sorter factories in the internal namespace. This allows us
// to keep the implemention of the allocator in the implementation file.
template <typename RoleSorter, typename FrameworkSorter>
class HierarchicalAllocatorProcess
  : public internal::HierarchicalAllocatorProcess
{
public:
  HierarchicalAllocatorProcess()
    : internal::HierarchicalAllocatorProcess(
          []() -> Sorter* { return new RoleSorter(); },
          []() -> Sorter* { return new FrameworkSorter(); }) {}
};

} // namespace allocator {
} // namespace master {
} // namespace internal {
} // namespace mesos {

#endif // __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__
<commit_msg>Used `size_t` instead of `int` to track number of frameworks per role.<commit_after>// 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 __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__
#define __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__

#include <string>

#include <mesos/mesos.hpp>

#include <process/future.hpp>
#include <process/id.hpp>
#include <process/metrics/gauge.hpp>
#include <process/metrics/metrics.hpp>

#include <stout/duration.hpp>
#include <stout/hashmap.hpp>
#include <stout/hashset.hpp>
#include <stout/option.hpp>

#include "master/allocator/mesos/allocator.hpp"
#include "master/allocator/sorter/drf/sorter.hpp"

#include "master/constants.hpp"

namespace mesos {
namespace internal {
namespace master {
namespace allocator {

// 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;

namespace internal {

// Forward declarations.
class OfferFilter;
class InverseOfferFilter;

// Implements the basic allocator algorithm - first pick a role by
// some criteria, then pick one of their frameworks to allocate to.
class HierarchicalAllocatorProcess : public MesosAllocatorProcess
{
public:
  HierarchicalAllocatorProcess(
      const std::function<Sorter*()>& _roleSorterFactory,
      const std::function<Sorter*()>& _frameworkSorterFactory)
    : ProcessBase(process::ID::generate("hierarchical-allocator")),
      initialized(false),
      paused(true),
      metrics(*this),
      roleSorter(NULL),
      quotaRoleSorter(NULL),
      roleSorterFactory(_roleSorterFactory),
      frameworkSorterFactory(_frameworkSorterFactory) {}

  virtual ~HierarchicalAllocatorProcess() {}

  process::PID<HierarchicalAllocatorProcess> self() const
  {
    return process::PID<Self>(this);
  }

  void initialize(
      const Duration& allocationInterval,
      const lambda::function<
          void(const FrameworkID&,
               const hashmap<SlaveID, Resources>&)>& offerCallback,
      const lambda::function<
          void(const FrameworkID&,
               const hashmap<SlaveID, UnavailableResources>&)>&
        inverseOfferCallback,
      const hashmap<std::string, double>& weights);

  void recover(
      const int _expectedAgentCount,
      const hashmap<std::string, Quota>& quotas);

  void addFramework(
      const FrameworkID& frameworkId,
      const FrameworkInfo& frameworkInfo,
      const hashmap<SlaveID, Resources>& used);

  void removeFramework(
      const FrameworkID& frameworkId);

  void activateFramework(
      const FrameworkID& frameworkId);

  void deactivateFramework(
      const FrameworkID& frameworkId);

  void updateFramework(
      const FrameworkID& frameworkId,
      const FrameworkInfo& frameworkInfo);

  void addSlave(
      const SlaveID& slaveId,
      const SlaveInfo& slaveInfo,
      const Option<Unavailability>& unavailability,
      const Resources& total,
      const hashmap<FrameworkID, Resources>& used);

  void removeSlave(
      const SlaveID& slaveId);

  void updateSlave(
      const SlaveID& slave,
      const Resources& oversubscribed);

  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);

  process::Future<Nothing> updateAvailable(
      const SlaveID& slaveId,
      const std::vector<Offer::Operation>& operations);

  void updateUnavailability(
      const SlaveID& slaveId,
      const Option<Unavailability>& unavailability);

  void updateInverseOffer(
      const SlaveID& slaveId,
      const FrameworkID& frameworkId,
      const Option<UnavailableResources>& unavailableResources,
      const Option<mesos::master::InverseOfferStatus>& status,
      const Option<Filters>& filters);

  process::Future<
      hashmap<SlaveID, hashmap<FrameworkID, mesos::master::InverseOfferStatus>>>
    getInverseOfferStatuses();

  void recoverResources(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      const Resources& resources,
      const Option<Filters>& filters);

  void suppressOffers(
      const FrameworkID& frameworkId);

  void reviveOffers(
      const FrameworkID& frameworkId);

  void setQuota(
      const std::string& role,
      const Quota& quota);

  void removeQuota(
      const std::string& role);

  void updateWeights(
      const std::vector<WeightInfo>& weightInfos);

protected:
  // Useful typedefs for dispatch/delay/defer to self()/this.
  typedef HierarchicalAllocatorProcess Self;
  typedef HierarchicalAllocatorProcess This;

  // Idempotent helpers for pausing and resuming allocation.
  void pause();
  void resume();

  // 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);

  // Send inverse offers from the specified slaves.
  void deallocate(const hashset<SlaveID>& slaveIds);

  // Remove an offer filter for the specified framework.
  void expire(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      OfferFilter* offerFilter);

  // Remove an inverse offer filter for the specified framework.
  void expire(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      InverseOfferFilter* inverseOfferFilter);

  // Returns the weight of the specified role name.
  double roleWeight(const std::string& name);

  // Checks whether the slave is whitelisted.
  bool isWhitelisted(const SlaveID& slaveId);

  // Returns true if there is a resource offer filter for this framework
  // on this slave.
  bool isFiltered(
      const FrameworkID& frameworkId,
      const SlaveID& slaveId,
      const Resources& resources);

  // Returns true if there is an inverse offer filter for this framework
  // on this slave.
  bool isFiltered(
      const FrameworkID& frameworkID,
      const SlaveID& slaveID);

  bool allocatable(const Resources& resources);

  bool initialized;
  bool paused;

  // Recovery data.
  Option<int> expectedAgentCount;

  Duration allocationInterval;

  lambda::function<
      void(const FrameworkID&,
           const hashmap<SlaveID, Resources>&)> offerCallback;

  lambda::function<
      void(const FrameworkID&,
           const hashmap<SlaveID, UnavailableResources>&)> inverseOfferCallback;

  struct Metrics
  {
    explicit Metrics(const Self& process)
      : event_queue_dispatches(
            "allocator/event_queue_dispatches",
            process::defer(process.self(), &Self::_event_queue_dispatches))
    {
      process::metrics::add(event_queue_dispatches);
    }

    ~Metrics()
    {
      process::metrics::remove(event_queue_dispatches);
    }

    process::metrics::Gauge event_queue_dispatches;
  } metrics;

  struct Framework
  {
    std::string role;

    // Whether the framework suppresses offers.
    bool suppressed;

    // Whether the framework desires revocable resources.
    bool revocable;

    // Active offer and inverse offer filters for the framework.
    hashmap<SlaveID, hashset<OfferFilter*>> offerFilters;
    hashmap<SlaveID, hashset<InverseOfferFilter*>> inverseOfferFilters;
  };

  double _event_queue_dispatches()
  {
    return static_cast<double>(eventCount<process::DispatchEvent>());
  }

  hashmap<FrameworkID, Framework> frameworks;

  struct Slave
  {
    // Total amount of regular *and* oversubscribed resources.
    Resources total;

    // Regular *and* oversubscribed resources that are allocated.
    //
    // NOTE: We keep track of slave's allocated resources despite
    // having that information in sorters. This is because the
    // information in sorters is not accurate if some framework
    // hasn't reregistered. See MESOS-2919 for details.
    Resources allocated;

    // We track the total and allocated resources on the slave, the
    // available resources are computed as follows:
    //
    //   available = total - allocated
    //
    // Note that it's possible for the slave to be over-allocated!
    // In this case, allocated > total.

    bool activated;  // Whether to offer resources.

    std::string hostname;

    // Represents a scheduled unavailability due to maintenance for a specific
    // slave, and the responses from frameworks as to whether they will be able
    // to gracefully handle this unavailability.
    //
    // NOTE: We currently implement maintenance in the allocator to be able to
    // leverage state and features such as the FrameworkSorter and OfferFilter.
    struct Maintenance
    {
      Maintenance(const Unavailability& _unavailability)
        : unavailability(_unavailability) {}

      // The start time and optional duration of the event.
      Unavailability unavailability;

      // A mapping of frameworks to the inverse offer status associated with
      // this unavailability.
      //
      // NOTE: We currently lose this information during a master fail over
      // since it is not persisted or replicated. This is ok as the new master's
      // allocator will send out new inverse offers and re-collect the
      // information. This is similar to all the outstanding offers from an old
      // master being invalidated, and new offers being sent out.
      hashmap<FrameworkID, mesos::master::InverseOfferStatus> statuses;

      // Represents the "unit of accounting" for maintenance. When a
      // `FrameworkID` is present in the hashset it means an inverse offer has
      // been sent out. When it is not present it means no offer is currently
      // outstanding.
      hashset<FrameworkID> offersOutstanding;
    };

    // When the `maintenance` is set the slave is scheduled to be unavailable at
    // a given point in time, for an optional duration. This information is used
    // to send out `InverseOffers`.
    Option<Maintenance> maintenance;
  };

  hashmap<SlaveID, Slave> slaves;

  // Number of registered frameworks for each role. When a role's active
  // count drops to zero, it is removed from this map; the role is also
  // removed from `roleSorter` and its `frameworkSorter` is deleted.
  hashmap<std::string, size_t> activeRoles;

  // Configured weight for each role, if any; if a role does not
  // appear here, it has the default weight of 1.
  hashmap<std::string, double> weights;

  // Configured quota for each role, if any. Setting quota for a role
  // changes the order that the role's frameworks are offered
  // resources. Quota comes before fair share, hence setting quota moves
  // the role's frameworks towards the front of the allocation queue.
  //
  // NOTE: We currently associate quota with roles, but this may
  // change in the future.
  hashmap<std::string, Quota> quotas;

  // Slaves to send offers for.
  Option<hashset<std::string>> whitelist;

  // There are two stages of allocation. During the first stage resources
  // are allocated only to frameworks in roles with quota set. During the
  // second stage remaining resources that would not be required to satisfy
  // un-allocated quota are then allocated to all frameworks.
  //
  // Each stage comprises two levels of sorting, hence "hierarchical".
  // Level 1 sorts across roles:
  //   Currently, only the allocated portion of the reserved resources are
  //   accounted for fairness calculation.
  //
  // TODO(mpark): Reserved resources should be accounted for fairness
  // calculation whether they are allocated or not, since they model a long or
  // forever running task. That is, the effect of reserving resources is
  // equivalent to launching a task in that the resources that make up the
  // reservation are not available to other roles as non-revocable.
  //
  // Level 2 sorts across frameworks within a particular role:
  //   Reserved resources at this level are, and should be accounted for
  //   fairness calculation only if they are allocated. This is because
  //   reserved resources are fairly shared across the frameworks in the role.
  //
  // The allocator relies on `Sorter`s to employ a particular sorting
  // algorithm. Each level has its own sorter and hence may have different
  // fairness calculations.
  //
  // NOTE: The hierarchical allocator considers revocable resources as
  // regular resources when doing fairness calculations.
  //
  // TODO(vinod): Consider using a different fairness algorithm for
  // revocable resources.

  // A sorter for active roles. This sorter determines the order in which
  // roles are allocated resources during Level 1 of the second stage.
  Sorter* roleSorter;

  // A dedicated sorter for roles for which quota is set. This sorter
  // determines the order in which quota'ed roles are allocated resources
  // during Level 1 of the first stage. Quota'ed roles have resources
  // allocated up to their alloted quota (the first stage) prior to
  // non-quota'ed roles (the second stage).
  //
  // NOTE: A role appears in `quotaRoleSorter` if it has a quota (even if
  // no frameworks are currently registered in that role). In contrast,
  // `roleSorter` only contains entries for roles with one or more
  // registered frameworks.
  //
  // NOTE: We do not include revocable resources in the quota role sorter,
  // because the quota role sorter's job is to perform fair sharing between
  // the quota roles as it pertains to their level of quota satisfaction.
  // Since revocable resources do not increase a role's level of satisfaction
  // toward its quota, we choose to exclude them from the quota role sorter.
  Sorter* quotaRoleSorter;

  // A collection of sorters, one per active role. Each sorter determines
  // the order in which frameworks that belong to the same role are allocated
  // resources inside the role's share. These sorters are used during Level 2
  // for both the first and the second stages.
  hashmap<std::string, Sorter*> frameworkSorters;

  // Factory functions for sorters.
  //
  // NOTE: `quotaRoleSorter` currently reuses `roleSorterFactory`.
  const std::function<Sorter*()> roleSorterFactory;
  const std::function<Sorter*()> frameworkSorterFactory;
};

} // namespace internal {

// We map the templatized version of the `HierarchicalAllocatorProcess` to one
// that relies on sorter factories in the internal namespace. This allows us
// to keep the implemention of the allocator in the implementation file.
template <typename RoleSorter, typename FrameworkSorter>
class HierarchicalAllocatorProcess
  : public internal::HierarchicalAllocatorProcess
{
public:
  HierarchicalAllocatorProcess()
    : internal::HierarchicalAllocatorProcess(
          []() -> Sorter* { return new RoleSorter(); },
          []() -> Sorter* { return new FrameworkSorter(); }) {}
};

} // namespace allocator {
} // namespace master {
} // namespace internal {
} // namespace mesos {

#endif // __MASTER_ALLOCATOR_MESOS_HIERARCHICAL_HPP__
<|endoftext|>


<commit_before>#include <stdio.h>
#include <cstring>
#include <string>
#include <iostream>
#include <vector>
#include <CircBuffer.h>

using namespace std;

static int WINDOW_LENGTH = 150;
static int LOOKAHEAD_BUFFER_LENGTH = 30;
static char TERMINAL_DELIMITER = 0x24;
static char NONTERMINAL_DELIMITER = 0x23;

char c;
char c1;
char c2;
char delim[2] = {TERMINAL_DELIMITER, NONTERMINAL_DELIMITER};
bool verbose = false;
CircBuffer dict(WINDOW_LENGTH);
std::vector<string> data;

void process_terminal(string terminal) {
	if (verbose) printf("(0,%s):  %s\n", terminal.c_str(), terminal.c_str());
	data.push_back(terminal);
	dict.put(terminal);
}

void process_nonterminal(int offset, char length) {
	if (verbose) printf("(1,%i,%i):  ",offset, length);
	int i;
	string* decoded_str = new string[length];
	int index = dict.size() - offset;
	dict.get(index, decoded_str, length); //get the data encoded by the pointer
	dict.put(decoded_str, length); //store this data in the dictionary buffer
	for (i=0; i<length; i++) {
		data.push_back(decoded_str[i]);
		if (verbose) printf("%s-", decoded_str[i].c_str());
	}
	if (verbose) printf("\n");
	delete [] decoded_str;
}

void decompress() {
		string line;
	char current_delimiter;
	while (getline(cin, line)) {
		current_delimiter = line.at(0);
		size_t prev = 1, pos;
		while(prev < line.length()) {
			if (current_delimiter == TERMINAL_DELIMITER) {
				pos = line.find_first_of(delim, prev);
				if (pos == string::npos) {
					pos = line.length()-1;
					process_terminal(line.substr(prev, line.length()-prev));
				}
				//printf("Processing terminal %s\n", line.substr(prev, pos-prev).c_str());
				else
					process_terminal(line.substr(prev, pos-prev));
			} else if (current_delimiter == NONTERMINAL_DELIMITER) {
				int offset = ((line.at(prev) & 0x000000ff) << 4) + ((line.at(prev+1) & 0x000000f0) >> 4);
				char length = (line.at(prev+1) & 0x0f);
				pos = prev+2;
				process_nonterminal(offset, length);
			}
			current_delimiter = line.at(pos);
			prev = pos+1;
		}
	}

	int i;
	for (i=0; i<data.size(); i++) {
		printf("%s ", data.at(i).c_str());
	}
	printf("\n");
}

int main(int argc, char** argv) {
	if (argc > 1 && strcmp("-v", argv[1]) == 0) {
		verbose = true;
	}
	decompress();
	return 0;
}<commit_msg>fixed newline bug in reading from cin.<commit_after>#include <stdio.h>
#include <cstring>
#include <string>
#include <iostream>
#include <vector>
#include <CircBuffer.h>

using namespace std;

static int WINDOW_LENGTH = 150;
static int LOOKAHEAD_BUFFER_LENGTH = 30;
static char TERMINAL_DELIMITER = 0x24;
static char NONTERMINAL_DELIMITER = 0x23;

char c;
char c1;
char c2;
char delim[2] = {TERMINAL_DELIMITER, NONTERMINAL_DELIMITER};
bool verbose = false;
CircBuffer dict(WINDOW_LENGTH);
std::vector<string> data;

void process_terminal(string terminal) {
	if (verbose) printf("(0,%s):  %s\n", terminal.c_str(), terminal.c_str());
	data.push_back(terminal);
	dict.put(terminal);
}

void process_nonterminal(int offset, char length) {
	if (verbose) printf("(1,%i,%i):  ",offset, length);
	int i;
	string* decoded_str = new string[length];
	int index = dict.size() - offset;
	dict.get(index, decoded_str, length); //get the data encoded by the pointer
	dict.put(decoded_str, length); //store this data in the dictionary buffer
	for (i=0; i<length; i++) {
		data.push_back(decoded_str[i]);
		if (verbose) printf("%s-", decoded_str[i].c_str());
	}
	if (verbose) printf("\n");
	delete [] decoded_str;
}

void decompress() {
	string line;
	char current_delimiter;
	istreambuf_iterator<char> eos;
	line = string(istreambuf_iterator<char> (cin), eos);
	current_delimiter = line.at(0);
	size_t prev = 1, pos;
	while(prev < line.length()) {
		if (current_delimiter == TERMINAL_DELIMITER) {
			pos = line.find_first_of(delim, prev);
			if (pos == string::npos) {
				pos = line.length()-1;
				process_terminal(line.substr(prev, line.length()-prev));
			}
			else
				process_terminal(line.substr(prev, pos-prev));
		} else if (current_delimiter == NONTERMINAL_DELIMITER) {
			int offset = ((line.at(prev) & 0x000000ff) << 4) + ((line.at(prev+1) & 0x000000f0) >> 4);
			char length = (line.at(prev+1) & 0x0f);
			pos = prev+2;
			process_nonterminal(offset, length);
		}
		current_delimiter = line.at(pos);
		prev = pos+1;
	}

	int i;
	for (i=0; i<data.size(); i++) {
		printf("%s ", data.at(i).c_str());
	}
	printf("\n");
}

int main(int argc, char** argv) {
	if (argc > 1 && strcmp("-v", argv[1]) == 0) {
		verbose = true;
	}
	decompress();
	return 0;
}<|endoftext|>


<commit_before>#include <bits/stdc++.h>
#define f first
#define s second
#define mp make_pair
#define pb push_back
using namespace std;

int main() {
  double rating;
    cout<<"Enter rating: ";
    cin>>rating;
    vector<double> criticRating(10197);
    vector<pair<double,int> > orderRating(10197);
// open a file in read mode.

    //ifstream infile;
    //infile.open("rating.txt");
    //cout << "Reading from the file" << endl;

    for(int i=0; i < 10197; ++i){
        //infile >> criticRating[i];
        cin>>criticRating[i];
        orderRating[i] = (mp(abs(criticRating[i]-rating),i));
    }
    //infile.close();
//
    sort(orderRating.begin(),orderRating.end());
    cout<<"Top recommended movies are: \n";
    //<<orderRating[0].s<<" "<<orderRating[1].s<<" "<<orderRating[2].s<<" "<<orderRating[3].s<<" "<<orderRating[4].s<<endl;
  int flag = 0, i =0;
    while(flag != 2 && i < 10196){
      cout<<orderRating[i].s;
        if(orderRating[i+1].f != orderRating[i].f)
            ++flag;
        ++i;
  }

    return 0;
}
<commit_msg>Delete rating.cpp<commit_after><|endoftext|>


<commit_before>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "prigenerator.h"
#include "shellgenerator.h"
#include "reporthandler.h"
#include "fileout.h"

void PriGenerator::addHeader(const QString &folder, const QString &header)
{
    priHash[folder].headers << header;
}

void PriGenerator::addSource(const QString &folder, const QString &source)
{
    priHash[folder].sources << source;
}

static void collectAndRemoveFile(QTextStream& stream, const QString& file) {
  QFile f(file);
  if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
    QString s = QString::fromLatin1(f.readAll());
    if (file.endsWith(".cpp")) {
      // remove first line include
      s = s.mid(s.indexOf('\n')+1);
    }
    stream << s;
    f.close();
    QFile::remove(file);
  }
}

static QString combineIncludes(const QString& text) {
  QStringList lines = text.split('\n');
  QSet<QString> includes;
  QString result;
  foreach(QString line, lines) {
    if (line.startsWith("#include")) {
      includes.insert(line);
    } else if (line.startsWith("#")) {
      // skip preprocessor stuff
    } else {
      result += line + "\n";
    }
  }
  QStringList includeList = includes.toList();
  qSort(includeList);
  result = includeList.join("\n") + result;
  return result;
}

static QStringList compactFiles(const QStringList& list, const QString& ext, const QString& dir, const QString& prefix) {
  QStringList outList;
  int count = list.count();
  int fileNum = 0;
  QString srcDir = dir;
  if (dir.endsWith("_builtin")) {
    srcDir = dir.left(dir.length()-strlen("_builtin"));
  }
  while (count>0) {
    QString outFileName = prefix + QString::number(fileNum) + ext;
    FileOut file(dir + "/" + outFileName);
    if (ext == ".cpp") {
      file.stream << "#include \"" + prefix + QString::number(fileNum) + ".h\"\n";
    }
    outList << outFileName;
    QString allText;
    QTextStream ts(&allText);
    for (int i = 0; i<MAX_CLASSES_PER_FILE && count>0; i++) {
      collectAndRemoveFile(ts,  srcDir + "/" + list.at(list.length()-count));
      count--;
    }
    allText = combineIncludes(allText);
    file.stream << allText;
    fileNum++;
  }
  return outList;
}

void PriGenerator::generate()
{
    QHashIterator<QString, Pri> pri(priHash);
    while (pri.hasNext()) {
        pri.next();
        QStringList list = pri.value().headers;
        if (list.isEmpty())
            continue;

        QString folder = pri.key();
        folder.replace('\\','/');
        int idx = folder.indexOf('/');
        folder = folder.left(idx);

        qSort(list.begin(), list.end());
        FileOut file(m_out_dir + "/generated_cpp/" + pri.key());

        // strange idea to do the file compacting so late, but it is the most effective way without patching the generator a lot
        bool compact = true;
        if (compact) {
          list = compactFiles(list, ".h", m_out_dir + "/generated_cpp/" + folder, folder);
        }

        file.stream << "HEADERS += \\\n";
        foreach (const QString &entry, list) {
          file.stream << "           $$PWD/" << entry << " \\\n";
        }

        file.stream << "\n";
        file.stream << "SOURCES += \\\n";
        list = pri.value().sources;
        qSort(list.begin(), list.end());
        if (compact) {
          list = compactFiles(list, ".cpp", m_out_dir + "/generated_cpp/" + folder, folder);
        }
        foreach (const QString &entry, list) {
            file.stream << "           $$PWD/" << entry << " \\\n";
        }
        file.stream << "           $$PWD/" << folder << "_init.cpp\n";

        if (file.done())
            ++m_num_generated_written;
        ++m_num_generated;
    }
}
<commit_msg>fixed Qt3Support member<commit_after>/****************************************************************************
**
** Copyright (C) 2008-2009 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the Qt Script Generator project on Qt Labs.
**
** $QT_BEGIN_LICENSE:LGPL$
** No Commercial Usage
** This file contains pre-release code and may not be distributed.
** You may use this file in accordance with the terms and conditions
** contained in the Technology Preview License Agreement accompanying
** this package.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 2.1 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL included in the
** packaging of this file.  Please review the following information to
** ensure the GNU Lesser General Public License version 2.1 requirements
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights.  These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** If you have questions regarding the use of this file, please contact
** Nokia at qt-info@nokia.com.
**
**
**
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "prigenerator.h"
#include "shellgenerator.h"
#include "reporthandler.h"
#include "fileout.h"

void PriGenerator::addHeader(const QString &folder, const QString &header)
{
    priHash[folder].headers << header;
}

void PriGenerator::addSource(const QString &folder, const QString &source)
{
    priHash[folder].sources << source;
}

static void collectAndRemoveFile(QTextStream& stream, const QString& file) {
  QFile f(file);
  if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
    QString s = QString::fromLatin1(f.readAll());
    if (file.endsWith(".cpp")) {
      // remove first line include
      s = s.mid(s.indexOf('\n')+1);
    }
    stream << s;
    f.close();
    QFile::remove(file);
  }
}

static QString combineIncludes(const QString& text) {
  QStringList lines = text.split('\n');
  QSet<QString> includes;
  QString result;
  foreach(QString line, lines) {
    if (line.startsWith("#include")) {
      includes.insert(line);
    } else if (line.startsWith("#")) {
      // skip preprocessor stuff
    } else {
      result += line + "\n";
    }
  }
  QStringList includeList = includes.toList();
  qSort(includeList);
  result = includeList.join("\n") + result;
  return result;
}

static QStringList compactFiles(const QStringList& list, const QString& ext, const QString& dir, const QString& prefix) {
  QStringList outList;
  int count = list.count();
  int fileNum = 0;
  QString srcDir = dir;
  if (dir.endsWith("_builtin")) {
    srcDir = dir.left(dir.length()-strlen("_builtin"));
  }
  while (count>0) {
    QString outFileName = prefix + QString::number(fileNum) + ext;
    FileOut file(dir + "/" + outFileName);
    if (ext == ".cpp") {
      file.stream << "#include \"" + prefix + QString::number(fileNum) + ".h\"\n";
    }
    outList << outFileName;
    QString allText;
    QTextStream ts(&allText);
    for (int i = 0; i<MAX_CLASSES_PER_FILE && count>0; i++) {
      collectAndRemoveFile(ts,  srcDir + "/" + list.at(list.count()-count));
      count--;
    }
    allText = combineIncludes(allText);
    file.stream << allText;
    fileNum++;
  }
  return outList;
}

void PriGenerator::generate()
{
    QHashIterator<QString, Pri> pri(priHash);
    while (pri.hasNext()) {
        pri.next();
        QStringList list = pri.value().headers;
        if (list.isEmpty())
            continue;

        QString folder = pri.key();
        folder.replace('\\','/');
        int idx = folder.indexOf('/');
        folder = folder.left(idx);

        qSort(list.begin(), list.end());
        FileOut file(m_out_dir + "/generated_cpp/" + pri.key());

        // strange idea to do the file compacting so late, but it is the most effective way without patching the generator a lot
        bool compact = true;
        if (compact) {
          list = compactFiles(list, ".h", m_out_dir + "/generated_cpp/" + folder, folder);
        }

        file.stream << "HEADERS += \\\n";
        foreach (const QString &entry, list) {
          file.stream << "           $$PWD/" << entry << " \\\n";
        }

        file.stream << "\n";
        file.stream << "SOURCES += \\\n";
        list = pri.value().sources;
        qSort(list.begin(), list.end());
        if (compact) {
          list = compactFiles(list, ".cpp", m_out_dir + "/generated_cpp/" + folder, folder);
        }
        foreach (const QString &entry, list) {
            file.stream << "           $$PWD/" << entry << " \\\n";
        }
        file.stream << "           $$PWD/" << folder << "_init.cpp\n";

        if (file.done())
            ++m_num_generated_written;
        ++m_num_generated;
    }
}
<|endoftext|>


<commit_before>#include "RedBlackTree.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <utility>

#define RED 'R'
#define BLACK 'B'

RbNode RBNIL = {BLACK, -1, &RBNIL, &RBNIL, &RBNIL};

static RbNode *Next(RbNode *e) {
  if (is_nil(e->right)) {
    return &RBNIL;
  }
  RbNode *next = e->right;
  while (not_nil(next->left)) {
    next = next->left;
  }
  return next;
}

static RbNode *GrandFather(RbNode *e) {
  if (is_nil(e))
    return &RBNIL;
  if (is_nil(e->father))
    return &RBNIL;
  return e->father->father;
}

static RbNode *Uncle(RbNode *e) {
  if (is_nil(GrandFather(e)))
    return &RBNIL;
  if (GrandFather(e)->left == e->father)
    return GrandFather(e)->right;
  if (GrandFather(e)->right == e->father)
    return GrandFather(e)->left;
  return &RBNIL;
}

static bool IsLeft(RbNode *e) {
  if (is_nil(e->father))
    return false;
  return e->father->left == e;
}

static bool IsRight(RbNode *e) {
  if (is_nil(e->father))
    return false;
  return e->father->right == e;
}

static RbNode *Brother(RbNode *e) {
  if (is_nil(e))
    return &RBNIL;
  if (IsLeft(e)) {
    return e->father->right;
  }
  if (IsRight(e)) {
    return e->father->left;
  }
  return &RBNIL;
}

static void DumpNode(RbNode *e) {
  assert(e);
  if (is_nil(e)) {
    std::cout << " [nil B]" << std::endl;
  } else {
    std::cout << " [" << e->value << " " << (e->color == RED ? "R" : "B")
              << " left:"
              << (is_nil(e->left) ? "nil" : std::to_string(e->left->value))
              << " right:"
              << (is_nil(e->right) ? "nil" : std::to_string(e->right->value))
              << " father:"
              << (is_nil(e->father) ? "nil" : std::to_string(e->father->value))
              << "]" << std::endl;
    if (not_nil(e->left)) {
      DumpNode(e->left);
    }
    if (not_nil(e->right)) {
      DumpNode(e->right);
    }
  }
}

static void DumpTree(RedBlackTree *t) {
  assert(t);
  std::cout << std::endl << std::endl << std::endl;
  DumpNode(t->root);
}

static void Free(RbNode *e) {
  if (is_nil(e))
    return;
  Free(e->left);
  Free(e->right);
  delete e;
}

static void LeftRotate(RbNode *&father, RbNode *&e) {
  RbNode *p_right = e->right;
  e->right = p_right->left;

  if (not_nil(e->right)) {
    e->right->father = e;
  }

  p_right->father = e->father;

  if (is_nil(e->father)) {
    father = p_right;
  } else if (e == e->father->left) {
    e->father->left = p_right;
  } else {
    e->father->right = p_right;
  }

  p_right->left = e;
  e->father = p_right;
}

static void RightRotate(RbNode *&father, RbNode *&e) {
  RbNode *p_left = e->left;
  e->left = p_left->right;

  if (not_nil(e->left)) {
    e->left->father = e;
  }

  p_left->father = e->father;

  if (is_nil(e->father)) {
    father = p_left;
  } else if (e == e->father->left) {
    e->father->left = p_left;
  } else {
    e->father->right = p_left;
  }

  p_left->right = e;
  e->father = p_left;
}

void FixInsert(RbNode *&root, RbNode *&e) {
  RbNode *e_father, *e_grand_father, *e_uncle;
  set_nil(e_father);
  set_nil(e_grand_father);

  while ((e != root) && (e->color == RED) && (e->father->color == RED)) {
    e_father = e->father;
    e_grand_father = GrandFather(e);
    e_uncle = Uncle(e);

    // case A: e_father is e_grand_father's left child
    if (IsLeft(e_father)) {

      // case 1: Red Uncle, e e_uncle is red
      if (not_nil(e_uncle) && e_uncle->color == RED) {
        assert(e_father == RED);
        assert(e_grand_father == RED);
        e_grand_father->color = RED;
        e_father->color = BLACK;
        e_uncle->color = BLACK;
        e = e_grand_father; // next loop from e_grand_father

      } else {
        // case 2: Black Uncle, left-right-case
        if (IsRight(e)) {
          LeftRotate(root, e_father);
          e = e_father;
          e_father = e->father;
        }

        // case 3: Black Uncle, left-left-case
        RightRotate(root, e_grand_father);
        std::swap(e_father->color, e_grand_father->color);
        e = e_father; // next loop from e_father
      }
    }

    // case B: e_father is e_grand_father's right child
    else {

      // case 1: Red Uncle
      if (not_nil(e_uncle) && (e_uncle->color == RED)) {
        e_grand_father->color = RED;
        e_father->color = BLACK;
        e_uncle->color = BLACK;
        e = e_grand_father; // next loop from e_grand_father
      } else {

        // case 4: Black Uncle, left-right-case
        if (IsLeft(e)) {
          RightRotate(root, e_father);
          e = e_father;
          e_father = e->father;
        }

        // case 5: Black Uncle, right-right-case
        LeftRotate(root, e_grand_father);
        std::swap(e_father->color, e_grand_father->color);
        e = e_father; // next loop from e_father
      }
    }
  } // while

  root->color = BLACK;
}

static void FixErase(RbNode *&root, RbNode *&e) {
  // Reached root
  if (e == root) {
    return;
  }

  RbNode *e_brother = Brother(e);
  RbNode *e_father = e->father;

  if (is_nil(e_brother)) {
    // No sibiling, double black pushed up
    FixErase(root, e_father);
  } else {
    if (e_brother->color == RED) {
      // brother red
      e_father->color = RED;
      e_brother->color = BLACK;
      if (IsLeft(e_brother)) {
        // left case
        RightRotate(root, e_father);
      } else {
        // right case
        LeftRotate(root, e_father);
      }
      FixErase(root, e);
    } else {
      // brother black
      if (e_brother->left->color == RED || e_brother->right->color == RED) {
        // at least 1 red children
        if (not_nil(e_brother->left) && e_brother->left->color == RED) {
          if (IsLeft(e_brother)) {
            // left left
            e_brother->left->color = e_brother->color;
            e_brother->color = e_father->color;
            RightRotate(root, e_father);
          } else {
            // right left
            e_brother->left->color = e_father->color;
            RightRotate(root, e_brother);
            LeftRotate(root, e_father);
          }
        } else {
          if (IsLeft(e_brother)) {
            // left right
            e_brother->right->color = e_father->color;
            LeftRotate(root, e_brother);
            RightRotate(root, e_father);
          } else {
            // right right
            e_brother->right->color = e_brother->color;
            e_brother->color = e_father->color;
            LeftRotate(root, e_father);
          }
        }
        e_father->color = BLACK;
      } else {
        // 2 black children
        e_brother->color = RED;
        if (e_father->color == BLACK) {
          FixErase(root, e_father);
        } else {
          e_father->color = BLACK;
        }
      }
    }
  }
}

static void Erase(RbNode *&root, RbNode *&e) {

  // case 1: e has no child
  if (is_nil(e->left) && is_nil(e->right)) {
    if (e == root) {
      set_nil(root);
    } else {
      if (e->color == BLACK) {
        FixErase(root, e);
      } else {
        if (not_nil(Uncle(e))) {
          Uncle(e)->color = RED;
        }
      }
      if (IsLeft(e)) {
        set_nil(e->father->left);
      } else {
        set_nil(e->father->right);
      }
    }
    delete e;
    return;
  }

  // case 2: e has 1 child
  if (is_nil(e->left) || is_nil(e->right)) {
    RbNode *p = not_nil(e->left) ? e->left : e->right;
    if (e == root) {
      e->value = p->value;
      set_nil(e->left);
      set_nil(e->right);
      delete p;
    } else {
      if (IsLeft(e)) {
        e->father->left = p;
      } else {
        e->father->right = p;
      }
      delete e;
      p->father = e->father;
      if (e->color == BLACK && p->color == BLACK) {
        FixErase(root, e);
      } else {
        p->color = BLACK;
      }
    }
    return;
  }

  // case 3: e has 2 child
  RbNode *p = Next(e);
  std::swap(p->color, e->color);
  Erase(root, p);
}

static RbNode *Find(RbNode *e, int value) {
  if (is_nil(e)) {
    return &RBNIL;
  }
  //二分查找
  if (e->value == value) {
    return e;
  } else if (e->value > value) {
    return Find(e->left, value);
  } else {
    return Find(e->right, value);
  }
}

static RbNode *Insert(RbNode *father, RbNode *e) {
  assert(father);
  assert(e);

  if (is_nil(father)) {
    return e;
  }

  //利用二分查找找到适合value插入的位置e

  if (father->value > e->value) {
    father->left = Insert(father->left, e);
    father->left->father = father;
  } else if (father->value < e->value) {
    father->right = Insert(father->right, e);
    father->right->father = father;
  } else {
    assert(father->value != e->value);
  }
  return father;
}

RedBlackTree *RedBlackTreeNew() {
  RedBlackTree *t = new RedBlackTree();
  if (!t)
    return NULL;
  t->root = &RBNIL;
  return t;
}

void RedBlackTreeFree(RedBlackTree *t) {
  assert(t);
  Free(t->root);
  delete t;
}

void RedBlackTreeInsert(RedBlackTree *t, int value) {
  assert(t);
  assert(value >= 0);

  RbNode *e = new RbNode();
  set_nil(e->left);
  set_nil(e->right);
  set_nil(e->father);
  e->color = RED; // new node is red
  e->value = value;

  t->root = Insert(t->root, e);
  FixInsert(t->root, e);
  DumpTree(t);
}

RbNode *RedBlackTreeFind(RedBlackTree *t, int value) {
  return Find(t->root, value);
}

void RedBlackTreeErase(RedBlackTree *t, int value) {
  RbNode *e = Find(t->root, value);
  if (is_nil(e)) {
    return;
  }
  Erase(t->root, e);
  DumpTree(t);
}

<commit_msg>update comment<commit_after>#include "RedBlackTree.h"
#include <algorithm>
#include <cassert>
#include <iostream>
#include <string>
#include <utility>

#define RED 'R'
#define BLACK 'B'

RbNode RBNIL = {BLACK, -1, &RBNIL, &RBNIL, &RBNIL};

static RbNode *Next(RbNode *e) {
  if (is_nil(e->right)) {
    return &RBNIL;
  }
  RbNode *next = e->right;
  while (not_nil(next->left)) {
    next = next->left;
  }
  return next;
}

static RbNode *GrandFather(RbNode *e) {
  if (is_nil(e))
    return &RBNIL;
  if (is_nil(e->father))
    return &RBNIL;
  return e->father->father;
}

static RbNode *Uncle(RbNode *e) {
  if (is_nil(GrandFather(e)))
    return &RBNIL;
  if (GrandFather(e)->left == e->father)
    return GrandFather(e)->right;
  if (GrandFather(e)->right == e->father)
    return GrandFather(e)->left;
  return &RBNIL;
}

static bool IsLeft(RbNode *e) {
  if (is_nil(e->father))
    return false;
  return e->father->left == e;
}

static bool IsRight(RbNode *e) {
  if (is_nil(e->father))
    return false;
  return e->father->right == e;
}

static RbNode *Brother(RbNode *e) {
  if (is_nil(e))
    return &RBNIL;
  if (IsLeft(e)) {
    return e->father->right;
  }
  if (IsRight(e)) {
    return e->father->left;
  }
  return &RBNIL;
}

static void DumpNode(RbNode *e) {
  assert(e);
  if (is_nil(e)) {
    std::cout << " [nil B]" << std::endl;
  } else {
    std::cout << " [" << e->value << " " << (e->color == RED ? "R" : "B")
              << " left:"
              << (is_nil(e->left) ? "nil" : std::to_string(e->left->value))
              << " right:"
              << (is_nil(e->right) ? "nil" : std::to_string(e->right->value))
              << " father:"
              << (is_nil(e->father) ? "nil" : std::to_string(e->father->value))
              << "]" << std::endl;
    if (not_nil(e->left)) {
      DumpNode(e->left);
    }
    if (not_nil(e->right)) {
      DumpNode(e->right);
    }
  }
}

static void DumpTree(RedBlackTree *t, const char *msg) {
  assert(t);
  std::cout << std::endl << std::endl << msg << std::endl;
  DumpNode(t->root);
}

static void Free(RbNode *e) {
  if (is_nil(e))
    return;
  Free(e->left);
  Free(e->right);
  delete e;
}

static void LeftRotate(RbNode *&father, RbNode *&e) {
  RbNode *p = e->right;
  e->right = p->left;

  if (not_nil(e->right)) {
    e->right->father = e;
  }

  p->father = e->father;

  if (is_nil(e->father)) {
    father = p;
  } else if (IsLeft(e)) {
    e->father->left = p;
  } else {
    e->father->right = p;
  }

  p->left = e;
  e->father = p;
}

static void RightRotate(RbNode *&father, RbNode *&e) {
  RbNode *p = e->left;
  e->left = p->right;

  if (not_nil(e->left)) {
    e->left->father = e;
  }

  p->father = e->father;

  if (is_nil(e->father)) {
    father = p;
  } else if (IsLeft(e)) {
    e->father->left = p;
  } else {
    e->father->right = p;
  }

  p->right = e;
  e->father = p;
}

void FixInsert(RbNode *&root, RbNode *&e) {
  RbNode *e_father, *e_grand_father, *e_uncle;
  set_nil(e_father);
  set_nil(e_grand_father);

  while ((e != root) && (e->color == RED) && (e->father->color == RED)) {
    e_father = e->father;
    e_grand_father = GrandFather(e);
    e_uncle = Uncle(e);

    // case A: e_father is e_grand_father's left child
    if (IsLeft(e_father)) {

      // case 1: Red Uncle, e e_uncle is red
      if (not_nil(e_uncle) && e_uncle->color == RED) {
        assert(e_father->color == RED);
        assert(e_grand_father->color == RED);
        e_grand_father->color = RED;
        e_father->color = BLACK;
        e_uncle->color = BLACK;
        e = e_grand_father; // next loop from e_grand_father

      } else {
        // case 2: Black Uncle, left-right-case
        if (IsRight(e)) {
          LeftRotate(root, e_father);
          e = e_father;
          e_father = e->father;
        }

        // case 3: Black Uncle, left-left-case
        RightRotate(root, e_grand_father);
        std::swap(e_father->color, e_grand_father->color);
        e = e_father; // next loop from e_father
      }
    }

    // case B: e_father is e_grand_father's right child
    else {

      // case 1: Red Uncle
      if (not_nil(e_uncle) && (e_uncle->color == RED)) {
        e_grand_father->color = RED;
        e_father->color = BLACK;
        e_uncle->color = BLACK;
        e = e_grand_father; // next loop from e_grand_father
      } else {

        // case 4: Black Uncle, left-right-case
        if (IsLeft(e)) {
          RightRotate(root, e_father);
          e = e_father;
          e_father = e->father;
        }

        // case 5: Black Uncle, right-right-case
        LeftRotate(root, e_grand_father);
        std::swap(e_father->color, e_grand_father->color);
        e = e_father; // next loop from e_father
      }
    }
  } // while

  root->color = BLACK;
}

static void FixErase(RbNode *&root, RbNode *&e) {
  // Reached root
  if (e == root) {
    return;
  }

  RbNode *e_brother = Brother(e);
  RbNode *e_father = e->father;

  if (is_nil(e_brother)) {
    // no brother, double black pushed up
    FixErase(root, e_father);
  } else {
    if (e_brother->color == RED) {
      // brother red
      e_father->color = RED;
      e_brother->color = BLACK;
      if (IsLeft(e_brother)) {
        // left case
        RightRotate(root, e_father);
      } else {
        // right case
        LeftRotate(root, e_father);
      }
      FixErase(root, e);
    } else {
      // brother black
      // at least 1 red children
      if (e_brother->left->color == RED || e_brother->right->color == RED) {
        if (not_nil(e_brother->left) && e_brother->left->color == RED) {
          if (IsLeft(e_brother)) {
            // left left
            e_brother->left->color = e_brother->color;
            e_brother->color = e_father->color;
            RightRotate(root, e_father);
          } else {
            // right left
            e_brother->left->color = e_father->color;
            RightRotate(root, e_brother);
            LeftRotate(root, e_father);
          }
        } else {
          if (IsLeft(e_brother)) {
            // left right
            e_brother->right->color = e_father->color;
            LeftRotate(root, e_brother);
            RightRotate(root, e_father);
          } else {
            // right right
            e_brother->right->color = e_brother->color;
            e_brother->color = e_father->color;
            LeftRotate(root, e_father);
          }
        }
        e_father->color = BLACK;
      } else {
        // 2 black children
        e_brother->color = RED;
        if (e_father->color == BLACK) {
          FixErase(root, e_father);
        } else {
          e_father->color = BLACK;
        }
      }
    }
  }
}

static void Erase(RbNode *&root, RbNode *&e) {

  // case 1: e has no child
  if (is_nil(e->left) && is_nil(e->right)) {
    if (e == root) {
      set_nil(root);
    } else {
      if (e->color == BLACK) {
        FixErase(root, e);
      } else {
        if (not_nil(Uncle(e))) {
          Uncle(e)->color = RED;
        }
      }
      if (IsLeft(e)) {
        set_nil(e->father->left);
      } else {
        set_nil(e->father->right);
      }
    }
    delete e;
    return;
  }

  // case 2: e has 1 child
  if (is_nil(e->left) || is_nil(e->right)) {
    RbNode *p = not_nil(e->left) ? e->left : e->right;
    if (e == root) {
      e->value = p->value;
      set_nil(e->left);
      set_nil(e->right);
      delete p;
    } else {
      if (IsLeft(e)) {
        e->father->left = p;
      } else {
        e->father->right = p;
      }
      delete e;
      p->father = e->father;
      if (e->color == BLACK && p->color == BLACK) {
        FixErase(root, e);
      } else {
        p->color = BLACK;
      }
    }
    return;
  }

  // case 3: e has 2 child
  RbNode *p = Next(e);
  std::swap(p->color, e->color);
  Erase(root, p);
}

static RbNode *Find(RbNode *e, int value) {
  if (is_nil(e)) {
    return &RBNIL;
  }
  //二分查找
  if (e->value == value) {
    return e;
  } else if (e->value > value) {
    return Find(e->left, value);
  } else {
    return Find(e->right, value);
  }
}

static RbNode *Insert(RbNode *father, RbNode *e) {
  assert(father);
  assert(e);

  if (is_nil(father)) {
    return e;
  }

  //利用二分查找找到适合value插入的位置e

  if (father->value > e->value) {
    father->left = Insert(father->left, e);
    father->left->father = father;
  } else if (father->value < e->value) {
    father->right = Insert(father->right, e);
    father->right->father = father;
  } else {
    assert(father->value != e->value);
  }
  return father;
}

RedBlackTree *RedBlackTreeNew() {
  RedBlackTree *t = new RedBlackTree();
  if (!t)
    return NULL;
  t->root = &RBNIL;
  return t;
}

void RedBlackTreeFree(RedBlackTree *t) {
  assert(t);
  Free(t->root);
  delete t;
}

void RedBlackTreeInsert(RedBlackTree *t, int value) {
  assert(t);
  assert(value >= 0);

  RbNode *e = new RbNode();
  set_nil(e->left);
  set_nil(e->right);
  set_nil(e->father);
  e->color = RED; // new node is red
  e->value = value;

  t->root = Insert(t->root, e);
  DumpTree(t, "before fix insert");
  FixInsert(t->root, e);
  DumpTree(t, "after fix insert");
}

RbNode *RedBlackTreeFind(RedBlackTree *t, int value) {
  return Find(t->root, value);
}

void RedBlackTreeErase(RedBlackTree *t, int value) {
  RbNode *e = Find(t->root, value);
  if (is_nil(e)) {
    return;
  }
  Erase(t->root, e);
  DumpTree(t, "erase");
}

<|endoftext|>


<commit_before>#include <iostream>
#include <string>
#include "consoleui.h"
#include "performer.h"
#include "dataaccess.h"

using namespace std;

ConsoleUI::ConsoleUI()
{

}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{
    cout << endl;
    cout << "This program is designed to keep track of some details on known computer scientists. " << endl;
    cout << "User is able to enter known characters from the history of computer science into a database." << endl;
    cout << "The program can display a list of the characters that have been entered into the database." << endl;
    cout << "It is also possible to perform a search of a specific person from the list." << endl;
    for (int i = 0; i < 45*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    cout << endl;
    cout << "Please enter one of the following commands to continue:" << endl;
    cout << endl;
    cout << "list   - This will list all computer scientists in the system" << endl;
    cout << "add    - This will add a new computer scientists" << endl;
    cout << "delete - Removes an entry" << endl;
    cout << "update - Updates an entry" << endl;
    cout << "search - Searches for a given computer scientist" << endl;
    cout << "help   - displays list of commands" << endl;
    cout << "exit   - This will close the application" << endl;

    string command;

    do
    {
        cout << endl << "Type a command: ";
        cin >> command;
        cout << endl;
        if (command == "list")
        {
            displayListOfPerformers();
        }

        else if (command == "add")
        {

            _data.writeData();

            //Performer newPerformer(name, gender, bYear, dYear);

            // TODO:
            //_service.addPerformer(newPerformer);
        }

        else if (command == "search")
        {

            string input;
            cout << "Enter name to search for: ";
            cin.ignore();
            getline(cin, input);

            vector <Performer> newVector = _service.search(input);
            for(size_t i = 0; i < newVector.size(); i++)
            {
            cout << "Found:" << endl;
            cout << "----------" << endl;
            cout << "Name: " << newVector[i].getName() << endl;
            cout << "Gender: " << newVector[i].getGender() << endl;
            cout << "Birth year: " << newVector[i].getbYear() << endl;
            cout << "Death year: " << newVector[i].getdYear() << endl;
            cout << endl;
            }

            if(newVector.size() == 0)
            {
                cout << "Nothing was found!";
            }
        }

        else if (command == "delete")
        {
            cout << "Entry removed" << endl;
        }

        else if (command == "help")
        {
            cout << "list   - This will list all computer scientists in the system" << endl;
            cout << "add    - This will add a new computer scientist" << endl;
            cout << "delete - Removes an entry" << endl;
            cout << "update - Updates an entry" << endl;
            cout << "search - Searches for a given computer scientist" << endl;
            cout << "help   - Displays list of commands" << endl;
            cout << "exit   - This will close the application" << endl;
        }

        else if (command == "exit")
        {
            cout << "exiting" << endl;
        }

        else if(command == "data")
        {
            vector<string> logs = _data.readData();

            string choose;
            cin >> choose;
            if(choose == "name")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "gender")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+1] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "birth")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+2] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "death")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+3] << endl;
                    i =  i + 3;
                }
            }

        }

        else
        {
            cout << "invalid command." << endl;
            cout << "type 'help' to see list of commands" << endl;
        }

    }while (command != "exit");
}

void ConsoleUI::displayListOfPerformers()
{
    vector<Performer> performers = _service.getPerformers();
    //cout << "name" << endl;
    //cout << "===============" << endl;
    cout << "Nr" << "\t" << "Name" << "\t\t" << "Gender";
    cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << endl;
    for (int i = 0; i < 41*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    for (size_t i = 0; i< performers.size(); ++i)
    {
        cout << i+1 << "\t" << performers[i].getName()
             << "\t"  << performers[i].getGender() << "\t" << "\t"
             << performers[i].getbYear() << "\t\t\t" << performers[i].getdYear()
             << endl;
    }
}

<commit_msg>smá breytingar<commit_after>#include <iostream>
#include <string>
#include "consoleui.h"
#include "performer.h"
#include "dataaccess.h"

using namespace std;

ConsoleUI::ConsoleUI()
{

}

// Should not contain logic for individual commands, that should be in separate functions!
void ConsoleUI::run()
{
    cout << endl;
    cout << "This program is designed to keep track of some details on known computer scientists. " << endl;
    cout << "User is able to enter known characters from the history of computer science into a database." << endl;
    cout << "The program can display a list of the characters that have been entered into the database." << endl;
    cout << "It is also possible to perform a search of a specific person from the list." << endl;
    for (int i = 0; i < 45*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    cout << endl;
    cout << "Please enter one of the following commands to continue:" << endl;
    cout << endl;
    cout << "list   - This will list all computer scientists in the system" << endl;
    cout << "add    - This will add a new computer scientists" << endl;
    cout << "delete - Removes an entry" << endl;
    cout << "update - Updates an entry" << endl;
    cout << "search - Searches for a given computer scientist" << endl;
    cout << "help   - displays list of commands" << endl;
    cout << "exit   - This will close the application" << endl;

    string command;

    do
    {
        cout << endl << "Type a command: ";
        cin >> command;
        cout << endl;
        if (command == "list")
        {
            displayListOfPerformers();
        }

        else if (command == "add")
        {

            _data.writeData();

            //Performer newPerformer(name, gender, bYear, dYear);

            // TODO:
            //_service.addPerformer(newPerformer);
        }

        else if (command == "search")
        {

            string input;
            cout << "Enter name to search for: ";
            cin.ignore();
            getline(cin, input);

            vector <Performer> newVector = _service.search(input);
            for(size_t i = 0; i < newVector.size(); i++)
            {
            cout << "Found:" << endl;
            cout << "----------" << endl;
            cout << "Name: " << newVector[i].getName() << endl;
            cout << "Gender: " << newVector[i].getGender() << endl;
            cout << "Birth year: " << newVector[i].getbYear() << endl;
            cout << "Death year: " << newVector[i].getdYear() << endl;
            cout << endl;
            }

            if(newVector.size() == 0)
            {
                cout << "Nothing was found!";
            }
        }

        else if (command == "delete")
        {
            cout << "Entry removed" << endl;
        }

        else if (command == "help")
        {
            cout << "list   - This will list all computer scientists in the system" << endl;
            cout << "add    - This will add a new computer scientist" << endl;
            cout << "delete - Removes an entry" << endl;
            cout << "update - Updates an entry" << endl;
            cout << "search - Searches for a given computer scientist" << endl;
            cout << "help   - Displays list of commands" << endl;
            cout << "exit   - This will close the application" << endl;
        }

        else if (command == "exit")
        {
            cout << "exiting" << endl;
        }

        else if(command == "data")
        {
            /*
            vector<string> logs = _data.readData();

            string choose;
            cin >> choose;
            if(choose == "name")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "gender")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+1] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "birth")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+2] << endl;
                    i =  i + 3;
                }
            }
            else if(choose == "death")
            {
                for(size_t i = 0; i < logs.size(); i++)
                {
                    cout << logs[i+3] << endl;
                    i =  i + 3;
                }
            }
            */

        }

        else
        {
            cout << "invalid command." << endl;
            cout << "type 'help' to see list of commands" << endl;
        }

    }while (command != "exit");
}

void ConsoleUI::displayListOfPerformers()
{
    //vector<Performer> performers = _service.getPerformers();
    //cout << "name" << endl;
    //cout << "===============" << endl;
    cout << "Nr" << "\t" << "Name" << "\t\t" << "Gender";
    cout << "\t\t" << "Birth year" << "\t\t" << "Deceased" << endl;
    for (int i = 0; i < 41*2; ++i)
    {
        cout << "=";
    }
    cout << endl;
    /*
    vector<string> logs = _data.readData();

    for (size_t i = 0; i < 1; i++)
    {
        int counter = 1;
        for(size_t j = 0; j < logs.size(); j++)
        {
            cout << counter << "\t" << logs[j] << "\t\t" << logs[j+1] << "\t" << logs[j+2] << "\t\t" << logs[j+3];
            j =  j + 3;
            counter++;
        }
    }
    */

    /*
    for (size_t i = 0; i< performers.size(); ++i)
    {
        cout << i+1 << "\t" << performers[i].getName()
             << "\t"  << performers[i].getGender() << "\t" << "\t"
             << performers[i].getbYear() << "\t\t\t" << performers[i].getdYear()
             << endl;
    }
    */
}

<|endoftext|>