// -*- C++ -*-

// Copyright (C) 2007-2014 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library.  This library is free
// software; you can redistribute it and/or modify it under the terms
// of the GNU General Public License as published by the Free Software
// Foundation; either version 3, or (at your option) any later
// version.

// This library is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
// General Public License for more details.

// Under Section 7 of GPL version 3, you are granted additional
// permissions described in the GCC Runtime Library Exception, version
// 3.1, as published by the Free Software Foundation.

// You should have received a copy of the GNU General Public License and
// a copy of the GCC Runtime Library Exception along with this program;
// see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
// <http://www.gnu.org/licenses/>.

/** @file parallel/quicksort.h
 *  @brief Implementation of a unbalanced parallel quicksort (in-place).
 *  This file is a GNU parallel extension to the Standard C++ Library.
 */

// Written by Johannes Singler.

#ifndef _GLIBCXX_PARALLEL_QUICKSORT_H
#define _GLIBCXX_PARALLEL_QUICKSORT_H 1

#include <parallel/parallel.h>
#include <parallel/partition.h>

namespace __gnu_parallel
{
  /** @brief Unbalanced quicksort divide step.
   *  @param __begin Begin iterator of subsequence.
   *  @param __end End iterator of subsequence.
   *  @param __comp Comparator.
   *  @param __pivot_rank Desired __rank of the pivot.
   *  @param __num_samples Choose pivot from that many samples.
   *  @param __num_threads Number of threads that are allowed to work on
   *  this part.
   */
  template<typename _RAIter, typename _Compare>
    typename std::iterator_traits<_RAIter>::difference_type
    __parallel_sort_qs_divide(_RAIter __begin, _RAIter __end,
			      _Compare __comp, typename std::iterator_traits
			      <_RAIter>::difference_type __pivot_rank,
			      typename std::iterator_traits
			      <_RAIter>::difference_type
			      __num_samples, _ThreadIndex __num_threads)
    {
      typedef std::iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;

      _DifferenceType __n = __end - __begin;
      __num_samples = std::min(__num_samples, __n);

      // Allocate uninitialized, to avoid default constructor.
      _ValueType* __samples = static_cast<_ValueType*>
	(::operator new(__num_samples * sizeof(_ValueType)));

      for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
        {
          const unsigned long long __index = static_cast<unsigned long long>
	    (__s) * __n / __num_samples;
          ::new(&(__samples[__s])) _ValueType(__begin[__index]);
        }

      __gnu_sequential::sort(__samples, __samples + __num_samples, __comp);

      _ValueType& __pivot = __samples[__pivot_rank * __num_samples / __n];

      __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool>
        __pred(__comp, __pivot);
      _DifferenceType __split = __parallel_partition(__begin, __end,
						     __pred, __num_threads);

      for (_DifferenceType __s = 0; __s < __num_samples; ++__s)
	__samples[__s].~_ValueType();
      ::operator delete(__samples);

      return __split;
    }

  /** @brief Unbalanced quicksort conquer step.
   *  @param __begin Begin iterator of subsequence.
   *  @param __end End iterator of subsequence.
   *  @param __comp Comparator.
   *  @param __num_threads Number of threads that are allowed to work on
   *  this part.
   */
  template<typename _RAIter, typename _Compare>
    void
    __parallel_sort_qs_conquer(_RAIter __begin, _RAIter __end,
			       _Compare __comp,
			       _ThreadIndex __num_threads)
    {
      typedef std::iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;

      if (__num_threads <= 1)
        {
          __gnu_sequential::sort(__begin, __end, __comp);
          return;
        }

      _DifferenceType __n = __end - __begin, __pivot_rank;

      if (__n <= 1)
        return;

      _ThreadIndex __num_threads_left;

      if ((__num_threads % 2) == 1)
        __num_threads_left = __num_threads / 2 + 1;
      else
        __num_threads_left = __num_threads / 2;

      __pivot_rank = __n * __num_threads_left / __num_threads;

      _DifferenceType __split = __parallel_sort_qs_divide
	(__begin, __end, __comp, __pivot_rank,
	 _Settings::get().sort_qs_num_samples_preset, __num_threads);

#pragma omp parallel sections num_threads(2)
      {
#pragma omp section
        __parallel_sort_qs_conquer(__begin, __begin + __split,
				   __comp, __num_threads_left);
#pragma omp section
        __parallel_sort_qs_conquer(__begin + __split, __end,
				   __comp, __num_threads - __num_threads_left);
      }
    }


  /** @brief Unbalanced quicksort main call.
   *  @param __begin Begin iterator of input sequence.
   *  @param __end End iterator input sequence, ignored.
   *  @param __comp Comparator.
   *  @param __num_threads Number of threads that are allowed to work on
   *  this part.
   */
  template<typename _RAIter, typename _Compare>
    void
    __parallel_sort_qs(_RAIter __begin, _RAIter __end,
		       _Compare __comp,
		       _ThreadIndex __num_threads)
    {
      _GLIBCXX_CALL(__n)

      typedef std::iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;

      _DifferenceType __n = __end - __begin;

      // At least one element per processor.
      if (__num_threads > __n)
        __num_threads = static_cast<_ThreadIndex>(__n);

      __parallel_sort_qs_conquer(
        __begin, __begin + __n, __comp, __num_threads);
    }

} //namespace __gnu_parallel

#endif /* _GLIBCXX_PARALLEL_QUICKSORT_H */
