From dfd7bdd22afd1467dda196b9c9c49b7170d9e98a Mon Sep 17 00:00:00 2001 From: David Schulz Date: Thu, 18 Jun 2020 12:32:48 +0200 Subject: Autotest: Introduce ItemDataCache Change-Id: Icbd703a8ddd3c5dea4a90d2c32c1866764bc0267 Reviewed-by: Christian Stenger --- src/plugins/autotest/testnavigationwidget.cpp | 36 +++++++++---------------- src/plugins/autotest/testnavigationwidget.h | 9 +++---- src/plugins/autotest/testtreemodel.cpp | 23 +++++----------- src/plugins/autotest/testtreemodel.h | 38 +++++++++++++++++++++++++-- 4 files changed, 57 insertions(+), 49 deletions(-) (limited to 'src/plugins/autotest') diff --git a/src/plugins/autotest/testnavigationwidget.cpp b/src/plugins/autotest/testnavigationwidget.cpp index f3195c873b..31b0c6749b 100644 --- a/src/plugins/autotest/testnavigationwidget.cpp +++ b/src/plugins/autotest/testnavigationwidget.cpp @@ -111,7 +111,6 @@ TestNavigationWidget::TestNavigationWidget(QWidget *parent) : connect(sm, &ProjectExplorer::SessionManager::startupProjectChanged, this, [this](ProjectExplorer::Project * /*project*/) { m_expandedStateCache.clear(); - m_itemUseCache.clear(); }); connect(m_model, &TestTreeModel::testTreeModelChanged, this, &TestNavigationWidget::reapplyCachedExpandedState); @@ -237,22 +236,12 @@ QList TestNavigationWidget::createToolButtons() void TestNavigationWidget::updateExpandedStateCache() { - // raise generation for cached items and drop anything reaching 10th generation - const QList cachedNames = m_itemUseCache.keys(); - for (const QString &cachedName : cachedNames) { - auto it = m_itemUseCache.find(cachedName); - if (it.value()++ >= 10) { - m_itemUseCache.erase(it); - m_expandedStateCache.remove(cachedName); - } - } + m_expandedStateCache.evolve(); for (Utils::TreeItem *rootNode : *m_model->rootItem()) { rootNode->forAllChildren([this](Utils::TreeItem *child) { - auto childItem = static_cast(child); - const QString cacheName = childItem->cacheName(); - m_expandedStateCache.insert(cacheName, m_view->isExpanded(childItem->index())); - m_itemUseCache[cacheName] = 0; // explicitly mark as 0-generation + m_expandedStateCache.insert(static_cast(child), + m_view->isExpanded(child->index())); }); } } @@ -328,16 +317,15 @@ void TestNavigationWidget::onRunThisTestTriggered(TestRunMode runMode) void TestNavigationWidget::reapplyCachedExpandedState() { - for (Utils::TreeItem *rootNode : *m_model->rootItem()) { - rootNode->forAllChildren([this](Utils::TreeItem *child) { - auto childItem = static_cast(child); - const QString cacheName = childItem->cacheName(); - const auto it = m_expandedStateCache.find(cacheName); - if (it == m_expandedStateCache.end()) - return; - QModelIndex index = child->index(); - if (m_view->isExpanded(index) != it.value()) - m_view->setExpanded(index, it.value()); + using namespace Utils; + for (TreeItem *rootNode : *m_model->rootItem()) { + rootNode->forAllChildren([this](TreeItem *child) { + optional cached = m_expandedStateCache.get(static_cast(child)); + if (cached.has_value()) { + QModelIndex index = child->index(); + if (m_view->isExpanded(index) != cached.value()) + m_view->setExpanded(index, cached.value()); + } }); } } diff --git a/src/plugins/autotest/testnavigationwidget.h b/src/plugins/autotest/testnavigationwidget.h index 23a12d4254..454f893c6b 100644 --- a/src/plugins/autotest/testnavigationwidget.h +++ b/src/plugins/autotest/testnavigationwidget.h @@ -27,6 +27,8 @@ #include "testrunner.h" +#include "testtreemodel.h" + #include #include @@ -47,12 +49,8 @@ class ProgressIndicator; } namespace Autotest { - -class TestTreeModel; - namespace Internal { -class TestTreeSortFilterModel; class TestTreeView; class TestNavigationWidget : public QWidget @@ -86,8 +84,7 @@ private: Utils::ProgressIndicator *m_progressIndicator; QTimer *m_progressTimer; QFrame *m_missingFrameworksWidget; - QHash m_expandedStateCache; - QHash m_itemUseCache; + ItemDataCache m_expandedStateCache; }; class TestNavigationWidgetFactory : public Core::INavigationWidgetFactory diff --git a/src/plugins/autotest/testtreemodel.cpp b/src/plugins/autotest/testtreemodel.cpp index 13d62216f2..95330d5fc9 100644 --- a/src/plugins/autotest/testtreemodel.cpp +++ b/src/plugins/autotest/testtreemodel.cpp @@ -92,7 +92,6 @@ void TestTreeModel::setupParsingConnections() synchronizeTestFrameworks(); // we might have project settings m_parser->onStartupProjectChanged(project); m_checkStateCache.clear(); // TODO persist to project settings? - m_itemUseCache.clear(); }); CppTools::CppModelManager *cppMM = CppTools::CppModelManager::instance(); @@ -295,22 +294,12 @@ void TestTreeModel::rebuild(const QList &frameworkIds) void TestTreeModel::updateCheckStateCache() { - // raise generation for cached items and drop anything reaching 10th generation - const QList cachedNames = m_itemUseCache.keys(); - for (const QString &cachedName : cachedNames) { - auto it = m_itemUseCache.find(cachedName); - if (it.value()++ >= 10) { - m_itemUseCache.erase(it); - m_checkStateCache.remove(cachedName); - } - } + m_checkStateCache.evolve(); for (Utils::TreeItem *rootNode : *rootItem()) { rootNode->forAllChildren([this](Utils::TreeItem *child) { auto childItem = static_cast(child); - const QString cacheName = childItem->cacheName(); - m_checkStateCache.insert(cacheName, childItem->checked()); - m_itemUseCache[cacheName] = 0; // explicitly mark as 0-generation + m_checkStateCache.insert(childItem, childItem->checked()); }); } } @@ -436,8 +425,8 @@ void TestTreeModel::insertItemInParent(TestTreeItem *item, TestTreeItem *root, b delete item; } else { // restore former check state if available - auto cached = m_checkStateCache.find(item->cacheName()); - if (cached != m_checkStateCache.end()) + Utils::optional cached = m_checkStateCache.get(item); + if (cached.has_value()) item->setData(0, cached.value(), Qt::CheckStateRole); else applyParentCheckState(parentNode, item); @@ -526,8 +515,8 @@ void TestTreeModel::handleParseResult(const TestParseResult *result, TestTreeIte // restore former check state if available newItem->forAllChildren([this](Utils::TreeItem *child) { auto childItem = static_cast(child); - auto cached = m_checkStateCache.find(childItem->cacheName()); - if (cached != m_checkStateCache.end()) + Utils::optional cached = m_checkStateCache.get(childItem); + if (cached.has_value()) childItem->setData(0, cached.value(), Qt::CheckStateRole); }); // it might be necessary to "split" created item diff --git a/src/plugins/autotest/testtreemodel.h b/src/plugins/autotest/testtreemodel.h index af3501c484..4ca3cb27b4 100644 --- a/src/plugins/autotest/testtreemodel.h +++ b/src/plugins/autotest/testtreemodel.h @@ -30,6 +30,7 @@ #include "testconfiguration.h" #include "testtreeitem.h" +#include #include #include @@ -38,6 +39,40 @@ namespace Autotest { namespace Internal { class AutotestPluginPrivate; class TestCodeParser; + +template +class ItemDataCache +{ +public: + void insert(TestTreeItem *item, const T &value) { m_cache[item->cacheName()] = {0, value}; } + void evolve() + { + auto it = m_cache.begin(), end = m_cache.end(); + while (it != end) + it = it->generation++ >= maxGen ? m_cache.erase(it) : ++it; + } + + Utils::optional get(TestTreeItem *item) + { + auto entry = m_cache.find(item->cacheName()); + if (entry == m_cache.end()) + return Utils::nullopt; + entry->generation = 0; + return Utils::make_optional(entry->value); + }; + + void clear() { m_cache.clear(); } + +private: + static constexpr int maxGen = 10; + struct Entry + { + int generation = 0; + T value; + }; + QHash m_cache; +}; + } // namespace Internal class TestParseResult; @@ -104,8 +139,7 @@ private: QList testItemsByName(TestTreeItem *root, const QString &testName); Internal::TestCodeParser *m_parser = nullptr; - QHash m_checkStateCache; - QHash m_itemUseCache; + Internal::ItemDataCache m_checkStateCache; }; namespace Internal { -- cgit v1.2.3