Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #ifndef _GLIBCXX_PARALLEL_SEARCH_H
00034 #define _GLIBCXX_PARALLEL_SEARCH_H 1
00035
00036 #include <bits/stl_algobase.h>
00037
00038 #include <parallel/parallel.h>
00039 #include <parallel/equally_split.h>
00040
00041 namespace __gnu_parallel
00042 {
00043
00044
00045
00046
00047
00048
00049 template<typename _RAIter, typename _DifferenceTp>
00050 void
00051 __calc_borders(_RAIter __elements, _DifferenceTp __length,
00052 _DifferenceTp* __off)
00053 {
00054 typedef _DifferenceTp _DifferenceType;
00055
00056 __off[0] = -1;
00057 if (__length > 1)
00058 __off[1] = 0;
00059 _DifferenceType __k = 0;
00060 for (_DifferenceType __j = 2; __j <= __length; __j++)
00061 {
00062 while ((__k >= 0) && !(__elements[__k] == __elements[__j-1]))
00063 __k = __off[__k];
00064 __off[__j] = ++__k;
00065 }
00066 }
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 template<typename __RAIter1,
00078 typename __RAIter2,
00079 typename _Pred>
00080 __RAIter1
00081 __search_template(__RAIter1 __begin1, __RAIter1 __end1,
00082 __RAIter2 __begin2, __RAIter2 __end2,
00083 _Pred __pred)
00084 {
00085 typedef std::iterator_traits<__RAIter1> _TraitsType;
00086 typedef typename _TraitsType::difference_type _DifferenceType;
00087
00088 _GLIBCXX_CALL((__end1 - __begin1) + (__end2 - __begin2));
00089
00090 _DifferenceType __pattern_length = __end2 - __begin2;
00091
00092
00093 if(__pattern_length <= 0)
00094 return __end1;
00095
00096
00097 _DifferenceType __input_length = (__end1 - __begin1) - __pattern_length;
00098
00099
00100 _DifferenceType __result = (__end1 - __begin1);
00101 _DifferenceType *__splitters;
00102
00103
00104 if (__input_length < 0)
00105 return __end1;
00106
00107 omp_lock_t __result_lock;
00108 omp_init_lock(&__result_lock);
00109
00110 _ThreadIndex __num_threads = std::max<_DifferenceType>
00111 (1, std::min<_DifferenceType>(__input_length,
00112 __get_max_threads()));
00113
00114 _DifferenceType __advances[__pattern_length];
00115 __calc_borders(__begin2, __pattern_length, __advances);
00116
00117 # pragma omp parallel num_threads(__num_threads)
00118 {
00119 # pragma omp single
00120 {
00121 __num_threads = omp_get_num_threads();
00122 __splitters = new _DifferenceType[__num_threads + 1];
00123 equally_split(__input_length, __num_threads, __splitters);
00124 }
00125
00126 _ThreadIndex __iam = omp_get_thread_num();
00127
00128 _DifferenceType __start = __splitters[__iam],
00129 __stop = __splitters[__iam + 1];
00130
00131 _DifferenceType __pos_in_pattern = 0;
00132 bool __found_pattern = false;
00133
00134 while (__start <= __stop && !__found_pattern)
00135 {
00136
00137 #pragma omp flush(__result)
00138
00139 if (__result < __start)
00140 break;
00141 while (__pred(__begin1[__start + __pos_in_pattern],
00142 __begin2[__pos_in_pattern]))
00143 {
00144 ++__pos_in_pattern;
00145 if (__pos_in_pattern == __pattern_length)
00146 {
00147
00148 omp_set_lock(&__result_lock);
00149 __result = std::min(__result, __start);
00150 omp_unset_lock(&__result_lock);
00151
00152 __found_pattern = true;
00153 break;
00154 }
00155 }
00156
00157 __start += (__pos_in_pattern - __advances[__pos_in_pattern]);
00158 __pos_in_pattern = (__advances[__pos_in_pattern] < 0
00159 ? 0 : __advances[__pos_in_pattern]);
00160 }
00161 }
00162
00163 omp_destroy_lock(&__result_lock);
00164
00165 delete[] __splitters;
00166
00167
00168 return (__begin1 + __result);
00169 }
00170 }
00171
00172 #endif