From b886fd9a8729efd111d3cb1eb98501f3724d06dc 2017-06-23 14:26:20 From: mperrinel Date: 2017-06-23 14:26:20 Subject: [PATCH] Implementation of the addDateTime method of the cache --- diff --git a/core/include/Variable/VariableCacheController.h b/core/include/Variable/VariableCacheController.h index 1a037d3..edcc65d 100644 --- a/core/include/Variable/VariableCacheController.h +++ b/core/include/Variable/VariableCacheController.h @@ -18,6 +18,13 @@ public: void addDateTime(std::shared_ptr variable, const SqpDateTime &dateTime); + /// Return all of the SqpDataTime part of the dateTime whose are not in the cache + QVector provideNotInCacheDateTimeList(std::shared_ptr variable, + const SqpDateTime &dateTime); + + + QVector dateCacheList(std::shared_ptr variable) const noexcept; + private: class VariableCacheControllerPrivate; spimpl::unique_impl_ptr impl; diff --git a/core/src/Variable/VariableCacheController.cpp b/core/src/Variable/VariableCacheController.cpp index cade905..63209ce 100644 --- a/core/src/Variable/VariableCacheController.cpp +++ b/core/src/Variable/VariableCacheController.cpp @@ -15,6 +15,10 @@ struct VariableCacheController::VariableCacheControllerPrivate { void addInCacheDataByStart(const SqpDateTime &dateTime, QVector &dateTimeList, QVector ¬InCache, int cacheIndex, double currentTStart); + + + void addDateTimeRecurse(const SqpDateTime &dateTime, QVector &dateTimeList, + int cacheIndex); }; @@ -27,8 +31,27 @@ void VariableCacheController::addDateTime(std::shared_ptr variable, const SqpDateTime &dateTime) { if (variable) { - // TODO: squeeze the map to let it only some SqpDateTime without intersection - impl->m_VariableToSqpDateTimeListMap[variable].push_back(dateTime); + auto findVariableIte = impl->m_VariableToSqpDateTimeListMap.find(variable); + if (findVariableIte == impl->m_VariableToSqpDateTimeListMap.end()) { + impl->m_VariableToSqpDateTimeListMap[variable].push_back(dateTime); + } + else { + + // addDateTime modify the list of the variable in a way to ensure + // that the list is ordered : l(0) < l(1). We assume also a < b + // (with a & b of type SqpDateTime) means ts(b) > te(a) + + // The algorithm will try the merge of two interval: + // - dateTime will be compare with the first interval of the list: + // A: if it is inferior, it will be inserted and it's finished. + // B: if it is in intersection, it will be merge then the merged one + // will be compared to the next interval. The old one is remove from the list + // C: if it is superior, we do the same with the next interval of the list + + int cacheIndex = 0; + impl->addDateTimeRecurse(dateTime, impl->m_VariableToSqpDateTimeListMap.at(variable), + cacheIndex); + } } } @@ -49,6 +72,45 @@ VariableCacheController::provideNotInCacheDateTimeList(std::shared_ptr return notInCache; } +QVector +VariableCacheController::dateCacheList(std::shared_ptr variable) const noexcept +{ + return impl->m_VariableToSqpDateTimeListMap.at(variable); +} + +void VariableCacheController::VariableCacheControllerPrivate::addDateTimeRecurse( + const SqpDateTime &dateTime, QVector &dateTimeList, int cacheIndex) +{ + const auto dateTimeListSize = dateTimeList.count(); + if (cacheIndex >= dateTimeListSize) { + dateTimeList.push_back(dateTime); + // there is no anymore interval to compore, we can just push_back it + return; + } + + auto currentDateTime = dateTimeList[cacheIndex]; + + if (dateTime.m_TEnd < currentDateTime.m_TStart) { + // The compared one is < to current one compared, we can insert it + dateTimeList.insert(cacheIndex, dateTime); + } + + else if (dateTime.m_TStart > currentDateTime.m_TEnd) { + // The compared one is > to current one compared we can comparet if to the next one + addDateTimeRecurse(dateTime, dateTimeList, ++cacheIndex); + } + else { + // Merge cases: we need to merge the two interval, remove the old one from the list then + // rerun the algo from this index with the merged interval + auto mTStart = std::min(dateTime.m_TStart, currentDateTime.m_TStart); + auto mTEnd = std::max(dateTime.m_TEnd, currentDateTime.m_TEnd); + auto mergeDateTime = SqpDateTime{mTStart, mTEnd}; + + dateTimeList.remove(cacheIndex); + addDateTimeRecurse(mergeDateTime, dateTimeList, cacheIndex); + } +} + void VariableCacheController::VariableCacheControllerPrivate::addInCacheDataByEnd( const SqpDateTime &dateTime, QVector &dateTimeList, diff --git a/core/tests/Variable/TestVariableCacheController.cpp b/core/tests/Variable/TestVariableCacheController.cpp index fa97f28..ab5e726 100644 --- a/core/tests/Variable/TestVariableCacheController.cpp +++ b/core/tests/Variable/TestVariableCacheController.cpp @@ -11,6 +11,8 @@ class TestVariableCacheController : public QObject { private slots: void testProvideNotInCacheDateTimeList(); + + void testAddDateTime(); }; @@ -241,5 +243,101 @@ void TestVariableCacheController::testProvideNotInCacheDateTimeList() QCOMPARE(notInCashSqp.m_TEnd, static_cast(te.toMSecsSinceEpoch())); } + +void TestVariableCacheController::testAddDateTime() +{ + VariableCacheController variableCacheController{}; + + auto ts0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 3, 0, 0}}; + auto te0 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; + auto sqp0 = SqpDateTime{static_cast(ts0.toMSecsSinceEpoch()), + static_cast(te0.toMSecsSinceEpoch())}; + + auto ts1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}}; + auto te1 = QDateTime{QDate{2017, 01, 01}, QTime{2, 8, 0, 0}}; + auto sqp1 = SqpDateTime{static_cast(ts1.toMSecsSinceEpoch()), + static_cast(te1.toMSecsSinceEpoch())}; + + auto ts2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 18, 0, 0}}; + auto te2 = QDateTime{QDate{2017, 01, 01}, QTime{2, 20, 0, 0}}; + auto sqp2 = SqpDateTime{static_cast(ts2.toMSecsSinceEpoch()), + static_cast(te2.toMSecsSinceEpoch())}; + + auto ts01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; + auto te01 = QDateTime{QDate{2017, 01, 01}, QTime{2, 6, 0, 0}}; + auto sqp01 = SqpDateTime{static_cast(ts01.toMSecsSinceEpoch()), + static_cast(te01.toMSecsSinceEpoch())}; + + auto ts3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 14, 0, 0}}; + auto te3 = QDateTime{QDate{2017, 01, 01}, QTime{2, 16, 0, 0}}; + auto sqp3 = SqpDateTime{static_cast(ts3.toMSecsSinceEpoch()), + static_cast(te3.toMSecsSinceEpoch())}; + + auto ts03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 4, 0, 0}}; + auto te03 = QDateTime{QDate{2017, 01, 01}, QTime{2, 22, 0, 0}}; + auto sqp03 = SqpDateTime{static_cast(ts03.toMSecsSinceEpoch()), + static_cast(te03.toMSecsSinceEpoch())}; + + + auto var0 = std::make_shared("", "", "", sqp0); + + + // First case: add the first interval to the variable :sqp0 + variableCacheController.addDateTime(var0, sqp0); + auto dateCacheList = variableCacheController.dateCacheList(var0); + QCOMPARE(dateCacheList.count(), 1); + auto dateCache = dateCacheList.at(0); + QCOMPARE(dateCache.m_TStart, static_cast(ts0.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te0.toMSecsSinceEpoch())); + + // 2nd case: add a second interval : sqp1 > sqp0 + variableCacheController.addDateTime(var0, sqp1); + dateCacheList = variableCacheController.dateCacheList(var0); + QCOMPARE(dateCacheList.count(), 2); + dateCache = dateCacheList.at(0); + QCOMPARE(dateCache.m_TStart, static_cast(ts0.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te0.toMSecsSinceEpoch())); + + dateCache = dateCacheList.at(1); + QCOMPARE(dateCache.m_TStart, static_cast(ts1.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te1.toMSecsSinceEpoch())); + + // 3th case: merge sqp0 & sqp1 with sqp01 + variableCacheController.addDateTime(var0, sqp01); + dateCacheList = variableCacheController.dateCacheList(var0); + QCOMPARE(dateCacheList.count(), 1); + dateCache = dateCacheList.at(0); + QCOMPARE(dateCache.m_TStart, static_cast(ts0.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te1.toMSecsSinceEpoch())); + + + // 4th case: add a second interval : sqp1 > sqp0 + variableCacheController.addDateTime(var0, sqp2); + variableCacheController.addDateTime(var0, sqp3); + dateCacheList = variableCacheController.dateCacheList(var0); + QCOMPARE(dateCacheList.count(), 3); + dateCache = dateCacheList.at(0); + QCOMPARE(dateCache.m_TStart, static_cast(ts0.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te1.toMSecsSinceEpoch())); + + dateCache = dateCacheList.at(1); + QCOMPARE(dateCache.m_TStart, static_cast(ts3.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te3.toMSecsSinceEpoch())); + + dateCache = dateCacheList.at(2); + QCOMPARE(dateCache.m_TStart, static_cast(ts2.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te2.toMSecsSinceEpoch())); + + + // 5th case: merge all interval + variableCacheController.addDateTime(var0, sqp03); + dateCacheList = variableCacheController.dateCacheList(var0); + QCOMPARE(dateCacheList.count(), 1); + dateCache = dateCacheList.at(0); + QCOMPARE(dateCache.m_TStart, static_cast(ts0.toMSecsSinceEpoch())); + QCOMPARE(dateCache.m_TEnd, static_cast(te03.toMSecsSinceEpoch())); +} + + QTEST_MAIN(TestVariableCacheController) #include "TestVariableCacheController.moc"