- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files
- Directories
- Examples

- File List
- File Members

# qtconcurrentresultstore.h

Go to the documentation of this file.

    00001 /****************************************************************************
    00002 **
    00003 ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    00004 ** All rights reserved.
    00005 ** Contact: Nokia Corporation (qt-info@nokia.com)
    00006 **
    00007 ** This file is part of the QtCore module of the Qt Toolkit.
    00008 **
    00009 ** $QT_BEGIN_LICENSE:LGPL$
    00010 ** Commercial Usage
    00011 ** Licensees holding valid Qt Commercial licenses may use this file in
    00012 ** accordance with the Qt Commercial License Agreement provided with the
    00013 ** Software or, alternatively, in accordance with the terms contained in
    00014 ** a written agreement between you and Nokia.
    00015 **
    00016 ** GNU Lesser General Public License Usage
    00017 ** Alternatively, this file may be used under the terms of the GNU Lesser
    00018 ** General Public License version 2.1 as published by the Free Software
    00019 ** Foundation and appearing in the file LICENSE.LGPL included in the
    00020 ** packaging of this file.  Please review the following information to
    00021 ** ensure the GNU Lesser General Public License version 2.1 requirements
    00022 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    00023 **
    00024 ** In addition, as a special exception, Nokia gives you certain additional
    00025 ** rights.  These rights are described in the Nokia Qt LGPL Exception
    00026 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this module.
    00027 **
    00028 ** GNU General Public License Usage
    00029 ** Alternatively, this file may be used under the terms of the GNU
    00030 ** General Public License version 3.0 as published by the Free Software
    00031 ** Foundation and appearing in the file LICENSE.GPL included in the
    00032 ** packaging of this file.  Please review the following information to
    00033 ** ensure the GNU General Public License version 3.0 requirements will be
    00034 ** met: http://www.gnu.org/copyleft/gpl.html.
    00035 **
    00036 ** If you have questions regarding the use of this file, please contact
    00037 ** Nokia at qt-info@nokia.com.
    00038 ** $QT_END_LICENSE$
    00039 **
    00040 ****************************************************************************/
    00041
    00042 #ifndef QTCONCURRENT_RESULTSTORE_H
    00043 #define QTCONCURRENT_RESULTSTORE_H
    00044
    00045 #include <QtCore/qglobal.h>
    00046
    00047 #ifndef QT_NO_QFUTURE
    00048
    00049 #include <QtCore/qmap.h>
    00050 #include <QtCore/qdebug.h>
    00051
    00052 QT_BEGIN_HEADER
    00053 QT_BEGIN_NAMESPACE
    00054
    00055 QT_MODULE(Core)
    00056
    00057 /*
    00058     ResultStore stores indexed results. Results can be added and retrieved
    00059     either individually batched in a QVector. Retriveing results and checking
    00060     which indexes are in the store can be done either by iterating or by random
    00061     accees. In addition results kan be removed from the front of the store,
    00062     either individually or in batches.
    00063 */
    00064
    00065 #ifndef qdoc
    00066
    00067 namespace QtConcurrent {
    00068
    00069 class ResultItem
    00070 {
    00071 public:
    00072     ResultItem(const void *_result, int _count) : m_count(_count), result(_result) { } // contruct with vector of results
    00073     ResultItem(const void *_result) : m_count(0), result(_result) { } // construct with result
    00074     ResultItem() : m_count(0), result(0) { }
    00075     bool isValid() const { return result != 0; }
    00076     bool isVector() const { return m_count != 0; }
    00077     int count() const { return (m_count == 0) ?  1 : m_count; }
    00078     int m_count;          // result is either a pointer to a result or to a vector of results,
    00079     const void *result; // if count is 0 it's a result, otherwise it's a vector.
    00080 };
    00081
    00082 class Q_CORE_EXPORT ResultIteratorBase
    00083 {
    00084 public:
    00085     ResultIteratorBase();
    00086     ResultIteratorBase(QMap<int, ResultItem>::const_iterator _mapIterator, int _vectorIndex = 0);
    00087     int vectorIndex() const;
    00088     int resultIndex() const;
    00089
    00090     ResultIteratorBase operator++();
    00091     int batchSize() const;
    00092     void batchedAdvance();
    00093     bool operator==(const ResultIteratorBase &other) const;
    00094     bool operator!=(const ResultIteratorBase &other) const;
    00095     bool isVector() const;
    00096     bool canIncrementVectorIndex() const;
    00097 protected:
    00098     QMap<int, ResultItem>::const_iterator mapIterator;
    00099     int m_vectorIndex;
    00100 };
    00101
    00102 template <typename T>
    00103 class  ResultIterator : public ResultIteratorBase
    00104 {
    00105 public:
    00106     ResultIterator(const ResultIteratorBase &base)
    00107     : ResultIteratorBase(base) { }
    00108
    00109     const T &value() const
    00110     {
    00111         return *pointer();
    00112     }
    00113
    00114     const T *pointer() const
    00115     {
    00116         if (mapIterator.value().isVector())
    00117             return &(reinterpret_cast<const QVector<T> *>(mapIterator.value().result)->at(m_vectorIndex));
    00118         else
    00119             return reinterpret_cast<const T *>(mapIterator.value().result);
    00120     }
    00121 };
    00122
    00123 class Q_CORE_EXPORT ResultStoreBase
    00124 {
    00125 public:
    00126     ResultStoreBase();
    00127     void setFilterMode(bool enable);
    00128     bool filterMode() const;
    00129     int addResult(int index, const void *result);
    00130     int addResults(int index, const void *results, int vectorSize, int logicalCount);
    00131     ResultIteratorBase begin() const;
    00132     ResultIteratorBase end() const;
    00133     bool hasNextResult() const;
    00134     ResultIteratorBase resultAt(int index) const;
    00135     bool contains(int index) const;
    00136     int count() const;
    00137     virtual ~ResultStoreBase() { };
    00138
    00139 protected:
    00140     int insertResultItem(int index, ResultItem &resultItem);
    00141     void insertResultItemIfValid(int index, ResultItem &resultItem);
    00142     void syncPendingResults();
    00143     void syncResultCount();
    00144     int updateInsertIndex(int index, int _count);
    00145
    00146     QMap<int, ResultItem> m_results;
    00147     int insertIndex;     // The index where the next results(s) will be inserted.
    00148     int resultCount;     // The number of consecutive results stored, starting at index 0.
    00149
    00150     bool m_filterMode;
    00151     QMap<int, ResultItem> pendingResults;
    00152     int filteredResults;
    00153
    00154 };
    00155
    00156 template <typename T>
    00157 class ResultStore : public ResultStoreBase
    00158 {
    00159 public:
    00160     ResultStore() { }
    00161
    00162     ResultStore(const ResultStoreBase &base)
    00163     : ResultStoreBase(base) { }
    00164
    00165     int addResult(int index, const T  *result)
    00166     {
    00167         if (result == 0)
    00168             return ResultStoreBase::addResult(index, result);
    00169         else
    00170             return ResultStoreBase::addResult(index, new T(*result));
    00171     }
    00172
    00173     int addResults(int index, const QVector<T> *results)
    00174     {
    00175         return ResultStoreBase::addResults(index, new QVector<T>(*results), results->count(), results->count());
    00176     }
    00177
    00178     int addResults(int index, const QVector<T> *results, int totalCount)
    00179     {
    00180         return ResultStoreBase::addResults(index, new QVector<T>(*results), results->count(), totalCount);
    00181     }
    00182
    00183     int addCanceledResult(int index)
    00184     {
    00185         return addResult(index, 0);
    00186     }
    00187
    00188     int addCanceledResults(int index, int _count)
    00189     {
    00190         QVector<T> empty;
    00191         return addResults(index, &empty, _count);
    00192     }
    00193
    00194     ResultIterator<T> begin() const
    00195     {
    00196         return static_cast<ResultIterator<T> >(ResultStoreBase::begin());
    00197     }
    00198
    00199     ResultIterator<T> end() const
    00200     {
    00201         return static_cast<ResultIterator<T> >(ResultStoreBase::end());
    00202     }
    00203
    00204     ResultIterator<T> resultAt(int index) const
    00205     {
    00206         return static_cast<ResultIterator<T> >(ResultStoreBase::resultAt(index));
    00207     }
    00208
    00209     void clear()
    00210     {
    00211         QMap<int, ResultItem>::const_iterator mapIterator = m_results.constBegin();
    00212         while (mapIterator != m_results.constEnd()) {
    00213             if (mapIterator.value().isVector())
    00214                 delete reinterpret_cast<const QVector<T> *>(mapIterator.value().result);
    00215             else
    00216                 delete reinterpret_cast<const T *>(mapIterator.value().result);
    00217             ++mapIterator;
    00218         }
    00219         resultCount = 0;
    00220         m_results.clear();
    00221     }
    00222
    00223     ~ResultStore()
    00224     {
    00225         clear();
    00226     }
    00227
    00228 };
    00229
    00230 } // namespace QtConcurrent
    00231
    00232 #endif //qdoc
    00233
    00234 QT_END_NAMESPACE
    00235 QT_END_HEADER
    00236
    00237 #endif // QT_NO_CONCURRENT
    00238
    00239 #endif