refactor: use QHash instead of QMap
- use QHash to improve access performance - key use appId instead of objectpath
This commit is contained in:
parent
2cc1515229
commit
60414b5271
@ -77,21 +77,19 @@ void ApplicationManager1Service::initService(QDBusConnection &connection) noexce
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto appIt = std::find_if(m_applicationList.cbegin(),
|
auto app = m_applicationList.value(appId);
|
||||||
m_applicationList.cend(),
|
|
||||||
[&appId](const QSharedPointer<ApplicationService> &app) { return app->id() == appId; });
|
|
||||||
|
|
||||||
if (appIt == m_applicationList.cend()) {
|
if (!app) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// 服务在 AM 之后启动那么 instance size 是 0, newJob 时尝试添加一次
|
// 服务在 AM 之后启动那么 instance size 是 0, newJob 时尝试添加一次
|
||||||
// 比如 dde-file-manager.service 如果启动的比 AM 晚,那么在 scanInstances 时不会 addInstanceToApplication
|
// 比如 dde-file-manager.service 如果启动的比 AM 晚,那么在 scanInstances 时不会 addInstanceToApplication
|
||||||
if ((*appIt)->instances().size() > 0) {
|
if (app->instances().size() > 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
qDebug() << "add Instance " << unitName << "on JobNew";
|
qDebug() << "add Instance " << unitName << "on JobNew, " << app->instances().size();
|
||||||
|
|
||||||
addInstanceToApplication(unitName, systemdUnitPath);
|
addInstanceToApplication(unitName, systemdUnitPath);
|
||||||
});
|
});
|
||||||
@ -225,20 +223,18 @@ void ApplicationManager1Service::addInstanceToApplication(const QString &unitNam
|
|||||||
instanceId = QUuid::createUuid().toString(QUuid::Id128);
|
instanceId = QUuid::createUuid().toString(QUuid::Id128);
|
||||||
}
|
}
|
||||||
|
|
||||||
auto appIt = std::find_if(m_applicationList.cbegin(),
|
auto app = m_applicationList.value(appId);
|
||||||
m_applicationList.cend(),
|
|
||||||
[&appId](const QSharedPointer<ApplicationService> &app) { return app->id() == appId; });
|
|
||||||
|
|
||||||
if (appIt == m_applicationList.cend()) {
|
if (!app) {
|
||||||
qWarning() << "couldn't find app" << appId << "in application manager.";
|
qWarning() << "couldn't find app" << appId << "in application manager.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
(*appIt)->updateAfterLaunch(sender() != nullptr); // activate by signal
|
app->updateAfterLaunch(sender() != nullptr); // activate by signal
|
||||||
|
|
||||||
const auto &applicationPath = (*appIt)->applicationPath().path();
|
const auto &applicationPath = app->applicationPath().path();
|
||||||
|
|
||||||
if (!(*appIt)->addOneInstance(instanceId, applicationPath, systemdUnitPath.path(), launcher)) {
|
if (!app->addOneInstance(instanceId, applicationPath, systemdUnitPath.path(), launcher)) {
|
||||||
qCritical() << "add Instance failed:" << applicationPath << unitName << systemdUnitPath.path();
|
qCritical() << "add Instance failed:" << applicationPath << unitName << systemdUnitPath.path();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -254,16 +250,14 @@ void ApplicationManager1Service::removeInstanceFromApplication(const QString &un
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto appIt = std::find_if(m_applicationList.cbegin(),
|
auto app = m_applicationList.value(appId);
|
||||||
m_applicationList.cend(),
|
|
||||||
[&appId](const QSharedPointer<ApplicationService> &app) { return app->id() == appId; });
|
|
||||||
|
|
||||||
if (appIt == m_applicationList.cend()) {
|
if (!app) {
|
||||||
qWarning() << "couldn't find app" << appId << "in application manager.";
|
qWarning() << "couldn't find app" << appId << "in application manager.";
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const auto &appIns = (*appIt)->applicationInstances();
|
const auto &appIns = app->applicationInstances();
|
||||||
|
|
||||||
auto instanceIt =
|
auto instanceIt =
|
||||||
std::find_if(appIns.cbegin(), appIns.cend(), [&systemdUnitPath](const QSharedPointer<InstanceService> &value) {
|
std::find_if(appIns.cbegin(), appIns.cend(), [&systemdUnitPath](const QSharedPointer<InstanceService> &value) {
|
||||||
@ -271,7 +265,7 @@ void ApplicationManager1Service::removeInstanceFromApplication(const QString &un
|
|||||||
});
|
});
|
||||||
|
|
||||||
if (instanceIt != appIns.cend()) {
|
if (instanceIt != appIns.cend()) {
|
||||||
(*appIt)->removeOneInstance(instanceIt.key());
|
app->removeOneInstance(instanceIt.key());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -440,16 +434,13 @@ QHash<QSharedPointer<ApplicationService>, QString> ApplicationManager1Service::s
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auto appIt = std::find_if(m_applicationList.cbegin(),
|
if (auto existApp = m_applicationList.value(desktopFile.desktopId()); existApp) {
|
||||||
m_applicationList.cend(),
|
|
||||||
[&desktopFile](const auto &app) { return desktopFile.desktopId() == app->id(); });
|
|
||||||
appIt != m_applicationList.cend()) {
|
|
||||||
if (autostartFlag) {
|
if (autostartFlag) {
|
||||||
auto realExec = tmp.value(DesktopFileEntryKey, "Exec").value_or(QString{""}).toString();
|
auto realExec = tmp.value(DesktopFileEntryKey, "Exec").value_or(QString{""}).toString();
|
||||||
qInfo() << "launch exist autostart application " << (*appIt)->id() << " by " << realExec;
|
qInfo() << "launch exist autostart application " << existApp->id() << " by " << realExec;
|
||||||
ret.insert(*appIt, realExec);
|
ret.insert(existApp, realExec);
|
||||||
}
|
}
|
||||||
(*appIt)->setAutostartSource({std::move(originalSource), std::move(tmp)});
|
existApp->setAutostartSource({std::move(originalSource), std::move(tmp)});
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -499,13 +490,16 @@ void ApplicationManager1Service::loadHooks() noexcept
|
|||||||
|
|
||||||
QList<QDBusObjectPath> ApplicationManager1Service::list() const
|
QList<QDBusObjectPath> ApplicationManager1Service::list() const
|
||||||
{
|
{
|
||||||
return m_applicationList.keys();
|
QList<QDBusObjectPath> paths;
|
||||||
|
for (const auto &appId : m_applicationList.keys())
|
||||||
|
paths << QDBusObjectPath{getObjectPathFromAppId(appId)};
|
||||||
|
|
||||||
|
return paths;
|
||||||
}
|
}
|
||||||
|
|
||||||
QSharedPointer<ApplicationService> ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) noexcept
|
QSharedPointer<ApplicationService> ApplicationManager1Service::addApplication(DesktopFile desktopFileSource) noexcept
|
||||||
{
|
{
|
||||||
auto objectPath = QDBusObjectPath{getObjectPathFromAppId(desktopFileSource.desktopId())};
|
if (auto app = m_applicationList.constFind(desktopFileSource.desktopId()); app != m_applicationList.cend()) {
|
||||||
if (auto app = m_applicationList.constFind(objectPath); app != m_applicationList.cend()) {
|
|
||||||
qInfo() << "this application already exists." << "current desktop source:" << desktopFileSource.sourcePath()
|
qInfo() << "this application already exists." << "current desktop source:" << desktopFileSource.sourcePath()
|
||||||
<< "exists app source:" << app->data()->desktopFileSource().sourcePath();
|
<< "exists app source:" << app->data()->desktopFileSource().sourcePath();
|
||||||
return *app;
|
return *app;
|
||||||
@ -528,7 +522,7 @@ QSharedPointer<ApplicationService> ApplicationManager1Service::addApplication(De
|
|||||||
if (!registerObjectToDBus(ptr, application->applicationPath().path(), ApplicationInterface)) {
|
if (!registerObjectToDBus(ptr, application->applicationPath().path(), ApplicationInterface)) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
m_applicationList.insert(application->applicationPath(), application);
|
m_applicationList.insert(application->id(), application);
|
||||||
|
|
||||||
emit listChanged();
|
emit listChanged();
|
||||||
emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr));
|
emit InterfacesAdded(application->applicationPath(), getChildInterfacesAndPropertiesFromObject(ptr));
|
||||||
@ -536,18 +530,18 @@ QSharedPointer<ApplicationService> ApplicationManager1Service::addApplication(De
|
|||||||
return application;
|
return application;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &application) noexcept
|
void ApplicationManager1Service::removeOneApplication(const QString &appId) noexcept
|
||||||
{
|
{
|
||||||
if (auto it = m_applicationList.find(application); it != m_applicationList.cend()) {
|
auto objectPath = QDBusObjectPath{getObjectPathFromAppId(appId)};
|
||||||
emit InterfacesRemoved(application, getChildInterfacesFromObject(it->data()));
|
if (auto it = m_applicationList.find(appId); it != m_applicationList.cend()) {
|
||||||
|
emit InterfacesRemoved(objectPath, getChildInterfacesFromObject(it->data()));
|
||||||
if (auto ptr = m_storage.lock(); ptr) {
|
if (auto ptr = m_storage.lock(); ptr) {
|
||||||
auto appId = (*it)->id();
|
|
||||||
if (!ptr->deleteApplication(appId)) {
|
if (!ptr->deleteApplication(appId)) {
|
||||||
qCritical() << "failed to delete all properties of" << appId;
|
qCritical() << "failed to delete all properties of" << appId;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
unregisterObjectFromDBus(application.path());
|
unregisterObjectFromDBus(objectPath.path());
|
||||||
m_applicationList.remove(application);
|
m_applicationList.remove(appId);
|
||||||
|
|
||||||
emit listChanged();
|
emit listChanged();
|
||||||
}
|
}
|
||||||
@ -555,8 +549,8 @@ void ApplicationManager1Service::removeOneApplication(const QDBusObjectPath &app
|
|||||||
|
|
||||||
void ApplicationManager1Service::removeAllApplication() noexcept
|
void ApplicationManager1Service::removeAllApplication() noexcept
|
||||||
{
|
{
|
||||||
for (const auto &app : m_applicationList.keys()) {
|
for (const auto &appId : m_applicationList.keys()) {
|
||||||
removeOneApplication(app);
|
removeOneApplication(appId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -583,22 +577,19 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf
|
|||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
auto app = std::find_if(m_applicationList.cbegin(), m_applicationList.cend(), [&ret](const auto &appPtr) {
|
if (!m_applicationList.contains(ret.ApplicationId)) {
|
||||||
return appPtr->id() == ret.ApplicationId;
|
|
||||||
});
|
|
||||||
|
|
||||||
if (app == m_applicationList.cend()) {
|
|
||||||
safe_sendErrorReply(QDBusError::Failed, "can't find application:" % ret.ApplicationId);
|
safe_sendErrorReply(QDBusError::Failed, "can't find application:" % ret.ApplicationId);
|
||||||
return {};
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
auto app = m_applicationList.value(ret.ApplicationId);
|
||||||
QDBusObjectPath instancePath;
|
QDBusObjectPath instancePath;
|
||||||
const auto &instances = (*app)->instances();
|
const auto &instances = app->instances();
|
||||||
if (ret.InstanceId.isEmpty() && instances.size() == 1) {
|
if (ret.InstanceId.isEmpty() && instances.size() == 1) {
|
||||||
// Maybe a dbus systemd service
|
// Maybe a dbus systemd service
|
||||||
instancePath = instances.constFirst();
|
instancePath = instances.constFirst();
|
||||||
} else {
|
} else {
|
||||||
instancePath = (*app)->findInstance(ret.InstanceId);
|
instancePath = app->findInstance(ret.InstanceId);
|
||||||
}
|
}
|
||||||
if (instancePath.path().isEmpty()) {
|
if (instancePath.path().isEmpty()) {
|
||||||
safe_sendErrorReply(QDBusError::Failed, "can't find instance:" % ret.InstanceId);
|
safe_sendErrorReply(QDBusError::Failed, "can't find instance:" % ret.InstanceId);
|
||||||
@ -606,7 +597,7 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf
|
|||||||
}
|
}
|
||||||
|
|
||||||
instance = instancePath;
|
instance = instancePath;
|
||||||
auto instanceObj = (*app)->m_Instances.constFind(instance);
|
auto instanceObj = app->m_Instances.constFind(instance);
|
||||||
application_instance_info = getChildInterfacesAndPropertiesFromObject(instanceObj->get());
|
application_instance_info = getChildInterfacesAndPropertiesFromObject(instanceObj->get());
|
||||||
|
|
||||||
return ret.ApplicationId;
|
return ret.ApplicationId;
|
||||||
@ -615,7 +606,7 @@ QString ApplicationManager1Service::Identify(const QDBusUnixFileDescriptor &pidf
|
|||||||
void ApplicationManager1Service::updateApplication(const QSharedPointer<ApplicationService> &destApp,
|
void ApplicationManager1Service::updateApplication(const QSharedPointer<ApplicationService> &destApp,
|
||||||
DesktopFile desktopFile) noexcept
|
DesktopFile desktopFile) noexcept
|
||||||
{
|
{
|
||||||
if (auto app = m_applicationList.find(destApp->applicationPath()); app == m_applicationList.cend()) {
|
if (!m_applicationList.contains(destApp->id())) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -659,11 +650,11 @@ void ApplicationManager1Service::doReloadApplications()
|
|||||||
auto desktopFileDirs = getDesktopFileDirs();
|
auto desktopFileDirs = getDesktopFileDirs();
|
||||||
desktopFileDirs.append(getAutoStartDirs()); // detect autostart apps add/remove/update
|
desktopFileDirs.append(getAutoStartDirs()); // detect autostart apps add/remove/update
|
||||||
|
|
||||||
auto apps = m_applicationList.keys();
|
auto appIds = m_applicationList.keys();
|
||||||
|
|
||||||
applyIteratively(
|
applyIteratively(
|
||||||
QList<QDir>(desktopFileDirs.cbegin(), desktopFileDirs.cend()),
|
QList<QDir>(desktopFileDirs.cbegin(), desktopFileDirs.cend()),
|
||||||
[this, &apps](const QFileInfo &info) -> bool {
|
[this, &appIds](const QFileInfo &info) -> bool {
|
||||||
ParserError err{ParserError::NoError};
|
ParserError err{ParserError::NoError};
|
||||||
auto ret = DesktopFile::searchDesktopFileByPath(info.absoluteFilePath(), err);
|
auto ret = DesktopFile::searchDesktopFileByPath(info.absoluteFilePath(), err);
|
||||||
if (!ret.has_value()) {
|
if (!ret.has_value()) {
|
||||||
@ -672,24 +663,16 @@ void ApplicationManager1Service::doReloadApplications()
|
|||||||
|
|
||||||
auto file = std::move(ret).value();
|
auto file = std::move(ret).value();
|
||||||
|
|
||||||
auto destApp =
|
QSharedPointer<ApplicationService> app = m_applicationList.value(file.desktopId());
|
||||||
std::find_if(m_applicationList.cbegin(),
|
|
||||||
m_applicationList.cend(),
|
|
||||||
[&file](const QSharedPointer<ApplicationService> &app) { return file.desktopId() == app->id(); });
|
|
||||||
|
|
||||||
if (err != ParserError::NoError) {
|
if (app and appIds.contains(app->id())) {
|
||||||
qWarning() << "error occurred:" << err << " skip this application.";
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (destApp != m_applicationList.cend() and apps.contains(destApp.key())) {
|
|
||||||
// Can emit correct remove signal when uninstalling applications
|
// Can emit correct remove signal when uninstalling applications
|
||||||
if (ApplicationFilter::tryExecCheck(*(destApp->data()->m_entry))) {
|
if (ApplicationFilter::tryExecCheck(*(app.data()->m_entry))) {
|
||||||
qDebug() << info.absolutePath() << "Checked TryExec failed and will be removed";
|
qDebug() << info.absolutePath() << "Checked TryExec failed and will be removed";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
apps.removeOne(destApp.key());
|
appIds.removeOne(app->id());
|
||||||
updateApplication(destApp.value(), std::move(file));
|
updateApplication(app, std::move(file));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -700,8 +683,8 @@ void ApplicationManager1Service::doReloadApplications()
|
|||||||
{"*.desktop"},
|
{"*.desktop"},
|
||||||
QDir::Name | QDir::DirsLast);
|
QDir::Name | QDir::DirsLast);
|
||||||
|
|
||||||
for (const auto &key : apps) {
|
for (const auto &appId : appIds) {
|
||||||
removeOneApplication(key);
|
removeOneApplication(appId);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_mimeManager->reset();
|
m_mimeManager->reset();
|
||||||
@ -715,15 +698,13 @@ ObjectMap ApplicationManager1Service::GetManagedObjects() const
|
|||||||
return dumpDBusObject(m_applicationList);
|
return dumpDBusObject(m_applicationList);
|
||||||
}
|
}
|
||||||
|
|
||||||
QMap<QDBusObjectPath, QSharedPointer<ApplicationService>>
|
QHash<QDBusObjectPath, QSharedPointer<ApplicationService>>
|
||||||
ApplicationManager1Service::findApplicationsByIds(const QStringList &appIds) const noexcept
|
ApplicationManager1Service::findApplicationsByIds(const QStringList &appIds) const noexcept
|
||||||
{
|
{
|
||||||
QMap<QDBusObjectPath, QSharedPointer<ApplicationService>> ret;
|
QHash<QDBusObjectPath, QSharedPointer<ApplicationService>> ret;
|
||||||
for (auto it = m_applicationList.constKeyValueBegin(); it != m_applicationList.constKeyValueEnd(); ++it) {
|
for (const auto appId : appIds) {
|
||||||
const auto &ptr = it->second;
|
if (auto app = m_applicationList.value(appId); app)
|
||||||
if (appIds.contains(ptr->id())) {
|
ret.insert(QDBusObjectPath{getObjectPathFromAppId(appId)}, app);
|
||||||
ret.insert(it->first, it->second);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
#include <QScopedPointer>
|
#include <QScopedPointer>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <QMap>
|
#include <QMap>
|
||||||
|
#include <QHash>
|
||||||
#include <QFileSystemWatcher>
|
#include <QFileSystemWatcher>
|
||||||
#include <QTimer>
|
#include <QTimer>
|
||||||
#include "applicationmanagerstorage.h"
|
#include "applicationmanagerstorage.h"
|
||||||
@ -39,9 +40,9 @@ public:
|
|||||||
|
|
||||||
void initService(QDBusConnection &connection) noexcept;
|
void initService(QDBusConnection &connection) noexcept;
|
||||||
QSharedPointer<ApplicationService> addApplication(DesktopFile desktopFileSource) noexcept;
|
QSharedPointer<ApplicationService> addApplication(DesktopFile desktopFileSource) noexcept;
|
||||||
void removeOneApplication(const QDBusObjectPath &application) noexcept;
|
void removeOneApplication(const QString &appId) noexcept;
|
||||||
void removeAllApplication() noexcept;
|
void removeAllApplication() noexcept;
|
||||||
[[nodiscard]] QMap<QDBusObjectPath, QSharedPointer<ApplicationService>>
|
[[nodiscard]] QHash<QDBusObjectPath, QSharedPointer<ApplicationService>>
|
||||||
findApplicationsByIds(const QStringList &appIds) const noexcept;
|
findApplicationsByIds(const QStringList &appIds) const noexcept;
|
||||||
void updateApplication(const QSharedPointer<ApplicationService> &destApp, DesktopFile desktopFile) noexcept;
|
void updateApplication(const QSharedPointer<ApplicationService> &destApp, DesktopFile desktopFile) noexcept;
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ private:
|
|||||||
QStringList m_systemdPathEnv;
|
QStringList m_systemdPathEnv;
|
||||||
QFileSystemWatcher m_watcher;
|
QFileSystemWatcher m_watcher;
|
||||||
QTimer m_reloadTimer;
|
QTimer m_reloadTimer;
|
||||||
QMap<QDBusObjectPath, QSharedPointer<ApplicationService>> m_applicationList;
|
QHash<QString, QSharedPointer<ApplicationService>> m_applicationList;
|
||||||
|
|
||||||
void scanMimeInfos() noexcept;
|
void scanMimeInfos() noexcept;
|
||||||
void scanApplications() noexcept;
|
void scanApplications() noexcept;
|
||||||
|
14
src/global.h
14
src/global.h
@ -554,6 +554,20 @@ ObjectMap dumpDBusObject(const QMap<QDBusObjectPath, QSharedPointer<T>> &map)
|
|||||||
return objs;
|
return objs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
ObjectMap dumpDBusObject(const QHash<QString, QSharedPointer<T>> &map)
|
||||||
|
{
|
||||||
|
ObjectMap objs;
|
||||||
|
|
||||||
|
for (auto it = map.constKeyValueBegin(); it != map.constKeyValueEnd(); ++it) {
|
||||||
|
const auto &[key, value] = *it;
|
||||||
|
auto interAndProps = getChildInterfacesAndPropertiesFromObject(value.data());
|
||||||
|
objs.insert(QDBusObjectPath{getObjectPathFromAppId(key)}, interAndProps);
|
||||||
|
}
|
||||||
|
|
||||||
|
return objs;
|
||||||
|
}
|
||||||
|
|
||||||
struct FileTimeInfo
|
struct FileTimeInfo
|
||||||
{
|
{
|
||||||
qint64 mtime;
|
qint64 mtime;
|
||||||
|
@ -44,7 +44,7 @@ bool SystemdSignalDispatcher::connectToSignals() noexcept
|
|||||||
"JobNew",
|
"JobNew",
|
||||||
this,
|
this,
|
||||||
SLOT(onJobNew(uint32_t, QDBusObjectPath, QString)))) {
|
SLOT(onJobNew(uint32_t, QDBusObjectPath, QString)))) {
|
||||||
qCritical() << "can't connect to UnitNew signal of systemd service.";
|
qCritical() << "can't connect to JobNew signal of systemd service.";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user