// -*- 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/set_operations.h
 * @brief Parallel implementations of set operations for random-access
 * iterators.
 *  This file is a GNU parallel extension to the Standard C++ Library.
 */

// Written by Marius Elvert and Felix Bondarenko.

#ifndef _GLIBCXX_PARALLEL_SET_OPERATIONS_H
#define _GLIBCXX_PARALLEL_SET_OPERATIONS_H 1

#include <omp.h>

#include <parallel/settings.h>
#include <parallel/multiseq_selection.h>

namespace __gnu_parallel
{
  template<typename _IIter, typename _OutputIterator>
    _OutputIterator
    __copy_tail(std::pair<_IIter, _IIter> __b,
		std::pair<_IIter, _IIter> __e, _OutputIterator __r)
    {
      if (__b.first != __e.first)
	{
          do
            {
              *__r++ = *__b.first++;
            }
          while (__b.first != __e.first);
	}
      else
	{
          while (__b.second != __e.second)
            *__r++ = *__b.second++;
	}
      return __r;
    }

  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    struct __symmetric_difference_func
    {
      typedef std::iterator_traits<_IIter> _TraitsType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef typename std::pair<_IIter, _IIter> _IteratorPair;

      __symmetric_difference_func(_Compare __comp) : _M_comp(__comp) {}

      _Compare _M_comp;

      _OutputIterator
      _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d,
		_OutputIterator __r) const
      {
	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              {
        	*__r = *__a;
        	++__a;
        	++__r;
              }
            else if (_M_comp(*__c, *__a))
              {
        	*__r = *__c;
        	++__c;
        	++__r;
              }
            else
              {
        	++__a;
        	++__c;
              }
          }
	return std::copy(__c, __d, std::copy(__a, __b, __r));
      }

      _DifferenceType
      __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const
      {
	_DifferenceType __counter = 0;

	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              {
        	++__a;
        	++__counter;
              }
            else if (_M_comp(*__c, *__a))
              {
        	++__c;
        	++__counter;
              }
            else
              {
        	++__a;
        	++__c;
              }
          }

	return __counter + (__b - __a) + (__d - __c);
      }

      _OutputIterator
      __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const
      { return std::copy(__c, __d, __out); }

      _OutputIterator
      __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
      { return std::copy(__a, __b, __out); }
    };


  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    struct __difference_func
    {
      typedef std::iterator_traits<_IIter> _TraitsType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef typename std::pair<_IIter, _IIter> _IteratorPair;

      __difference_func(_Compare __comp) : _M_comp(__comp) {}

      _Compare _M_comp;

      _OutputIterator
      _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d,
		_OutputIterator __r) const
      {
	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              {
        	*__r = *__a;
        	++__a;
        	++__r;
              }
            else if (_M_comp(*__c, *__a))
              { ++__c; }
            else
              {
        	++__a;
        	++__c;
              }
          }
	return std::copy(__a, __b, __r);
      }

      _DifferenceType
      __count(_IIter __a, _IIter __b,
	      _IIter __c, _IIter __d) const
      {
	_DifferenceType __counter = 0;

	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              {
        	++__a;
        	++__counter;
              }
            else if (_M_comp(*__c, *__a))
              { ++__c; }
            else
              { ++__a; ++__c; }
          }

	return __counter + (__b - __a);
      }

      _OutputIterator
      __first_empty(_IIter, _IIter, _OutputIterator __out) const
      { return __out; }

      _OutputIterator
      __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
      { return std::copy(__a, __b, __out); }
    };


  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    struct __intersection_func
    {
      typedef std::iterator_traits<_IIter> _TraitsType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef typename std::pair<_IIter, _IIter> _IteratorPair;

      __intersection_func(_Compare __comp) : _M_comp(__comp) {}

      _Compare _M_comp;

      _OutputIterator
      _M_invoke(_IIter __a, _IIter __b, _IIter __c, _IIter __d,
		_OutputIterator __r) const
      {
	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              { ++__a; }
            else if (_M_comp(*__c, *__a))
              { ++__c; }
            else
              {
        	*__r = *__a;
        	++__a;
        	++__c;
        	++__r;
              }
          }

	return __r;
      }

      _DifferenceType
      __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const
      {
	_DifferenceType __counter = 0;

	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              { ++__a; }
            else if (_M_comp(*__c, *__a))
              { ++__c; }
            else
              {
        	++__a;
        	++__c;
        	++__counter;
              }
          }

	return __counter;
      }

      _OutputIterator
      __first_empty(_IIter, _IIter, _OutputIterator __out) const
      { return __out; }

      _OutputIterator
      __second_empty(_IIter, _IIter, _OutputIterator __out) const
      { return __out; }
    };

  template<class _IIter, class _OutputIterator, class _Compare>
    struct __union_func
    {
      typedef typename std::iterator_traits<_IIter>::difference_type
      _DifferenceType;

      __union_func(_Compare __comp) : _M_comp(__comp) {}

      _Compare _M_comp;

      _OutputIterator
      _M_invoke(_IIter __a, const _IIter __b, _IIter __c,
		const _IIter __d, _OutputIterator __r) const
      {
	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              {
        	*__r = *__a;
        	++__a;
              }
            else if (_M_comp(*__c, *__a))
              {
        	*__r = *__c;
        	++__c;
              }
            else
              {
        	*__r = *__a;
        	++__a;
        	++__c;
              }
            ++__r;
          }
	return std::copy(__c, __d, std::copy(__a, __b, __r));
      }

      _DifferenceType
      __count(_IIter __a, _IIter __b, _IIter __c, _IIter __d) const
      {
	_DifferenceType __counter = 0;

	while (__a != __b && __c != __d)
          {
            if (_M_comp(*__a, *__c))
              { ++__a; }
            else if (_M_comp(*__c, *__a))
              { ++__c; }
            else
              {
        	++__a;
        	++__c;
              }
            ++__counter;
          }

	__counter += (__b - __a);
	__counter += (__d - __c);
	return __counter;
      }

      _OutputIterator
      __first_empty(_IIter __c, _IIter __d, _OutputIterator __out) const
      { return std::copy(__c, __d, __out); }

      _OutputIterator
      __second_empty(_IIter __a, _IIter __b, _OutputIterator __out) const
      { return std::copy(__a, __b, __out); }
    };

  template<typename _IIter,
           typename _OutputIterator,
           typename _Operation>
    _OutputIterator
    __parallel_set_operation(_IIter __begin1, _IIter __end1,
			     _IIter __begin2, _IIter __end2,
			     _OutputIterator __result, _Operation __op)
    {
      _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2))

      typedef std::iterator_traits<_IIter> _TraitsType;
      typedef typename _TraitsType::difference_type _DifferenceType;
      typedef typename std::pair<_IIter, _IIter> _IteratorPair;

      if (__begin1 == __end1)
	return __op.__first_empty(__begin2, __end2, __result);

      if (__begin2 == __end2)
	return __op.__second_empty(__begin1, __end1, __result);

      const _DifferenceType __size = (__end1 - __begin1) + (__end2 - __begin2);

      const _IteratorPair __sequence[2] = { std::make_pair(__begin1, __end1),
					    std::make_pair(__begin2, __end2) };
      _OutputIterator __return_value = __result;
      _DifferenceType *__borders;
      _IteratorPair *__block_begins;
      _DifferenceType* __lengths;

      _ThreadIndex __num_threads =
          std::min<_DifferenceType>(__get_max_threads(),
              std::min(__end1 - __begin1, __end2 - __begin2));

#     pragma omp parallel num_threads(__num_threads)
      {
#       pragma omp single
	{
	  __num_threads = omp_get_num_threads();

	  __borders = new _DifferenceType[__num_threads + 2];
	  __equally_split(__size, __num_threads + 1, __borders);
	  __block_begins = new _IteratorPair[__num_threads + 1];
	  // Very __start.
	  __block_begins[0] = std::make_pair(__begin1, __begin2);
	  __lengths = new _DifferenceType[__num_threads];
	} //single

	_ThreadIndex __iam = omp_get_thread_num();

	// _Result from multiseq_partition.
	_IIter __offset[2];
	const _DifferenceType __rank = __borders[__iam + 1];

	multiseq_partition(__sequence, __sequence + 2,
			   __rank, __offset, __op._M_comp);

	// allowed to read?
	// together
	// *(__offset[ 0 ] - 1) == *__offset[ 1 ]
	if (__offset[ 0 ] != __begin1 && __offset[1] != __end2
	    && !__op._M_comp(*(__offset[0] - 1), *__offset[1])
	    && !__op._M_comp(*__offset[1], *(__offset[0] - 1)))
	  {
	    // Avoid split between globally equal elements: move one to
	    // front in first sequence.
              --__offset[0];
	  }

	_IteratorPair __block_end = __block_begins[__iam + 1] =
	  _IteratorPair(__offset[0], __offset[1]);

	// Make sure all threads have their block_begin result written out.
#       pragma omp barrier

	_IteratorPair __block_begin = __block_begins[__iam];

	// Begin working for the first block, while the others except
	// the last start to count.
	if (__iam == 0)
	  {
	    // The first thread can copy already.
	    __lengths[ __iam ] =
	      __op._M_invoke(__block_begin.first, __block_end.first,
			     __block_begin.second, __block_end.second,
			     __result) - __result;
	  }
	else
	  {
	    __lengths[ __iam ] =
	      __op.__count(__block_begin.first, __block_end.first,
			   __block_begin.second, __block_end.second);
	  }

	// Make sure everyone wrote their lengths.
#       pragma omp barrier

	_OutputIterator __r = __result;

	if (__iam == 0)
	  {
	    // Do the last block.
	    for (_ThreadIndex __i = 0; __i < __num_threads; ++__i)
	      __r += __lengths[__i];

	    __block_begin = __block_begins[__num_threads];

	    // Return the result iterator of the last block.
	    __return_value =
	      __op._M_invoke(__block_begin.first, __end1,
			     __block_begin.second, __end2, __r);

	  }
          else
            {
              for (_ThreadIndex __i = 0; __i < __iam; ++__i)
        	__r += __lengths[ __i ];

              // Reset begins for copy pass.
              __op._M_invoke(__block_begin.first, __block_end.first,
			     __block_begin.second, __block_end.second, __r);
            }
	}
      return __return_value;
    }

  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    inline _OutputIterator
    __parallel_set_union(_IIter __begin1, _IIter __end1,
			 _IIter __begin2, _IIter __end2,
			 _OutputIterator __result, _Compare __comp)
    {
      return __parallel_set_operation(__begin1, __end1, __begin2, __end2,
				      __result,
				      __union_func< _IIter, _OutputIterator,
				      _Compare>(__comp));
    }

  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    inline _OutputIterator
    __parallel_set_intersection(_IIter __begin1, _IIter __end1,
                        	_IIter __begin2, _IIter __end2,
                        	_OutputIterator __result, _Compare __comp)
    {
      return __parallel_set_operation(__begin1, __end1, __begin2, __end2,
				      __result,
				      __intersection_func<_IIter,
				      _OutputIterator, _Compare>(__comp));
    }

  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    inline _OutputIterator
    __parallel_set_difference(_IIter __begin1, _IIter __end1,
                              _IIter __begin2, _IIter __end2,
                              _OutputIterator __result, _Compare __comp)
    {
      return __parallel_set_operation(__begin1, __end1, __begin2, __end2,
				      __result,
				      __difference_func<_IIter,
				      _OutputIterator, _Compare>(__comp));
    }

  template<typename _IIter,
           typename _OutputIterator,
           typename _Compare>
    inline _OutputIterator
    __parallel_set_symmetric_difference(_IIter __begin1, _IIter __end1,
                                	_IIter __begin2, _IIter __end2,
                                	_OutputIterator __result,
                                	_Compare __comp)
    {
      return __parallel_set_operation(__begin1, __end1, __begin2, __end2,
				      __result,
				      __symmetric_difference_func<_IIter,
				      _OutputIterator, _Compare>(__comp));
    }
}

#endif /* _GLIBCXX_PARALLEL_SET_OPERATIONS_H */
