[kdevelop/kdevelop] kdevplatform/language/duchain: DUChain: Do not randomly discard top-contextes on shutdown

Jarmo Tiitto <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit ec0dd0d8a91b29e194c9676aa9d57a21dacc5713 by Jarmo Tiitto.
Committed on 02/08/2026 at 13:13.
Pushed by jatothrim into branch 'master'.

DUChain: Do not randomly discard top-contextes on shutdown

Reviewing the DUChainPrivate::cleanupTopContexts() reveals an
astonishing fact: we are selecting a random set of top-contextes to be
discarded on DUChain::shutdown(). The discarded data will be recreated
on the session's next launch causing a large amount of wasted work to be
done.

Get rid of the cleanupTopContexts() step since it is actively harmful
on loading the session the next time.

M  +0    -8    kdevplatform/language/duchain/duchain.cpp
M  +0    -88   kdevplatform/language/duchain/duchainprivate.cpp
M  +0    -9    kdevplatform/language/duchain/duchainprivate.h

https://invent.kde.org/kdevelop/kdevelop/-/commit/ec0dd0d8a91b29e194c9676aa9d57a21dacc5713

diff --git a/kdevplatform/language/duchain/duchain.cpp b/kdevplatform/language/duchain/duchain.cpp
index 3a9f5fdcfd..3ea70bde0b 100644
--- a/kdevplatform/language/duchain/duchain.cpp
+++ b/kdevplatform/language/duchain/duchain.cpp
@@ -574,14 +574,6 @@ void DUChain::shutdown()
 
     QMutexLocker lock(&sdDUChainPrivate->cleanupMutex());
 
-    {
-        //Acquire write-lock of the repository, so when kdevelop crashes in that process, the repository is discarded
-        //Crashes here may happen in an inconsistent state, thus this makes sense, to protect the user from more crashes
-        globalItemRepositoryRegistry().lockForWriting();
-        sdDUChainPrivate->cleanupTopContexts();
-        globalItemRepositoryRegistry().unlockForWriting();
-    }
-
     sdDUChainPrivate->doMoreCleanup(); //Must be done _before_ finalCleanup, else we may be deleting yet needed data
 
     sdDUChainPrivate->m_openDocumentContexts.clear();
diff --git a/kdevplatform/language/duchain/duchainprivate.cpp b/kdevplatform/language/duchain/duchainprivate.cpp
index 82886ccf5d..2dc0de55d1 100644
--- a/kdevplatform/language/duchain/duchainprivate.cpp
+++ b/kdevplatform/language/duchain/duchainprivate.cpp
@@ -744,94 +744,6 @@ unloadContexts:
         return ret;
     }
 
-    struct CleanupListVisitor
-    {
-        QList<uint> checkContexts;
-        bool operator()(const EnvironmentInformationItem* item)
-        {
-            checkContexts << item->m_topContext;
-            return true;
-        }
-    };
-
-    ///Will check a selection of all top-contexts for up-to-date ness, and remove them if out of date
-    void DUChainPrivate::cleanupTopContexts()
-    {
-        DUChainWriteLocker lock(DUChain::lock());
-        qCDebug(LANGUAGE) << "cleaning top-contexts";
-        CleanupListVisitor visitor;
-        uint startPos = 0;
-        LockedItemRepository::write<EnvironmentInformation>([&visitor](EnvironmentInformationRepo& repo) {
-            repo.visitAllItems(visitor);
-        });
-
-        int checkContextsCount = maxFinalCleanupCheckContexts;
-        int percentageOfContexts = (visitor.checkContexts.size() * 100) / minimumFinalCleanupCheckContextsPercentage;
-
-        if (checkContextsCount < percentageOfContexts)
-            checkContextsCount = percentageOfContexts;
-
-        if (visitor.checkContexts.size() > (int)checkContextsCount)
-            startPos = QRandomGenerator::global()->bounded(visitor.checkContexts.size() - checkContextsCount);
-
-        int endPos = startPos + maxFinalCleanupCheckContexts;
-        if (endPos > visitor.checkContexts.size())
-            endPos = visitor.checkContexts.size();
-        QSet<uint> check;
-        for (int a = startPos; a < endPos && check.size() < checkContextsCount; ++a)
-            if (check.size() < checkContextsCount)
-                addContextsForRemoval(check, IndexedTopDUContext(visitor.checkContexts[a]));
-
-        for (uint topIndex : std::as_const(check)) {
-            IndexedTopDUContext top(topIndex);
-            if (top.data()) {
-                qCDebug(LANGUAGE) << "removing top-context for" << top.data()->url().str() <<
-                    "because it is out of date";
-                instance->removeDocumentChain(top.data());
-            }
-        }
-
-        qCDebug(LANGUAGE) << "check ready";
-    }
-
-    void DUChainPrivate::addContextsForRemoval(QSet<uint>& topContexts, IndexedTopDUContext top)
-    {
-        if (topContexts.contains(top.index()))
-            return;
-
-        QExplicitlySharedDataPointer<ParsingEnvironmentFile> info(instance->environmentFileForDocument(top));
-        ///@todo Also check if the context is "useful"(Not a duplicate context, imported by a useful one, ...)
-        if (info && info->needsUpdate()) {
-            //This context will be removed
-        } else {
-            return;
-        }
-
-        topContexts.insert(top.index());
-
-        if (info) {
-            //Check whether importers need to be removed as well
-            const QList<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> importers = info->importers();
-
-            QSet<QExplicitlySharedDataPointer<ParsingEnvironmentFile>> checkNext;
-
-            //Do breadth first search, so less imports/importers have to be loaded, and a lower depth is reached
-
-            for (auto& importer : importers) {
-                IndexedTopDUContext c = importer->indexedTopContext();
-                // Prevent useless recursion
-                if (Algorithm::insert(topContexts, c.index()).inserted) {
-                    checkNext.insert(importer);
-                }
-            }
-
-            for (auto& parsingEnvFile : std::as_const(checkNext)) {
-                topContexts.remove(parsingEnvFile->indexedTopContext().index()); // Enable full check again
-                addContextsForRemoval(topContexts, parsingEnvFile->indexedTopContext());
-            }
-        }
-    }
-
     ///Stores the environment-information for the given url
     void DUChainPrivate::storeInformationList(const IndexedString& url)
     {
diff --git a/kdevplatform/language/duchain/duchainprivate.h b/kdevplatform/language/duchain/duchainprivate.h
index ef5a9f0e9d..13dcd1aead 100644
--- a/kdevplatform/language/duchain/duchainprivate.h
+++ b/kdevplatform/language/duchain/duchainprivate.h
@@ -67,10 +67,6 @@ const int SOFT_CLEANUP_STEPS = 1;
 
 // seconds to wait before trying to cleanup the DUChain
 const uint cleanupEverySeconds = 200;
-
-///Approximate maximum count of top-contexts that are checked during final cleanup
-const uint maxFinalCleanupCheckContexts = 2000;
-const uint minimumFinalCleanupCheckContextsPercentage = 10; //Check at least n% of all top-contexts during cleanup
 }
 
 namespace KDevelop {
@@ -462,13 +458,8 @@ public:
     ///@warning no other mutexes should be locked, as that may lead to a dedalock
     ParsingEnvironmentFile* loadInformation(uint topContextIndex);
 
-    ///Will check a selection of all top-contexts for up-to-date ness, and remove them if out of date
-    void cleanupTopContexts();
-
 private:
 
-    void addContextsForRemoval(QSet<uint>& topContexts, IndexedTopDUContext top);
-
     ///Stores the environment-information for the given url
     void storeInformationList(const IndexedString& url);
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.