ShellBanner
System:Linux MiraNet 3.0.0-14-generic-pae #23-Ubuntu SMP Mon Nov 21 22:07:10 UTC 2011 i686
Software:Apache. PHP/5.3.6-13ubuntu3.10
ID:uid=65534(nobody) gid=65534(nogroup) groups=65534(nogroup)
Safe Mode:OFF
Open_Basedir:OFF
Freespace:25.65 GB of 70.42 GB (36.42%)
MySQL: ON MSSQL: OFF Oracle: OFF PostgreSQL: OFF Curl: OFF Sockets: ON Fetch: OFF Wget: ON Perl: ON
Disabled Functions: pcntl_alarm,pcntl_fork,pcntl_waitpid,pcntl_wait,pcntl_wifexited,pcntl_wifstopped,pcntl_wifsignaled,pcntl_wexitstatus,pcntl_wtermsig,pcntl_wstopsig,pcntl_signal,pcntl_signal_dispatch,pcntl_get_last_error,pcntl_strerror,pcntl_sigprocmask,pcntl_sigwaitinfo,pcntl_sigtimedwait,pcntl_exec,pcntl_getpriority,pcntl_setpriority,

/ usr/ include/ c++/ 4.6/ parallel/ - drwxr-xr-x

Directory:
Viewing file:     partition.h (14.6 KB)      -rw-r--r--
Select action/file-type:
(+) | (+) | (+) | Code (+) | Session (+) | (+) | SDB (+) | (+) | (+) | (+) | (+) | (+) |
// -*- 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/partition.h
 *  @brief Parallel implementation of std::partition(),
 *  std::nth_element(), and std::partial_sort().
 *  This file is a GNU parallel extension to the Standard C++ Library.
 */

// Written by Johannes Singler and Felix Putze.

#ifndef _GLIBCXX_PARALLEL_PARTITION_H
#define _GLIBCXX_PARALLEL_PARTITION_H 1

#include <parallel/basic_iterator.h>
#include <parallel/sort.h>
#include <parallel/random_number.h>
#include <bits/stl_algo.h>
#include <parallel/parallel.h>

/** @brief Decide whether to declare certain variables volatile. */
#define _GLIBCXX_VOLATILE volatile

namespace __gnu_parallel
{
  /** @brief Parallel implementation of std::partition.
    *  @param __begin Begin iterator of input sequence to split.
    *  @param __end End iterator of input sequence to split.
    *  @param __pred Partition predicate, possibly including some kind
    *         of pivot.
    *  @param __num_threads Maximum number of threads to use for this task.
    *  @return Number of elements not fulfilling the predicate. */
  template<typename _RAIter, typename _Predicate>
    typename std::iterator_traits<_RAIter>::difference_type
    __parallel_partition(_RAIter __begin, _RAIter __end,
             _Predicate __pred, _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;

      _GLIBCXX_CALL(__n)

      const _Settings& __s = _Settings::get();

      // shared
      _GLIBCXX_VOLATILE _DifferenceType __left = 0, __right = __n - 1,
                                        __dist = __n,
                                        __leftover_left, __leftover_right,
                                        __leftnew, __rightnew;

      // just 0 or 1, but int to allow atomic operations
      int* __reserved_left = 0, * __reserved_right = 0;

      _DifferenceType __chunk_size = __s.partition_chunk_size;

      //at least two chunks per thread
      if (__dist >= 2 * __num_threads * __chunk_size)
#       pragma omp parallel num_threads(__num_threads)
    {
#         pragma omp single
      {
        __num_threads = omp_get_num_threads();
        __reserved_left = new int[__num_threads];
        __reserved_right = new int[__num_threads];

        if (__s.partition_chunk_share > 0.0)
          __chunk_size = std::max<_DifferenceType>
        (__s.partition_chunk_size, (double)__n 
         * __s.partition_chunk_share / (double)__num_threads);
        else
          __chunk_size = __s.partition_chunk_size;
      }

      while (__dist >= 2 * __num_threads * __chunk_size)
        {
#             pragma omp single
          {
        _DifferenceType __num_chunks = __dist / __chunk_size;

        for (_ThreadIndex __r = 0; __r < __num_threads; ++__r)
          {
            __reserved_left [__r] = 0; // false
            __reserved_right[__r] = 0; // false
          }
        __leftover_left = 0;
        __leftover_right = 0;
          } //implicit barrier

          // Private.
          _DifferenceType __thread_left, __thread_left_border,
                      __thread_right, __thread_right_border;

          __thread_left = __left + 1;
          // Just to satisfy the condition below.
          __thread_left_border = __thread_left - 1;

          __thread_right = __n - 1;
             // Just to satisfy the condition below.
          __thread_right_border = __thread_right + 1;

          bool __iam_finished = false;
          while (!__iam_finished)
        {
          if (__thread_left > __thread_left_border)
            {
                      _DifferenceType __former_dist =
                              __fetch_and_add(&__dist, -__chunk_size);
                      if (__former_dist < __chunk_size)
                        {
                          __fetch_and_add(&__dist, __chunk_size);
                          __iam_finished = true;
                          break;
                        }
                      else
                        {
                          __thread_left =
                                  __fetch_and_add(&__left, __chunk_size);
                          __thread_left_border =
                                  __thread_left + (__chunk_size - 1);
                        }
            }

          if (__thread_right < __thread_right_border)
            {
                      _DifferenceType __former_dist =
                              __fetch_and_add(&__dist, -__chunk_size);
                      if (__former_dist < __chunk_size)
                        {
                          __fetch_and_add(&__dist, __chunk_size);
                          __iam_finished = true;
                          break;
                        }
                      else
                        {
                          __thread_right =
                                  __fetch_and_add(&__right, -__chunk_size);
                          __thread_right_border =
                                  __thread_right - (__chunk_size - 1);
                        }
            }

          // Swap as usual.
          while (__thread_left < __thread_right)
            {
              while (__pred(__begin[__thread_left])
                 && __thread_left <= __thread_left_border)
            ++__thread_left;
              while (!__pred(__begin[__thread_right])
                 && __thread_right >= __thread_right_border)
            --__thread_right;

              if (__thread_left > __thread_left_border
              || __thread_right < __thread_right_border)
            // Fetch new chunk(__s).
            break;

              std::iter_swap(__begin + __thread_left,
                             __begin + __thread_right);
              ++__thread_left;
              --__thread_right;
            }
        }

          // Now swap the leftover chunks to the right places.
          if (__thread_left <= __thread_left_border)
#               pragma omp atomic
        ++__leftover_left;
          if (__thread_right >= __thread_right_border)
#               pragma omp atomic
        ++__leftover_right;

#             pragma omp barrier

              _DifferenceType
                    __leftold = __left,
                    __leftnew = __left - __leftover_left * __chunk_size,
                    __rightold = __right,
                    __rightnew = __right + __leftover_right * __chunk_size;

          // <=> __thread_left_border + (__chunk_size - 1) >= __leftnew
          if (__thread_left <= __thread_left_border
          && __thread_left_border >= __leftnew)
        {
          // Chunk already in place, reserve spot.
        __reserved_left[(__left - (__thread_left_border + 1))
                / __chunk_size] = 1;
        }

          // <=> __thread_right_border - (__chunk_size - 1) <= __rightnew
          if (__thread_right >= __thread_right_border
          && __thread_right_border <= __rightnew)
        {
          // Chunk already in place, reserve spot.
          __reserved_right[((__thread_right_border - 1) - __right)
                   / __chunk_size] = 1;
        }

#             pragma omp barrier

          if (__thread_left <= __thread_left_border
          && __thread_left_border < __leftnew)
        {
          // Find spot and swap.
          _DifferenceType __swapstart = -1;
                  for (int __r = 0; __r < __leftover_left; ++__r)
                    if (__reserved_left[__r] == 0
                        && __compare_and_swap(&(__reserved_left[__r]), 0, 1))
                      {
                        __swapstart = __leftold - (__r + 1) * __chunk_size;
                        break;
                      }

#if _GLIBCXX_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif

          std::swap_ranges(__begin + __thread_left_border
                   - (__chunk_size - 1),
                   __begin + __thread_left_border + 1,
                   __begin + __swapstart);
        }

          if (__thread_right >= __thread_right_border
          && __thread_right_border > __rightnew)
        {
          // Find spot and swap
          _DifferenceType __swapstart = -1;
                  for (int __r = 0; __r < __leftover_right; ++__r)
                    if (__reserved_right[__r] == 0
                        && __compare_and_swap(&(__reserved_right[__r]), 0, 1))
                      {
                        __swapstart = __rightold + __r * __chunk_size + 1;
                        break;
                      }

#if _GLIBCXX_ASSERTIONS
          _GLIBCXX_PARALLEL_ASSERT(__swapstart != -1);
#endif

          std::swap_ranges(__begin + __thread_right_border,
                   __begin + __thread_right_border
                   + __chunk_size, __begin + __swapstart);
          }
#if _GLIBCXX_ASSERTIONS
#             pragma omp barrier

#             pragma omp single
          {
        for (_DifferenceType __r = 0; __r < __leftover_left; ++__r)
          _GLIBCXX_PARALLEL_ASSERT(__reserved_left[__r] == 1);
        for (_DifferenceType __r = 0; __r < __leftover_right; ++__r)
          _GLIBCXX_PARALLEL_ASSERT(__reserved_right[__r] == 1);
          }
#endif

          __left = __leftnew;
          __right = __rightnew;
              __dist = __right - __left + 1;
        }

#           pragma omp flush(__left, __right)
    } // end "recursion" //parallel

        _DifferenceType __final_left = __left, __final_right = __right;

    while (__final_left < __final_right)
      {
        // Go right until key is geq than pivot.
        while (__pred(__begin[__final_left])
           && __final_left < __final_right)
          ++__final_left;

        // Go left until key is less than pivot.
        while (!__pred(__begin[__final_right])
           && __final_left < __final_right)
          --__final_right;

        if (__final_left == __final_right)
          break;
        std::iter_swap(__begin + __final_left, __begin + __final_right);
        ++__final_left;
        --__final_right;
      }

    // All elements on the left side are < piv, all elements on the
    // right are >= piv
    delete[] __reserved_left;
    delete[] __reserved_right;

    // Element "between" __final_left and __final_right might not have
    // been regarded yet
    if (__final_left < __n && !__pred(__begin[__final_left]))
      // Really swapped.
      return __final_left;
    else
      return __final_left + 1;
    }

  /**
    *  @brief Parallel implementation of std::nth_element().
    *  @param __begin Begin iterator of input sequence.
    *  @param __nth _Iterator of element that must be in position afterwards.
    *  @param __end End iterator of input sequence.
    *  @param __comp Comparator.
    */
  template<typename _RAIter, typename _Compare>
    void 
    __parallel_nth_element(_RAIter __begin, _RAIter __nth, 
               _RAIter __end, _Compare __comp)
    {
      typedef std::iterator_traits<_RAIter> _TraitsType;
      typedef typename _TraitsType::value_type _ValueType;
      typedef typename _TraitsType::difference_type _DifferenceType;

      _GLIBCXX_CALL(__end - __begin)

      _RAIter __split;
      _RandomNumber __rng;

      const _Settings& __s = _Settings::get();
      _DifferenceType __minimum_length = std::max<_DifferenceType>(2,
        std::max(__s.nth_element_minimal_n, __s.partition_minimal_n));

      // Break if input range to small.
      while (static_cast<_SequenceIndex>(__end - __begin) >= __minimum_length)
    {
          _DifferenceType __n = __end - __begin;

          _RAIter __pivot_pos = __begin + __rng(__n);

          // Swap __pivot_pos value to end.
          if (__pivot_pos != (__end - 1))
            std::iter_swap(__pivot_pos, __end - 1);
          __pivot_pos = __end - 1;

          // _Compare must have first_value_type, second_value_type,
          // result_type
          // _Compare ==
          // __gnu_parallel::_Lexicographic<S, int,
      //                                __gnu_parallel::_Less<S, S> >
          // __pivot_pos == std::pair<S, int>*
          __gnu_parallel::__binder2nd<_Compare, _ValueType, _ValueType, bool>
            __pred(__comp, *__pivot_pos);

          // Divide, leave pivot unchanged in last place.
          _RAIter __split_pos1, __split_pos2;
          __split_pos1 = __begin + __parallel_partition(__begin, __end - 1,
                            __pred,
                            __get_max_threads());

          // Left side: < __pivot_pos; __right side: >= __pivot_pos

          // Swap pivot back to middle.
          if (__split_pos1 != __pivot_pos)
            std::iter_swap(__split_pos1, __pivot_pos);
          __pivot_pos = __split_pos1;

          // In case all elements are equal, __split_pos1 == 0
          if ((__split_pos1 + 1 - __begin) < (__n >> 7)
              || (__end - __split_pos1) < (__n >> 7))
            {
              // Very unequal split, one part smaller than one 128th
              // elements not strictly larger than the pivot.
              __gnu_parallel::__unary_negate<__gnu_parallel::
            __binder1st<_Compare, _ValueType,
                    _ValueType, bool>, _ValueType>
            __pred(__gnu_parallel::__binder1st<_Compare, _ValueType,
               _ValueType, bool>(__comp, *__pivot_pos));

              // Find other end of pivot-equal range.
              __split_pos2 = __gnu_sequential::partition(__split_pos1 + 1,
                             __end, __pred);
            }
          else
            // Only skip the pivot.
            __split_pos2 = __split_pos1 + 1;

          // Compare iterators.
          if (__split_pos2 <= __nth)
            __begin = __split_pos2;
          else if (__nth < __split_pos1)
            __end = __split_pos1;
          else
            break;
    }

      // Only at most _Settings::partition_minimal_n __elements __left.
      __gnu_sequential::nth_element(__begin, __nth, __end, __comp);
    }

  /** @brief Parallel implementation of std::partial_sort().
  *  @param __begin Begin iterator of input sequence.
  *  @param __middle Sort until this position.
  *  @param __end End iterator of input sequence.
  *  @param __comp Comparator. */
  template<typename _RAIter, typename _Compare>
    void
    __parallel_partial_sort(_RAIter __begin,
                _RAIter __middle,
                _RAIter __end, _Compare __comp)
    {
      __parallel_nth_element(__begin, __middle, __end, __comp);
      std::sort(__begin, __middle, __comp);
    }

} //namespace __gnu_parallel

#undef _GLIBCXX_VOLATILE

#endif /* _GLIBCXX_PARALLEL_PARTITION_H */
Command:
Quick Commands:
Upload:
[Read-Only] Max size: 100MB
PHP Filesystem: <@ Ú
Search File:
regexp
Create File:
Overwrite [Read-Only]
View File:
Mass Defacement:
[+] Main Directory: [+] Defacement Url:
LmfaoX Shell - Private Build [BETA] - v0.1 -; Generated: 0.1689 seconds