qtconcurrentfilterkernel.h
上传用户:detong
上传日期:2022-06-22
资源大小:20675k
文件大小:11k
源码类别:

系统编程

开发平台:

Unix_Linux

  1. /****************************************************************************
  2. **
  3. ** Copyright (C) 2008 Nokia Corporation and/or its subsidiary(-ies).
  4. ** Contact: Qt Software Information (qt-info@nokia.com)
  5. **
  6. ** This file is part of the QtCore module of the Qt Toolkit.
  7. **
  8. ** Commercial Usage
  9. ** Licensees holding valid Qt Commercial licenses may use this file in
  10. ** accordance with the Qt Commercial License Agreement provided with the
  11. ** Software or, alternatively, in accordance with the terms contained in
  12. ** a written agreement between you and Nokia.
  13. **
  14. **
  15. ** GNU General Public License Usage
  16. ** Alternatively, this file may be used under the terms of the GNU
  17. ** General Public License versions 2.0 or 3.0 as published by the Free
  18. ** Software Foundation and appearing in the file LICENSE.GPL included in
  19. ** the packaging of this file.  Please review the following information
  20. ** to ensure GNU General Public Licensing requirements will be met:
  21. ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and
  22. ** http://www.gnu.org/copyleft/gpl.html.  In addition, as a special
  23. ** exception, Nokia gives you certain additional rights. These rights
  24. ** are described in the Nokia Qt GPL Exception version 1.3, included in
  25. ** the file GPL_EXCEPTION.txt in this package.
  26. **
  27. ** Qt for Windows(R) Licensees
  28. ** As a special exception, Nokia, as the sole copyright holder for Qt
  29. ** Designer, grants users of the Qt/Eclipse Integration plug-in the
  30. ** right for the Qt/Eclipse Integration to link to functionality
  31. ** provided by Qt Designer and its related libraries.
  32. **
  33. ** If you are unsure which license is appropriate for your use, please
  34. ** contact the sales department at qt-sales@nokia.com.
  35. **
  36. ****************************************************************************/
  37. #ifndef QTCONCURRENT_FILTERKERNEL_H
  38. #define QTCONCURRENT_FILTERKERNEL_H
  39. #include <QtCore/qglobal.h>
  40. #ifndef QT_NO_CONCURRENT
  41. #include <QtCore/qtconcurrentiteratekernel.h>
  42. #include <QtCore/qtconcurrentmapkernel.h>
  43. #include <QtCore/qtconcurrentreducekernel.h>
  44. QT_BEGIN_HEADER
  45. QT_BEGIN_NAMESPACE
  46. QT_MODULE(Core)
  47. #ifndef qdoc
  48. namespace QtConcurrent {
  49. template <typename T>
  50. struct qValueType
  51. {
  52.     typedef typename T::value_type value_type;
  53. };
  54. template <typename T>
  55. struct qValueType<const T*>
  56. {
  57.     typedef T value_type;
  58. };
  59. template <typename T>
  60. struct qValueType<T*>
  61. {
  62.     typedef T value_type;
  63. };
  64. // Implementation of filter
  65. template <typename Sequence, typename KeepFunctor, typename ReduceFunctor>
  66. class FilterKernel : public IterateKernel<typename Sequence::const_iterator, void>
  67. {
  68.     typedef ReduceKernel<ReduceFunctor, Sequence, typename Sequence::value_type> Reducer;
  69.     typedef IterateKernel<typename Sequence::const_iterator, void> IterateKernelType;
  70.     typedef typename ReduceFunctor::result_type T;
  71.     Sequence reducedResult;
  72.     Sequence &sequence;
  73.     KeepFunctor keep;
  74.     ReduceFunctor reduce;
  75.     Reducer reducer;
  76. public:
  77.     FilterKernel(Sequence &_sequence, KeepFunctor _keep, ReduceFunctor _reduce)
  78.         : IterateKernelType(const_cast<const Sequence &>(_sequence).begin(), const_cast<const Sequence &>(_sequence).end()), reducedResult(),
  79.           sequence(_sequence),
  80.           keep(_keep),
  81.           reduce(_reduce),
  82.           reducer(OrderedReduce)
  83.     { }
  84.     bool runIteration(typename Sequence::const_iterator it, int index, T *)
  85.     {
  86.         IntermediateResults<typename Sequence::value_type> results;
  87.         results.begin = index;
  88.         results.end = index + 1;
  89.             if (keep(*it))
  90.                 results.vector.append(*it);
  91.             reducer.runReduce(reduce, reducedResult, results);
  92.             return false;
  93.     }
  94.     bool runIterations(typename Sequence::const_iterator sequenceBeginIterator, int begin, int end, T *)
  95.     {
  96.         IntermediateResults<typename Sequence::value_type> results;
  97.         results.begin = begin;
  98.         results.end = end;
  99.         results.vector.reserve(end - begin);
  100.         typename Sequence::const_iterator it = sequenceBeginIterator;
  101.         advance(it, begin);
  102.         for (int i = begin; i < end; ++i) {
  103.             if (keep(*it))
  104.                 results.vector.append(*it);
  105.             advance(it, 1);
  106.         }
  107.         reducer.runReduce(reduce, reducedResult, results);
  108.         return false;
  109.     }
  110.     void finish()
  111.     {
  112.         reducer.finish(reduce, reducedResult);
  113.         sequence = reducedResult;
  114.     }
  115.     inline bool shouldThrottleThread()
  116.     {
  117.         return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
  118.     }
  119.     inline bool shouldStartThread()
  120.     {
  121.         return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
  122.     }
  123.     typedef void ReturnType;
  124.     typedef void ResultType;
  125. };
  126. // Implementation of filter-reduce
  127. template <typename ReducedResultType,
  128.           typename Iterator,
  129.           typename KeepFunctor,
  130.           typename ReduceFunctor,
  131.           typename Reducer = ReduceKernel<ReduceFunctor,
  132.                                           ReducedResultType,
  133.                                           typename qValueType<Iterator>::value_type> >
  134. class FilteredReducedKernel : public IterateKernel<Iterator, ReducedResultType>
  135. {
  136.     ReducedResultType reducedResult;
  137.     KeepFunctor keep;
  138.     ReduceFunctor reduce;
  139.     Reducer reducer;
  140.     typedef IterateKernel<Iterator, ReducedResultType> IterateKernelType;
  141. public:
  142.     FilteredReducedKernel(Iterator begin,
  143.                           Iterator end,
  144.                           KeepFunctor _keep,
  145.                           ReduceFunctor _reduce,
  146.                           ReduceOptions reduceOption)
  147.         : IterateKernelType(begin, end), reducedResult(), keep(_keep), reduce(_reduce), reducer(reduceOption)
  148.     { }
  149. #if 0
  150.     FilteredReducedKernel(ReducedResultType initialValue,
  151.                           KeepFunctor keep,
  152.                           ReduceFunctor reduce,
  153.                           ReduceOption reduceOption)
  154.         : reducedResult(initialValue), keep(keep), reduce(reduce), reducer(reduceOption)
  155.     { }
  156. #endif
  157.     bool runIteration(Iterator it, int index, ReducedResultType *)
  158.     {
  159.         IntermediateResults<typename qValueType<Iterator>::value_type> results;
  160.         results.begin = index;
  161.         results.end = index + 1;
  162.         if (keep(*it))
  163.             results.vector.append(*it);
  164.         reducer.runReduce(reduce, reducedResult, results);
  165.         return false;
  166.     }
  167.     bool runIterations(Iterator sequenceBeginIterator, int begin, int end, ReducedResultType *)
  168.     {
  169.         IntermediateResults<typename qValueType<Iterator>::value_type> results;
  170.         results.begin = begin;
  171.         results.end = end;
  172.         results.vector.reserve(end - begin);
  173.         Iterator it = sequenceBeginIterator;
  174.         advance(it, begin);
  175.         for (int i = begin; i < end; ++i) {
  176.             if (keep(*it))
  177.                 results.vector.append(*it);
  178.             advance(it, 1);
  179.         }
  180.         reducer.runReduce(reduce, reducedResult, results);
  181.         return false;
  182.     }
  183.     void finish()
  184.     {
  185.         reducer.finish(reduce, reducedResult);
  186.     }
  187.     inline bool shouldThrottleThread()
  188.     {
  189.         return IterateKernelType::shouldThrottleThread() || reducer.shouldThrottle();
  190.     }
  191.     inline bool shouldStartThread()
  192.     {
  193.         return IterateKernelType::shouldStartThread() && reducer.shouldStartThread();
  194.     }
  195.     typedef ReducedResultType ReturnType;
  196.     typedef ReducedResultType ResultType;
  197.     ReducedResultType *result()
  198.     {
  199.         return &reducedResult;
  200.     }
  201. };
  202. // Implementation of filter that reports individual results via QFutureInterface
  203. template <typename Iterator, typename KeepFunctor>
  204. class FilteredEachKernel : public IterateKernel<Iterator, typename qValueType<Iterator>::value_type>
  205. {
  206.     typedef typename qValueType<Iterator>::value_type T;
  207.     typedef IterateKernel<Iterator, T> IterateKernelType;
  208.     KeepFunctor keep;
  209. public:
  210.     typedef T ReturnType;
  211.     typedef T ResultType;
  212.     FilteredEachKernel(Iterator begin, Iterator end, KeepFunctor _keep)
  213.         : IterateKernelType(begin, end), keep(_keep)
  214.     { }
  215.     void start()
  216.     {
  217.         if (this->futureInterface)
  218.             this->futureInterface->setFilterMode(true);
  219.         IterateKernelType::start();
  220.     }
  221.     bool runIteration(Iterator it, int index, T *)
  222.     {
  223.         if (keep(*it))
  224.             this->reportResult(&(*it), index);
  225.         else
  226.             this->reportResult(0, index);
  227.         return false;
  228.     }
  229.     bool runIterations(Iterator sequenceBeginIterator, int begin, int end, T *)
  230.     {
  231.         const int count = end - begin;
  232.         IntermediateResults<typename qValueType<Iterator>::value_type> results;
  233.         results.begin = begin;
  234.         results.end = end;
  235.         results.vector.reserve(count);
  236.         Iterator it = sequenceBeginIterator;
  237.         advance(it, begin);
  238.         for (int i = begin; i < end; ++i) {
  239.             if (keep(*it))
  240.                 results.vector.append(*it);
  241.             advance(it, 1);
  242.         }
  243.         this->reportResults(results.vector, begin, count);
  244.         return false;
  245.     }
  246. };
  247. template <typename Iterator, typename KeepFunctor>
  248. inline
  249. ThreadEngineStarter<typename qValueType<Iterator>::value_type>
  250. startFiltered(Iterator begin, Iterator end, KeepFunctor functor)
  251. {
  252.     return startThreadEngine(new FilteredEachKernel<Iterator, KeepFunctor>(begin, end, functor));
  253. }
  254. template <typename Sequence, typename KeepFunctor>
  255. inline ThreadEngineStarter<typename Sequence::value_type>
  256. startFiltered(const Sequence &sequence, KeepFunctor functor)
  257. {
  258.     typedef SequenceHolder1<Sequence,
  259.                             FilteredEachKernel<typename Sequence::const_iterator, KeepFunctor>,
  260.                             KeepFunctor>
  261.         SequenceHolderType;
  262.         return startThreadEngine(new SequenceHolderType(sequence, functor));
  263. }
  264. template <typename ResultType, typename Sequence, typename MapFunctor, typename ReduceFunctor>
  265. inline ThreadEngineStarter<ResultType> startFilteredReduced(const Sequence & sequence,
  266.                                                            MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
  267.                                                            ReduceOptions options)
  268. {
  269.     typedef typename Sequence::const_iterator Iterator;
  270.     typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type > Reducer;
  271.     typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
  272.     typedef SequenceHolder2<Sequence, FilteredReduceType, MapFunctor, ReduceFunctor> SequenceHolderType;
  273.     return startThreadEngine(new SequenceHolderType(sequence, mapFunctor, reduceFunctor, options));
  274. }
  275. template <typename ResultType, typename Iterator, typename MapFunctor, typename ReduceFunctor>
  276. inline ThreadEngineStarter<ResultType> startFilteredReduced(Iterator begin, Iterator end,
  277.                                                            MapFunctor mapFunctor, ReduceFunctor reduceFunctor,
  278.                                                            ReduceOptions options)
  279. {
  280.     typedef ReduceKernel<ReduceFunctor, ResultType, typename qValueType<Iterator>::value_type> Reducer;
  281.     typedef FilteredReducedKernel<ResultType, Iterator, MapFunctor, ReduceFunctor, Reducer> FilteredReduceType;
  282.     return startThreadEngine(new FilteredReduceType(begin, end, mapFunctor, reduceFunctor, options));
  283. }
  284. } // namespace QtConcurrent
  285. #endif // qdoc
  286. QT_END_NAMESPACE
  287. QT_END_HEADER
  288. #endif // QT_NO_CONCURRENT
  289. #endif