##// END OF EJS Templates
Creates attribute to get nb points of a variable
Alexandre Leroux -
r716:880a343c8475
parent child
Show More
@@ -1,80 +1,84
1 1 #ifndef SCIQLOP_VARIABLE_H
2 2 #define SCIQLOP_VARIABLE_H
3 3
4 4 #include "CoreGlobal.h"
5 5
6 6 #include <Data/DataSeriesIterator.h>
7 7 #include <Data/SqpRange.h>
8 8
9 9 #include <QLoggingCategory>
10 10 #include <QObject>
11 11
12 12 #include <Common/MetaTypes.h>
13 13 #include <Common/spimpl.h>
14 14
15 15 Q_DECLARE_LOGGING_CATEGORY(LOG_Variable)
16 16
17 17 class IDataSeries;
18 18 class QString;
19 19
20 20 /**
21 21 * @brief The Variable class represents a variable in SciQlop.
22 22 */
23 23 class SCIQLOP_CORE_EXPORT Variable : public QObject {
24 24
25 25 Q_OBJECT
26 26
27 27 public:
28 28 explicit Variable(const QString &name, const SqpRange &dateTime,
29 29 const QVariantHash &metadata = {});
30 30
31 31 /// Copy ctor
32 32 explicit Variable(const Variable &other);
33 33
34 34 std::shared_ptr<Variable> clone() const;
35 35
36 36 QString name() const noexcept;
37 37 void setName(const QString &name) noexcept;
38 38 SqpRange range() const noexcept;
39 39 void setRange(const SqpRange &range) noexcept;
40 40 SqpRange cacheRange() const noexcept;
41 41 void setCacheRange(const SqpRange &cacheRange) noexcept;
42 42
43 /// @return the number of points hold by the variable. The number of points is updated each time
44 /// the data series changes
45 int nbPoints() const noexcept;
46
43 47 /// Returns the real range of the variable, i.e. the min and max x-axis values of the data
44 48 /// series between the range of the variable. The real range is updated each time the variable
45 49 /// range or the data series changed
46 50 /// @return the real range, invalid range if the data series is null or empty
47 51 /// @sa setDataSeries()
48 52 /// @sa setRange()
49 53 SqpRange realRange() const noexcept;
50 54
51 55 /// @return the data of the variable, nullptr if there is no data
52 56 std::shared_ptr<IDataSeries> dataSeries() const noexcept;
53 57
54 58 QVariantHash metadata() const noexcept;
55 59
56 60 bool contains(const SqpRange &range) const noexcept;
57 61 bool intersect(const SqpRange &range) const noexcept;
58 62 bool isInside(const SqpRange &range) const noexcept;
59 63
60 64 bool cacheContains(const SqpRange &range) const noexcept;
61 65 bool cacheIntersect(const SqpRange &range) const noexcept;
62 66 bool cacheIsInside(const SqpRange &range) const noexcept;
63 67
64 68 QVector<SqpRange> provideNotInCacheRangeList(const SqpRange &range) const noexcept;
65 69 QVector<SqpRange> provideInCacheRangeList(const SqpRange &range) const noexcept;
66 70 void mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept;
67 71
68 72 signals:
69 73 void updated();
70 74
71 75 private:
72 76 class VariablePrivate;
73 77 spimpl::unique_impl_ptr<VariablePrivate> impl;
74 78 };
75 79
76 80 // Required for using shared_ptr in signals/slots
77 81 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_REGISTRY, std::shared_ptr<Variable>)
78 82 SCIQLOP_REGISTER_META_TYPE(VARIABLE_PTR_VECTOR_REGISTRY, QVector<std::shared_ptr<Variable> >)
79 83
80 84 #endif // SCIQLOP_VARIABLE_H
@@ -1,296 +1,304
1 1 #include "Variable/Variable.h"
2 2
3 3 #include <Data/IDataSeries.h>
4 4 #include <Data/SqpRange.h>
5 5
6 6 #include <QMutex>
7 7 #include <QReadWriteLock>
8 8 #include <QThread>
9 9
10 10 Q_LOGGING_CATEGORY(LOG_Variable, "Variable")
11 11
12 12 struct Variable::VariablePrivate {
13 13 explicit VariablePrivate(const QString &name, const SqpRange &dateTime,
14 14 const QVariantHash &metadata)
15 15 : m_Name{name},
16 16 m_Range{dateTime},
17 17 m_Metadata{metadata},
18 18 m_DataSeries{nullptr},
19 m_RealRange{INVALID_RANGE}
19 m_RealRange{INVALID_RANGE},
20 m_NbPoints{0}
20 21 {
21 22 }
22 23
23 24 VariablePrivate(const VariablePrivate &other)
24 25 : m_Name{other.m_Name},
25 26 m_Range{other.m_Range},
26 27 m_Metadata{other.m_Metadata},
27 28 m_DataSeries{other.m_DataSeries != nullptr ? other.m_DataSeries->clone() : nullptr},
28 m_RealRange{other.m_RealRange}
29 m_RealRange{other.m_RealRange},
30 m_NbPoints{other.m_NbPoints}
29 31 {
30 32 }
31 33
32 34 void lockRead() { m_Lock.lockForRead(); }
33 35 void lockWrite() { m_Lock.lockForWrite(); }
34 36 void unlock() { m_Lock.unlock(); }
35 37
36 38 void purgeDataSeries()
37 39 {
38 40 if (m_DataSeries) {
39 41 m_DataSeries->purge(m_CacheRange.m_TStart, m_CacheRange.m_TEnd);
40 42 }
41 43 updateRealRange();
42 44 }
43 45
44 46 /// Updates real range according to current variable range and data series
45 47 void updateRealRange()
46 48 {
47 49 if (m_DataSeries) {
48 50 m_DataSeries->lockRead();
49 51 auto end = m_DataSeries->cend();
50 52 auto minXAxisIt = m_DataSeries->minXAxisData(m_Range.m_TStart);
51 53 auto maxXAxisIt = m_DataSeries->maxXAxisData(m_Range.m_TEnd);
52 54
53 55 m_RealRange = (minXAxisIt != end && maxXAxisIt != end)
54 56 ? SqpRange{minXAxisIt->x(), maxXAxisIt->x()}
55 57 : INVALID_RANGE;
56 58 m_DataSeries->unlock();
57 59 }
58 60 else {
59 61 m_RealRange = INVALID_RANGE;
60 62 }
61 63 }
62 64
63 65 QString m_Name;
64 66
65 67 SqpRange m_Range;
66 68 SqpRange m_CacheRange;
67 69 QVariantHash m_Metadata;
68 70 std::shared_ptr<IDataSeries> m_DataSeries;
69 71 SqpRange m_RealRange;
72 int m_NbPoints;
70 73
71 74 QReadWriteLock m_Lock;
72 75 };
73 76
74 77 Variable::Variable(const QString &name, const SqpRange &dateTime, const QVariantHash &metadata)
75 78 : impl{spimpl::make_unique_impl<VariablePrivate>(name, dateTime, metadata)}
76 79 {
77 80 }
78 81
79 82 Variable::Variable(const Variable &other)
80 83 : impl{spimpl::make_unique_impl<VariablePrivate>(*other.impl)}
81 84 {
82 85 }
83 86
84 87 std::shared_ptr<Variable> Variable::clone() const
85 88 {
86 89 return std::make_shared<Variable>(*this);
87 90 }
88 91
89 92 QString Variable::name() const noexcept
90 93 {
91 94 impl->lockRead();
92 95 auto name = impl->m_Name;
93 96 impl->unlock();
94 97 return name;
95 98 }
96 99
97 100 void Variable::setName(const QString &name) noexcept
98 101 {
99 102 impl->lockWrite();
100 103 impl->m_Name = name;
101 104 impl->unlock();
102 105 }
103 106
104 107 SqpRange Variable::range() const noexcept
105 108 {
106 109 impl->lockRead();
107 110 auto range = impl->m_Range;
108 111 impl->unlock();
109 112 return range;
110 113 }
111 114
112 115 void Variable::setRange(const SqpRange &range) noexcept
113 116 {
114 117 impl->lockWrite();
115 118 impl->m_Range = range;
116 119 impl->updateRealRange();
117 120 impl->unlock();
118 121 }
119 122
120 123 SqpRange Variable::cacheRange() const noexcept
121 124 {
122 125 impl->lockRead();
123 126 auto cacheRange = impl->m_CacheRange;
124 127 impl->unlock();
125 128 return cacheRange;
126 129 }
127 130
128 131 void Variable::setCacheRange(const SqpRange &cacheRange) noexcept
129 132 {
130 133 impl->lockWrite();
131 134 if (cacheRange != impl->m_CacheRange) {
132 135 impl->m_CacheRange = cacheRange;
133 136 impl->purgeDataSeries();
134 137 }
135 138 impl->unlock();
136 139 }
137 140
141 int Variable::nbPoints() const noexcept
142 {
143 return impl->m_NbPoints;
144 }
145
138 146 SqpRange Variable::realRange() const noexcept
139 147 {
140 148 return impl->m_RealRange;
141 149 }
142 150
143 151 void Variable::mergeDataSeries(std::shared_ptr<IDataSeries> dataSeries) noexcept
144 152 {
145 153 qCDebug(LOG_Variable()) << "TORM Variable::mergeDataSeries"
146 154 << QThread::currentThread()->objectName();
147 155 if (!dataSeries) {
148 156 /// @todo ALX : log
149 157 return;
150 158 }
151 159
152 160 // Add or merge the data
153 161 impl->lockWrite();
154 162 if (!impl->m_DataSeries) {
155 163 impl->m_DataSeries = dataSeries->clone();
156 164 }
157 165 else {
158 166 impl->m_DataSeries->merge(dataSeries.get());
159 167 }
160 168 impl->purgeDataSeries();
161 169 impl->unlock();
162 170 }
163 171
164 172 std::shared_ptr<IDataSeries> Variable::dataSeries() const noexcept
165 173 {
166 174 impl->lockRead();
167 175 auto dataSeries = impl->m_DataSeries;
168 176 impl->unlock();
169 177
170 178 return dataSeries;
171 179 }
172 180
173 181 QVariantHash Variable::metadata() const noexcept
174 182 {
175 183 impl->lockRead();
176 184 auto metadata = impl->m_Metadata;
177 185 impl->unlock();
178 186 return metadata;
179 187 }
180 188
181 189 bool Variable::contains(const SqpRange &range) const noexcept
182 190 {
183 191 impl->lockRead();
184 192 auto res = impl->m_Range.contains(range);
185 193 impl->unlock();
186 194 return res;
187 195 }
188 196
189 197 bool Variable::intersect(const SqpRange &range) const noexcept
190 198 {
191 199
192 200 impl->lockRead();
193 201 auto res = impl->m_Range.intersect(range);
194 202 impl->unlock();
195 203 return res;
196 204 }
197 205
198 206 bool Variable::isInside(const SqpRange &range) const noexcept
199 207 {
200 208 impl->lockRead();
201 209 auto res = range.contains(SqpRange{impl->m_Range.m_TStart, impl->m_Range.m_TEnd});
202 210 impl->unlock();
203 211 return res;
204 212 }
205 213
206 214 bool Variable::cacheContains(const SqpRange &range) const noexcept
207 215 {
208 216 impl->lockRead();
209 217 auto res = impl->m_CacheRange.contains(range);
210 218 impl->unlock();
211 219 return res;
212 220 }
213 221
214 222 bool Variable::cacheIntersect(const SqpRange &range) const noexcept
215 223 {
216 224 impl->lockRead();
217 225 auto res = impl->m_CacheRange.intersect(range);
218 226 impl->unlock();
219 227 return res;
220 228 }
221 229
222 230 bool Variable::cacheIsInside(const SqpRange &range) const noexcept
223 231 {
224 232 impl->lockRead();
225 233 auto res = range.contains(SqpRange{impl->m_CacheRange.m_TStart, impl->m_CacheRange.m_TEnd});
226 234 impl->unlock();
227 235 return res;
228 236 }
229 237
230 238
231 239 QVector<SqpRange> Variable::provideNotInCacheRangeList(const SqpRange &range) const noexcept
232 240 {
233 241 // This code assume that cach in contigue. Can return 0, 1 or 2 SqpRange
234 242
235 243 auto notInCache = QVector<SqpRange>{};
236 244
237 245 if (!this->cacheContains(range)) {
238 246 if (range.m_TEnd <= impl->m_CacheRange.m_TStart
239 247 || range.m_TStart >= impl->m_CacheRange.m_TEnd) {
240 248 notInCache << range;
241 249 }
242 250 else if (range.m_TStart < impl->m_CacheRange.m_TStart
243 251 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
244 252 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart};
245 253 }
246 254 else if (range.m_TStart < impl->m_CacheRange.m_TStart
247 255 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
248 256 notInCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TStart}
249 257 << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
250 258 }
251 259 else if (range.m_TStart < impl->m_CacheRange.m_TEnd) {
252 260 notInCache << SqpRange{impl->m_CacheRange.m_TEnd, range.m_TEnd};
253 261 }
254 262 else {
255 263 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
256 264 << QThread::currentThread();
257 265 }
258 266 }
259 267
260 268 return notInCache;
261 269 }
262 270
263 271 QVector<SqpRange> Variable::provideInCacheRangeList(const SqpRange &range) const noexcept
264 272 {
265 273 // This code assume that cach in contigue. Can return 0 or 1 SqpRange
266 274
267 275 auto inCache = QVector<SqpRange>{};
268 276
269 277
270 278 if (this->intersect(range)) {
271 279 if (range.m_TStart <= impl->m_CacheRange.m_TStart
272 280 && range.m_TEnd >= impl->m_CacheRange.m_TStart
273 281 && range.m_TEnd < impl->m_CacheRange.m_TEnd) {
274 282 inCache << SqpRange{impl->m_CacheRange.m_TStart, range.m_TEnd};
275 283 }
276 284
277 285 else if (range.m_TStart >= impl->m_CacheRange.m_TStart
278 286 && range.m_TEnd <= impl->m_CacheRange.m_TEnd) {
279 287 inCache << range;
280 288 }
281 289 else if (range.m_TStart > impl->m_CacheRange.m_TStart
282 290 && range.m_TEnd > impl->m_CacheRange.m_TEnd) {
283 291 inCache << SqpRange{range.m_TStart, impl->m_CacheRange.m_TEnd};
284 292 }
285 293 else if (range.m_TStart <= impl->m_CacheRange.m_TStart
286 294 && range.m_TEnd >= impl->m_CacheRange.m_TEnd) {
287 295 inCache << impl->m_CacheRange;
288 296 }
289 297 else {
290 298 qCCritical(LOG_Variable()) << tr("Detection of unknown case.")
291 299 << QThread::currentThread();
292 300 }
293 301 }
294 302
295 303 return inCache;
296 304 }
General Comments 0
You need to be logged in to leave comments. Login now