Utils: Promote CppEditor::StringTable

It's useful on a more general level, and it's only useful as
real singleton.

Change-Id: I1da38a8eb6f9332a36261288d1b088ca6204eb7a
Reviewed-by: Jarek Kobus <jaroslaw.kobus@qt.io>
This commit is contained in:
hjk
2022-12-02 16:18:02 +01:00
parent 9d5d350f8f
commit 7a02b39f26
10 changed files with 69 additions and 79 deletions

View File

@@ -156,6 +156,7 @@ add_qtc_library(Utils
sortfiltermodel.h sortfiltermodel.h
span.h span.h
statuslabel.cpp statuslabel.h statuslabel.cpp statuslabel.h
stringtable.cpp stringtable.h
stringutils.cpp stringutils.h stringutils.cpp stringutils.h
styledbar.cpp styledbar.h styledbar.cpp styledbar.h
stylehelper.cpp stylehelper.h stylehelper.cpp stylehelper.h

View File

@@ -3,28 +3,27 @@
#include "stringtable.h" #include "stringtable.h"
#include <utils/qtcassert.h> #include "runextensions.h"
#include <utils/runextensions.h>
#include <QDebug> #include <QDebug>
#include <QElapsedTimer> #include <QElapsedTimer>
#include <QMutex> #include <QMutex>
#include <QSet> #include <QSet>
#include <QThreadPool>
#include <QTimer> #include <QTimer>
#ifdef WITH_TESTS // FIXME: Re-create in better location?
#include <extensionsystem/pluginmanager.h> //#ifdef WITH_TESTS
#endif //#include <extensionsystem/pluginmanager.h>
//#endif
namespace CppEditor::Internal { namespace Utils::StringTable {
enum { enum {
GCTimeOut = 10 * 1000 // 10 seconds GCTimeOut = 10 * 1000 // 10 seconds
}; };
enum { enum {
DebugStringTable = 0 DebugStringTable = 1
}; };
class StringTablePrivate : public QObject class StringTablePrivate : public QObject
@@ -44,7 +43,11 @@ public:
QTimer m_gcCountDown; QTimer m_gcCountDown;
}; };
static StringTablePrivate *m_instance = nullptr; static StringTablePrivate &stringTable()
{
static StringTablePrivate theStringTable;
return theStringTable;
}
StringTablePrivate::StringTablePrivate() StringTablePrivate::StringTablePrivate()
{ {
@@ -56,14 +59,9 @@ StringTablePrivate::StringTablePrivate()
connect(&m_gcCountDown, &QTimer::timeout, this, &StringTablePrivate::startGC); connect(&m_gcCountDown, &QTimer::timeout, this, &StringTablePrivate::startGC);
} }
QString StringTable::insert(const Utils::FilePath &path) QTCREATOR_UTILS_EXPORT QString insert(const QString &string)
{ {
return m_instance->insert(path.path()); return stringTable().insert(string);
}
QString StringTable::insert(const QString &string)
{
return m_instance->insert(string);
} }
void StringTablePrivate::cancelAndWait() void StringTablePrivate::cancelAndWait()
@@ -96,39 +94,37 @@ void StringTablePrivate::startGC()
m_future = Utils::runAsync(&StringTablePrivate::GC, this); m_future = Utils::runAsync(&StringTablePrivate::GC, this);
} }
void StringTable::scheduleGC() QTCREATOR_UTILS_EXPORT void scheduleGC()
{ {
QMetaObject::invokeMethod(&m_instance->m_gcCountDown, QOverload<>::of(&QTimer::start), QMetaObject::invokeMethod(&stringTable().m_gcCountDown, QOverload<>::of(&QTimer::start),
Qt::QueuedConnection); Qt::QueuedConnection);
} }
StringTable::StringTable() static int bytesSaved = 0;
{
m_instance = new StringTablePrivate;
}
StringTable::~StringTable()
{
delete m_instance;
m_instance = nullptr;
}
static inline bool isQStringInUse(const QString &string) static inline bool isQStringInUse(const QString &string)
{ {
auto data_ptr = const_cast<QString&>(string).data_ptr(); QStringPrivate data_ptr = const_cast<QString&>(string).data_ptr();
if (DebugStringTable) {
const int ref = data_ptr->d_ptr()->ref_;
bytesSaved += (ref - 1) * string.size();
if (ref > 10)
qDebug() << ref << string.size() << string.left(50);
}
return data_ptr->isShared() || !data_ptr->isMutable() /* QStringLiteral ? */; return data_ptr->isShared() || !data_ptr->isMutable() /* QStringLiteral ? */;
} }
void StringTablePrivate::GC(QFutureInterface<void> &futureInterface) void StringTablePrivate::GC(QFutureInterface<void> &futureInterface)
{ {
#ifdef WITH_TESTS //#ifdef WITH_TESTS
if (ExtensionSystem::PluginManager::isScenarioRunning("TestStringTable")) { // if (ExtensionSystem::PluginManager::isScenarioRunning("TestStringTable")) {
if (ExtensionSystem::PluginManager::finishScenario()) // if (ExtensionSystem::PluginManager::finishScenario())
QThread::sleep(5); // QThread::sleep(5);
} // }
#endif //#endif
int initialSize = 0; int initialSize = 0;
bytesSaved = 0;
QElapsedTimer timer; QElapsedTimer timer;
if (DebugStringTable) { if (DebugStringTable) {
initialSize = m_strings.size(); initialSize = m_strings.size();
@@ -149,8 +145,9 @@ void StringTablePrivate::GC(QFutureInterface<void> &futureInterface)
if (DebugStringTable) { if (DebugStringTable) {
const int currentSize = m_strings.size(); const int currentSize = m_strings.size();
qDebug() << "StringTable::GC removed" << initialSize - currentSize qDebug() << "StringTable::GC removed" << initialSize - currentSize
<< "strings in" << timer.elapsed() << "ms, size is now" << currentSize; << "strings in" << timer.elapsed() << "ms, size is now" << currentSize
<< "saved: " << bytesSaved << "bytes";
} }
} }
} // CppEditor::Internal } // Utils::StringTable

View File

@@ -0,0 +1,13 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include <utils/utils_global.h>
namespace Utils::StringTable {
QTCREATOR_UTILS_EXPORT QString insert(const QString &string);
QTCREATOR_UTILS_EXPORT void scheduleGC();
} // Utils::StringTable

View File

@@ -287,6 +287,8 @@ Project {
"../3rdparty/span/span.hpp", "../3rdparty/span/span.hpp",
"statuslabel.cpp", "statuslabel.cpp",
"statuslabel.h", "statuslabel.h",
"stringtable.cpp",
"stringtable.h",
"stringutils.cpp", "stringutils.cpp",
"stringutils.h", "stringutils.h",
"styledbar.cpp", "styledbar.cpp",

View File

@@ -109,7 +109,6 @@ add_qtc_plugin(CppEditor
searchsymbols.cpp searchsymbols.h searchsymbols.cpp searchsymbols.h
semantichighlighter.cpp semantichighlighter.h semantichighlighter.cpp semantichighlighter.h
senddocumenttracker.cpp senddocumenttracker.h senddocumenttracker.cpp senddocumenttracker.h
stringtable.cpp stringtable.h
symbolfinder.cpp symbolfinder.h symbolfinder.cpp symbolfinder.h
symbolsfindfilter.cpp symbolsfindfilter.h symbolsfindfilter.cpp symbolsfindfilter.h
typehierarchybuilder.cpp typehierarchybuilder.h typehierarchybuilder.cpp typehierarchybuilder.h

View File

@@ -229,8 +229,6 @@ QtcPlugin {
"semantichighlighter.h", "semantichighlighter.h",
"senddocumenttracker.cpp", "senddocumenttracker.cpp",
"senddocumenttracker.h", "senddocumenttracker.h",
"stringtable.cpp",
"stringtable.h",
"symbolfinder.cpp", "symbolfinder.cpp",
"symbolfinder.h", "symbolfinder.h",
"symbolsfindfilter.cpp", "symbolsfindfilter.cpp",

View File

@@ -27,7 +27,6 @@
#include "cpptypehierarchy.h" #include "cpptypehierarchy.h"
#include "projectinfo.h" #include "projectinfo.h"
#include "resourcepreviewhoverhandler.h" #include "resourcepreviewhoverhandler.h"
#include "stringtable.h"
#ifdef WITH_TESTS #ifdef WITH_TESTS
#include "compileroptionsbuilder_test.h" #include "compileroptionsbuilder_test.h"
@@ -87,6 +86,7 @@
#include <utils/macroexpander.h> #include <utils/macroexpander.h>
#include <utils/mimeutils.h> #include <utils/mimeutils.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/stringtable.h>
#include <utils/theme/theme.h> #include <utils/theme/theme.h>
#include <QAction> #include <QAction>
@@ -186,7 +186,6 @@ public:
CppIncludeHierarchyFactory m_cppIncludeHierarchyFactory; CppIncludeHierarchyFactory m_cppIncludeHierarchyFactory;
CppEditorFactory m_cppEditorFactory; CppEditorFactory m_cppEditorFactory;
StringTable stringTable;
CppModelManager modelManager; CppModelManager modelManager;
CppCodeModelSettings m_codeModelSettings; CppCodeModelSettings m_codeModelSettings;
CppToolsSettings settings; CppToolsSettings settings;

View File

@@ -3,7 +3,9 @@
#include "cpplocatordata.h" #include "cpplocatordata.h"
#include "stringtable.h" #include <utils/stringtable.h>
using namespace Utils;
namespace CppEditor { namespace CppEditor {
@@ -57,7 +59,7 @@ void CppLocatorData::onAboutToRemoveFiles(const QStringList &files)
} }
} }
Internal::StringTable::scheduleGC(); StringTable::scheduleGC();
flushPendingDocument(false); flushPendingDocument(false);
} }
@@ -70,7 +72,7 @@ void CppLocatorData::flushPendingDocument(bool force) const
return; return;
for (CPlusPlus::Document::Ptr doc : std::as_const(m_pendingDocuments)) for (CPlusPlus::Document::Ptr doc : std::as_const(m_pendingDocuments))
m_infosByFile.insert(Internal::StringTable::insert(doc->filePath()), m_search(doc)); m_infosByFile.insert(StringTable::insert(doc->filePath().toString()), m_search(doc));
m_pendingDocuments.clear(); m_pendingDocuments.clear();
m_pendingDocuments.reserve(MaxPendingDocuments); m_pendingDocuments.reserve(MaxPendingDocuments);

View File

@@ -2,21 +2,23 @@
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0 // SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#include "searchsymbols.h" #include "searchsymbols.h"
#include "stringtable.h"
#include <cplusplus/Icons.h> #include <cplusplus/Icons.h>
#include <cplusplus/LookupContext.h> #include <cplusplus/LookupContext.h>
#include <utils/qtcassert.h> #include <utils/qtcassert.h>
#include <utils/scopedswap.h> #include <utils/scopedswap.h>
#include <utils/stringtable.h>
#include <QDebug> #include <QDebug>
using namespace CPlusPlus; using namespace CPlusPlus;
using namespace Utils;
namespace CppEditor { namespace CppEditor {
using ScopedIndexItemPtr = Utils::ScopedSwap<IndexItem::Ptr>; using ScopedIndexItemPtr = ScopedSwap<IndexItem::Ptr>;
using ScopedScope = Utils::ScopedSwap<QString>; using ScopedScope = ScopedSwap<QString>;
SearchSymbols::SymbolTypes SearchSymbols::AllTypes = SearchSymbols::SymbolTypes SearchSymbols::AllTypes =
SymbolSearcher::Classes SymbolSearcher::Classes
@@ -37,7 +39,7 @@ void SearchSymbols::setSymbolsToSearchFor(const SymbolTypes &types)
IndexItem::Ptr SearchSymbols::operator()(Document::Ptr doc, const QString &scope) IndexItem::Ptr SearchSymbols::operator()(Document::Ptr doc, const QString &scope)
{ {
IndexItem::Ptr root = IndexItem::create(Internal::StringTable::insert(doc->filePath()), 100); IndexItem::Ptr root = IndexItem::create(StringTable::insert(doc->filePath().toString()), 100);
{ // RAII scope { // RAII scope
ScopedIndexItemPtr parentRaii(_parent, root); ScopedIndexItemPtr parentRaii(_parent, root);
@@ -46,13 +48,13 @@ IndexItem::Ptr SearchSymbols::operator()(Document::Ptr doc, const QString &scope
QTC_ASSERT(_parent, return IndexItem::Ptr()); QTC_ASSERT(_parent, return IndexItem::Ptr());
QTC_ASSERT(root, return IndexItem::Ptr()); QTC_ASSERT(root, return IndexItem::Ptr());
QTC_ASSERT(_parent->filePath().toString() == Internal::StringTable::insert(doc->filePath()), QTC_ASSERT(_parent->filePath().toString() == StringTable::insert(doc->filePath().toString()),
return IndexItem::Ptr()); return IndexItem::Ptr());
for (int i = 0, ei = doc->globalSymbolCount(); i != ei; ++i) for (int i = 0, ei = doc->globalSymbolCount(); i != ei; ++i)
accept(doc->globalSymbolAt(i)); accept(doc->globalSymbolAt(i));
Internal::StringTable::scheduleGC(); StringTable::scheduleGC();
m_paths.clear(); m_paths.clear();
} }
@@ -274,13 +276,13 @@ IndexItem::Ptr SearchSymbols::addChildItem(const QString &symbolName, const QStr
m_paths.insert(symbol->fileId(), path); m_paths.insert(symbol->fileId(), path);
} }
const QIcon icon = Icons::iconForSymbol(symbol); const QIcon icon = CPlusPlus::Icons::iconForSymbol(symbol);
IndexItem::Ptr newItem = IndexItem::create(Internal::StringTable::insert(symbolName), IndexItem::Ptr newItem = IndexItem::create(StringTable::insert(symbolName),
Internal::StringTable::insert(symbolType), StringTable::insert(symbolType),
Internal::StringTable::insert(symbolScope), StringTable::insert(symbolScope),
itemType, itemType,
Internal::StringTable::insert(path), StringTable::insert(path),
symbol->line(), symbol->line(),
symbol->column() - 1, // 1-based vs 0-based column symbol->column() - 1, // 1-based vs 0-based column
icon); icon);

View File

@@ -1,23 +0,0 @@
// Copyright (C) 2016 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include <utils/filepath.h>
namespace CppEditor::Internal {
class StringTable
{
public:
static QString insert(const Utils::FilePath &string);
static QString insert(const QString &string);
static void scheduleGC();
private:
friend class CppEditorPluginPrivate;
StringTable();
~StringTable();
};
} // CppEditor::Internal