// -*- C++ -*-

// Copyright (C) 2007, 2008, 2009, 2010 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 */
