##// END OF EJS Templates
Made Variable data update atomic ease thread safety and avoid mixing...
jeandet -
r16:5da3a19e8770
parent child
Show More
@@ -207,7 +207,7 class SCIQLOP_CORE_EXPORT DataSeries : public IDataSeries {
207 public:
207 public:
208 /// @sa IDataSeries::xAxisData()
208 /// @sa IDataSeries::xAxisData()
209 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
209 std::shared_ptr<ArrayData<1> > xAxisData() override { return m_XAxisData; }
210 const std::shared_ptr<ArrayData<1> > xAxisData() const { return m_XAxisData; }
210 const std::shared_ptr<ArrayData<1> > xAxisData() const override { return m_XAxisData; }
211
211
212 /// @sa IDataSeries::xAxisUnit()
212 /// @sa IDataSeries::xAxisUnit()
213 Unit xAxisUnit() const override { return m_XAxisUnit; }
213 Unit xAxisUnit() const override { return m_XAxisUnit; }
@@ -415,9 +415,12 public:
415 // Mutexes //
415 // Mutexes //
416 // /////// //
416 // /////// //
417
417
418 virtual void lockRead() { m_Lock.lockForRead(); }
418 virtual QReadLocker getReadLock() override { return QReadLocker{&m_Lock}; }
419 virtual void lockWrite() { m_Lock.lockForWrite(); }
419 virtual QWriteLocker getWriteLock() override { return QWriteLocker{&m_Lock}; }
420 virtual void unlock() { m_Lock.unlock(); }
420
421 virtual void lockRead() override { m_Lock.lockForRead(); }
422 virtual void lockWrite() override { m_Lock.lockForWrite(); }
423 virtual void unlock() override { m_Lock.unlock(); }
421
424
422 protected:
425 protected:
423 /// Protected ctor (DataSeries is abstract).
426 /// Protected ctor (DataSeries is abstract).
@@ -1,14 +1,17
1 #ifndef SCIQLOP_IDATASERIES_H
1 #ifndef SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
2 #define SCIQLOP_IDATASERIES_H
3
3
4 #include <memory>
5
6 #include <QReadWriteLock>
7 #include <QString>
8
4 #include <Common/MetaTypes.h>
9 #include <Common/MetaTypes.h>
5 #include <Data/DataSeriesIterator.h>
10 #include <Data/DataSeriesIterator.h>
6 #include <Data/DateTimeRange.h>
11 #include <Data/DateTimeRange.h>
7 #include <Data/Unit.h>
12 #include <Data/Unit.h>
13 #include <Common/deprecate.h>
8
14
9 #include <memory>
10
11 #include <QString>
12
15
13 template <int Dim>
16 template <int Dim>
14 class ArrayData;
17 class ArrayData;
@@ -90,10 +93,13 public:
90 // /////// //
93 // /////// //
91 // Mutexes //
94 // Mutexes //
92 // /////// //
95 // /////// //
93
96 virtual QReadLocker getReadLock() = 0;
97 virtual QWriteLocker getWriteLock() = 0;
98 DEPRECATE(
94 virtual void lockRead() = 0;
99 virtual void lockRead() = 0;
95 virtual void lockWrite() = 0;
100 virtual void lockWrite() = 0;
96 virtual void unlock() = 0;
101 virtual void unlock() = 0;
102 )
97 };
103 };
98
104
99 // Required for using shared_ptr in signals/slots
105 // Required for using shared_ptr in signals/slots
@@ -26,7 +26,7 public:
26 explicit VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
26 explicit VectorSeries(std::vector<double> xAxisData, std::vector<double> valuesData,
27 const Unit &xAxisUnit, const Unit &valuesUnit);
27 const Unit &xAxisUnit, const Unit &valuesUnit);
28
28
29 std::unique_ptr<IDataSeries> clone() const;
29 std::unique_ptr<IDataSeries> clone() const override;
30
30
31 std::shared_ptr<IDataSeries> subDataSeries(const DateTimeRange &range) override;
31 std::shared_ptr<IDataSeries> subDataSeries(const DateTimeRange &range) override;
32 };
32 };
@@ -1,15 +1,16
1 #ifndef SCIQLOP_VARIABLE_H
1 #ifndef SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
2 #define SCIQLOP_VARIABLE_H
3
3
4 #include "CoreGlobal.h"
4 #include <QLoggingCategory>
5 #include <QObject>
6 #include <QUuid>
7 #include <QReadWriteLock>
5
8
9 #include "CoreGlobal.h"
6 #include <Data/DataSeriesIterator.h>
10 #include <Data/DataSeriesIterator.h>
7 #include <Data/DataSeriesType.h>
11 #include <Data/DataSeriesType.h>
8 #include <Data/DateTimeRange.h>
12 #include <Data/DateTimeRange.h>
9
13
10 #include <QLoggingCategory>
11 #include <QObject>
12 #include <QUuid>
13
14
14 #include <Common/deprecate.h>
15 #include <Common/deprecate.h>
15 #include <Common/MetaTypes.h>
16 #include <Common/MetaTypes.h>
@@ -77,7 +78,10 DEPRECATE(
77 DEPRECATE(
78 DEPRECATE(
78 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
79 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
79 )
80 )
80 void mergeDataSeries(IDataSeries* dataSeries, bool notify=false) noexcept;
81
82 void updateData(const std::vector<IDataSeries*>& dataSeries,
83 const DateTimeRange& newRange, const DateTimeRange& newCacheRange,
84 bool notify=true);
81
85
82 DEPRECATE(
86 DEPRECATE(
83 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
87 static QVector<DateTimeRange> provideNotInCacheRangeList(const DateTimeRange &oldRange,
@@ -98,6 +102,7 private:
98 class VariablePrivate;
102 class VariablePrivate;
99 spimpl::unique_impl_ptr<VariablePrivate> impl;
103 spimpl::unique_impl_ptr<VariablePrivate> impl;
100 QUuid _uuid;
104 QUuid _uuid;
105 QReadWriteLock m_lock;
101 };
106 };
102
107
103 // Required for using shared_ptr in signals/slots
108 // Required for using shared_ptr in signals/slots
@@ -12,7 +12,6
12
12
13 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
13 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
14
14
15 namespace {
16
15
17 /**
16 /**
18 * Searches in metadata for a value that can be converted to DataSeriesType
17 * Searches in metadata for a value that can be converted to DataSeriesType
@@ -20,7 +19,7 namespace {
20 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
19 * @return the value converted to a DataSeriesType if it was found, UNKNOWN type otherwise
21 * @sa DataSeriesType
20 * @sa DataSeriesType
22 */
21 */
23 DataSeriesType findDataSeriesType(const QVariantHash &metadata)
22 static DataSeriesType findDataSeriesType(const QVariantHash &metadata)
24 {
23 {
25 auto dataSeriesType = DataSeriesType::UNKNOWN;
24 auto dataSeriesType = DataSeriesType::UNKNOWN;
26
25
@@ -33,7 +32,6 DataSeriesType findDataSeriesType(const QVariantHash &metadata)
33 return dataSeriesType;
32 return dataSeriesType;
34 }
33 }
35
34
36 } // namespace
37
35
38 #define VP_PROPERTY(property,getter,setter,type) \
36 #define VP_PROPERTY(property,getter,setter,type) \
39 type getter() noexcept\
37 type getter() noexcept\
@@ -95,23 +93,31 struct Variable::VariablePrivate {
95 updateRealRange();
93 updateRealRange();
96 updateNbPoints();
94 updateNbPoints();
97 }
95 }
98
96 void mergeDataSeries(const std::vector<IDataSeries*>& dataseries)
97 {
98 QWriteLocker lock{&m_Lock};
99 for(auto ds:dataseries)
100 {
101 if(m_DataSeries)
102 m_DataSeries->merge(ds);
103 else
104 m_DataSeries = ds->clone();
105 }
106 }
99 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
107 void updateNbPoints() { m_NbPoints = m_DataSeries ? m_DataSeries->nbPoints() : 0; }
100
108
101 /// Updates real range according to current variable range and data series
109 /// Updates real range according to current variable range and data series
102 void updateRealRange()
110 void updateRealRange()
103 {
111 {
104 if (m_DataSeries) {
112 if (m_DataSeries) {
105 m_DataSeries->lockRead();
113 auto lock = m_DataSeries->getReadLock();
106 auto end = m_DataSeries->cend();
114 auto end = m_DataSeries->cend();
107 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
115 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
108 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
116 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
109
117 if(minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
110 m_RealRange
118 m_RealRange = DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()};
111 = (minXAxisIt != end && maxXAxisIt != end && minXAxisIt->x() <= maxXAxisIt->x())
119 else
112 ? DateTimeRange{minXAxisIt->x(), maxXAxisIt->x()}
120 m_RealRange = std::nullopt;
113 : INVALID_RANGE;
114 m_DataSeries->unlock();
115 }
121 }
116 else {
122 else {
117 m_RealRange = std::nullopt;
123 m_RealRange = std::nullopt;
@@ -201,34 +207,17 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
201 }
207 }
202 }
208 }
203
209
204 void Variable::mergeDataSeries(IDataSeries *dataSeries, bool notify) noexcept
210 void Variable::updateData(const std::vector<IDataSeries *> &dataSeries, const DateTimeRange &newRange, const DateTimeRange &newCacheRange, bool notify)
205 {
211 {
206 if (dataSeries==nullptr) {
212 {
207 SCIQLOP_ERROR(Variable,"Given IDataSeries is nullptr");
213 QWriteLocker lock{&m_lock};
208 return;
214 impl->mergeDataSeries(dataSeries);
209 }
215 impl->setRange(newRange);
210
216 impl->setCacheRange(newCacheRange);
211 auto dataInit = false;
217 impl->purgeDataSeries();
212 // @TODO move impl to Pimpl this is what it stands for...
213 // Add or merge the data
214 impl->lockWrite();
215 if (!impl->m_DataSeries) {
216 //@TODO find a better way
217 impl->m_DataSeries = dataSeries->clone();
218 dataInit = true;
219 delete dataSeries;
220 }
221 else {
222 impl->m_DataSeries->merge(dataSeries);
223 }
224 impl->purgeDataSeries();
225 impl->unlock();
226
227 if (dataInit) {
228 emit dataInitialized();
229 }
218 }
230 if(notify)
219 if(notify)
231 emit this->updated();
220 emit updated();
232 }
221 }
233
222
234
223
@@ -40,13 +40,12 class VariableController2::VariableController2Private
40 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
40 newCacheRange = _cacheStrategy->computeRange(var->cacheRange(),r);
41 missingRanges = newCacheRange - var->cacheRange();
41 missingRanges = newCacheRange - var->cacheRange();
42 }
42 }
43 std::vector<IDataSeries*> data;
43 for(auto range:missingRanges)
44 for(auto range:missingRanges)
44 {
45 {
45 auto data = provider->getData(DataProviderParameters{{range},var->metadata()});
46 data.push_back(provider->getData(DataProviderParameters{{range},var->metadata()}));
46 var->mergeDataSeries(data);
47 }
47 }
48 var->setCacheRange(newCacheRange);
48 var->updateData(data,r,newCacheRange,true);
49 var->setRange(r);
50 }
49 }
51 public:
50 public:
52 VariableController2Private(QObject* parent=Q_NULLPTR)
51 VariableController2Private(QObject* parent=Q_NULLPTR)
@@ -12,7 +12,7 namespace {
12
12
13 /// Provider used for the tests
13 /// Provider used for the tests
14 class TestProvider : public IDataProvider {
14 class TestProvider : public IDataProvider {
15 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
15 std::shared_ptr<IDataProvider> clone() const override { return std::make_shared<TestProvider>(); }
16
16
17 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
17 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
18 {
18 {
@@ -69,7 +69,7 void validateRanges(VariableController &variableController,
69
69
70 /// Provider used for the tests
70 /// Provider used for the tests
71 class TestProvider : public IDataProvider {
71 class TestProvider : public IDataProvider {
72 std::shared_ptr<IDataProvider> clone() const { return std::make_shared<TestProvider>(); }
72 std::shared_ptr<IDataProvider> clone() const override { return std::make_shared<TestProvider>(); }
73
73
74 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
74 void requestDataLoading(QUuid acqIdentifier, const DataProviderParameters &parameters) override
75 {
75 {
General Comments 0
You need to be logged in to leave comments. Login now