优化非转码业务查询链路性能
This commit is contained in:
@@ -706,34 +706,49 @@ void CodeSearchPage::autoBuildIndexIfNeeded()
|
||||
CallChainAnalyzer *ca = currentAnalyzer();
|
||||
ca->setRootPath(path);
|
||||
|
||||
// 1) 优先从磁盘缓存读取(程序重启 / 页面切换时秒开,无需重新扫描目录)
|
||||
QString message;
|
||||
if (ca->loadFromCache(path, &message)) {
|
||||
m_indexedPathByMode[m_mode] = path;
|
||||
LogManager::instance()->log(QString("[代码检索-缓存] %1").arg(message));
|
||||
return;
|
||||
}
|
||||
// 统一的“全量构建/重建”流程:后台线程扫描目录,避免界面卡死;
|
||||
// 构建完成后写入缓存,供下次直接读取。
|
||||
auto fullBuild = [this, path]() {
|
||||
m_indexing = true;
|
||||
runIndexBuild(currentAnalyzer(), "正在构建代码索引,请稍候...",
|
||||
[this, path](bool ok, const QString &message) {
|
||||
m_indexing = false;
|
||||
if (ok) {
|
||||
currentAnalyzer()->saveToCache();
|
||||
m_indexedPathByMode[m_mode] = path;
|
||||
LogManager::instance()->log(QString("[代码检索-自动] %1").arg(message));
|
||||
} else {
|
||||
m_indexedPathByMode[m_mode] = path; // 标记已尝试,避免每次显示重复重试
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
// 2) 缓存不存在或已失效:后台线程扫描目录构建索引,期间显示进度框,避免界面卡死;
|
||||
// 构建完成后写入缓存,供下次直接读取。
|
||||
m_indexing = true;
|
||||
runIndexBuild(ca, "正在构建代码索引,请稍候...",
|
||||
[this, path](bool ok, const QString &message) {
|
||||
m_indexing = false;
|
||||
if (ok) {
|
||||
currentAnalyzer()->saveToCache();
|
||||
m_indexedPathByMode[m_mode] = path;
|
||||
LogManager::instance()->log(QString("[代码检索-自动] %1").arg(message));
|
||||
} else {
|
||||
m_indexedPathByMode[m_mode] = path; // 标记已尝试,避免每次显示重复重试
|
||||
}
|
||||
});
|
||||
// 二级加速(方案②):仅 stat root 直接子项做快速粗判(毫秒级、主线程),
|
||||
// 命中则后台直接读缓存;未命中再后台做全量指纹校验+构建(方案①,不阻塞 UI)。
|
||||
if (ca->cacheQuickValid(path)) {
|
||||
m_indexing = true;
|
||||
runCacheLoad(ca, "正在加载索引缓存,请稍候...", /*skipFingerprint=*/true,
|
||||
[this, path, fullBuild](bool ok, const QString &message) {
|
||||
m_indexing = false;
|
||||
if (ok) {
|
||||
m_indexedPathByMode[m_mode] = path;
|
||||
LogManager::instance()->log(QString("[代码检索-缓存] %1").arg(message));
|
||||
} else {
|
||||
// 粗判命中但读缓存失败(极少见,如缓存损坏):回退全量构建
|
||||
m_indexedPathByMode[m_mode] = path; // 标记已尝试
|
||||
fullBuild();
|
||||
}
|
||||
});
|
||||
} else {
|
||||
fullBuild();
|
||||
}
|
||||
}
|
||||
|
||||
void CodeSearchPage::runIndexBuild(CallChainAnalyzer *ca, const QString &title,
|
||||
std::function<void(bool, const QString &)> onDone)
|
||||
void CodeSearchPage::runAsync(CallChainAnalyzer *ca, const QString &title,
|
||||
std::function<QPair<bool, QString>(CallChainAnalyzer *)> task,
|
||||
std::function<void(bool, const QString &)> onDone)
|
||||
{
|
||||
// 模态进度框(不确定进度),后台构建期间维持界面响应
|
||||
// 模态进度框(不确定进度),后台任务期间维持界面响应
|
||||
auto *dlg = new QProgressDialog(title, QString(), 0, 0, this);
|
||||
dlg->setWindowTitle("请稍候");
|
||||
dlg->setWindowModality(Qt::WindowModal);
|
||||
@@ -754,13 +769,31 @@ void CodeSearchPage::runIndexBuild(CallChainAnalyzer *ca, const QString &title,
|
||||
}
|
||||
});
|
||||
|
||||
// 在后台线程执行实际扫描,避免阻塞 UI 线程
|
||||
// 在后台线程执行实际任务,避免阻塞 UI 线程
|
||||
auto future = QtConcurrent::run([=]() -> BuildResult {
|
||||
return task(ca);
|
||||
});
|
||||
watcher->setFuture(future);
|
||||
}
|
||||
|
||||
void CodeSearchPage::runIndexBuild(CallChainAnalyzer *ca, const QString &title,
|
||||
std::function<void(bool, const QString &)> onDone)
|
||||
{
|
||||
runAsync(ca, title, [](CallChainAnalyzer *ca) -> QPair<bool, QString> {
|
||||
QString msg;
|
||||
const bool ok = ca->buildIndex(&msg);
|
||||
return {ok, msg};
|
||||
});
|
||||
watcher->setFuture(future);
|
||||
}, onDone);
|
||||
}
|
||||
|
||||
void CodeSearchPage::runCacheLoad(CallChainAnalyzer *ca, const QString &title, bool skipFingerprint,
|
||||
std::function<void(bool, const QString &)> onDone)
|
||||
{
|
||||
runAsync(ca, title, [skipFingerprint](CallChainAnalyzer *ca) -> QPair<bool, QString> {
|
||||
QString msg;
|
||||
const bool ok = ca->loadFromCache(ca->rootPath(), &msg, skipFingerprint);
|
||||
return {ok, msg};
|
||||
}, onDone);
|
||||
}
|
||||
|
||||
void CodeSearchPage::onQueryByInput()
|
||||
|
||||
@@ -89,9 +89,16 @@ private:
|
||||
void applyMode();
|
||||
CallChainAnalyzer *currentAnalyzer() const;
|
||||
|
||||
/// 后台线程异步构建索引(避免界面卡顿),构建期间显示进度框;完成后回调 onDone(ok, message)
|
||||
/// 后台线程异步执行索引任务(避免界面卡顿),期间显示模态进度框;完成后回调 onDone(ok, message)
|
||||
void runAsync(CallChainAnalyzer *ca, const QString &title,
|
||||
std::function<QPair<bool, QString>(CallChainAnalyzer *)> task,
|
||||
std::function<void(bool, const QString &)> onDone);
|
||||
/// 后台线程异步构建索引(扫描目录),完成后回调 onDone
|
||||
void runIndexBuild(CallChainAnalyzer *ca, const QString &title,
|
||||
std::function<void(bool, const QString &)> onDone);
|
||||
/// 后台线程异步从缓存加载索引;skipFingerprint 为 true 时跳过全量目录指纹校验
|
||||
void runCacheLoad(CallChainAnalyzer *ca, const QString &title, bool skipFingerprint,
|
||||
std::function<void(bool, const QString &)> onDone);
|
||||
|
||||
Mode m_mode = ConvertMode;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user