Skip to content

fix: fix override path matching in reload hotloading#143

Merged
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master
Mar 24, 2026
Merged

fix: fix override path matching in reload hotloading#143
18202781743 merged 1 commit into
linuxdeepin:masterfrom
18202781743:master

Conversation

@18202781743
Copy link
Copy Markdown
Contributor

@18202781743 18202781743 commented Feb 24, 2026

The issue was that during hot reload operations, override configuration
paths were being incorrectly matched by the getMetaConfigureId function
instead of being handled by getOverrideConfigureId. This caused override
configurations to fail during reload operations.

The fix modifies the regular expression in getMetaConfigureId to exclude
override paths using negative lookahead (?!overrides/). This ensures
that override paths are properly routed to getOverrideConfigureId for
correct processing. Additionally, the getConfigureIdByPath function was
updated to not check for file existence before parsing, as files may not
exist during deletion operations but still need path parsing.

Log: Fixed hot reload functionality for override configuration paths

Influence:

  1. Test hot reload functionality with override configurations
  2. Verify that override paths are correctly identified and processed
  3. Test configuration deletion and reload scenarios
  4. Validate both standard and override configuration paths work
    correctly
  5. Test edge cases with special characters in configuration paths

fix: 修复热加载中覆盖路径匹配问题

问题在于热重载操作期间,覆盖配置路径被 getMetaConfigureId 函数错误匹配,
而不是由 getOverrideConfigureId 处理。这导致覆盖配置在重载操作期间失效。

修复方案修改了 getMetaConfigureId 中的正则表达式,使用负向先
行断言 (?!overrides/) 排除覆盖路径。这确保覆盖路径能正确路由到
getOverrideConfigureId 进行处理。此外,更新了 getConfigureIdByPath 函
数,使其在解析前不检查文件是否存在,因为在删除操作期间文件可能不存在但仍
需要路径解析。

Log: 修复了覆盖配置路径的热重载功能

Influence:

  1. 测试覆盖配置的热重载功能
  2. 验证覆盖路径是否正确识别和处理
  3. 测试配置删除和重载场景
  4. 验证标准和覆盖配置路径都能正常工作
  5. 测试包含特殊字符的配置路径边界情况

@18202781743 18202781743 requested review from BLumia and mhduiy February 24, 2026 10:22
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Feb 24, 2026

Reviewer's Guide

Replaces static helper functions in helper.hpp with inline to fix multiple-definition linker warnings, updates debug log format specifiers to use %lld for qint64-sized counts, and adjusts range-based for loops to iterate QString and user-info elements by const & instead of by value to avoid copies and related warnings, all without changing observable behavior.

File-Level Changes

Change Details Files
Convert header-only helper functions from static to inline to avoid multiple definition warnings while preserving behavior.
  • Change all free helper functions in the header from static to inline so they can be defined in a single common header without violating the one-definition rule.
  • Ensure helper functions that are used across translation units (e.g., for applications, resources, translation dirs, user info, QVariant/JSON conversions) now have inline linkage semantics instead of per-TU internal linkage.
  • Retain signatures, defaults, and internal logic of all helpers unchanged to minimize behavioral risk.
dconfig-center/common/helper.hpp
Fix type-mismatched debug logging format strings for container size / count values that are effectively qint64.
  • Update qCInfo, qCDebug, and qDebug calls to use %lld instead of %d for container size/count values to match qint64-sized arguments and silence format warnings.
  • Keep the surrounding log messages and arguments identical apart from the format specifier change.
dconfig-center/dde-dconfig-daemon/dconfigserver.cpp
dconfig-center/dde-dconfig-daemon/dconfigresource.cpp
dconfig-center/dde-dconfig-daemon/dconfigrefmanager.cpp
Use const references instead of by-value copies in range-based for loops to avoid unnecessary QString and pair copying.
  • Change range-based for loops over QStringList and user info collections to iterate with const auto & instead of const auto to avoid implicit copies and improve performance.
  • Ensure loop body logic remains the same, only the iteration variable declaration changes.
dconfig-center/dde-dconfig-daemon/dconfigserver.cpp
dconfig-center/dde-dconfig-editor/mainwindow.cpp

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码变更主要包含两个方面的改进:将头文件中的静态函数改为内联函数,以及优化日志输出格式和循环变量引用。以下是对这些变更的详细审查和改进建议:

1. 头文件函数内联化 (helper.hpp)

变更内容
helper.hpp 中的多个 static 函数改为 inline 函数。

审查意见

  • 语法逻辑:修改是正确的。在头文件中定义非成员函数时,为了避免多重定义错误(ODR violation),必须使用 inline 关键字。之前的 static 虽然也能避免链接错误(因为每个编译单元都有独立副本),但会增加代码体积。inline 是更规范的做法。
  • 代码质量:提高了代码质量。这符合 C++ 的最佳实践,减少了潜在的符号冲突,并且允许编译器在跨编译单元时进行更好的优化。
  • 代码性能:理论上可能略微提升性能或减少二进制体积。static 会导致每个包含该头文件的 .o 文件都生成一份函数副本。inline 允许链接器合并相同的函数实现,或者直接内联展开,减少指令缓存压力。
  • 代码安全:无直接影响。

改进建议

  • 建议:既然这些函数都在头文件中,且逻辑相对简单,除了 inline 外,可以考虑将其放入匿名命名空间(namespace { ... })中,或者在命名空间内部定义为 inline,以进一步限制作用域。但目前的改动已经足够好。

2. 日志格式化字符串修正 (dconfigrefmanager.cpp, dconfigresource.cpp, dconfigserver.cpp)

变更内容
qDebug / qCDebug / qCInfo 中的格式化占位符从 %d 修改为 %lld,用于打印 count()size() 的返回值。

审查意见

  • 语法逻辑:修改是必要的。在 Qt 中,QList::count()QList::size() 返回 int 类型(在 32 位和 64 位平台上通常都是 32 位有符号整数)。然而,使用 %lld(long long)通常是为了防止在某些平台上 size_tqsizetype(Qt 6 中容器大小返回的类型)是 64 位时的截断问题,或者是为了统一格式。
    • 注意:如果这是 Qt 5 项目,count() 返回 int%d 其实是正确的,%lld 会进行隐式转换。如果是 Qt 6,count() 返回 qsizetype(通常是 ptrdiff_t 的别名,64 位系统上为 64 位),则必须使用 %zdqptrdiff 对应的格式,或者强制转换。使用 %lld 配合 static_cast<long long>(...) 是一种兼容性较好的写法。
    • 代码中直接传入了 count(),如果编译器对格式化字符串检查严格(如 -Wformat),且 int 不是 long long,可能会产生警告。
  • 代码质量:提高了代码的健壮性,防止在大数据量下日志输出错误或截断。
  • 代码性能:无影响。
  • 代码安全:无影响。

改进建议

  • 建议:为了更严谨,建议显式进行类型转换,例如:
    qCDebug(cfLog, "... count:%lld ...", static_cast<long long>(request.data.count()));
    或者使用 Qt 提供的类型安全的打印方式(如果项目使用的 Qt 版本支持),避免使用 C 风格的格式化字符串。

3. 循环变量改为常量引用 (dconfigserver.cpp, mainwindow.cpp)

变更内容
for (const auto item : ...) 修改为 for (const auto &item : ...)

审查意见

  • 语法逻辑:修改正确且推荐。
  • 代码质量:显著提升。当 item 是非基本类型(如 QString, UserInfo 等)时,按值传递会在每次循环迭代时调用拷贝构造函数,造成不必要的内存分配和复制。使用 const auto & 避免了拷贝,仅增加引用的开销。
  • 代码性能:提升性能。减少了栈内存的分配和对象复制的 CPU 开销。
  • 代码安全:无直接影响。

改进建议

  • 无,这是现代 C++ 的最佳实践。

总结

这份代码变更整体质量很高,主要是针对 C++ 最佳实践 的修正:

  1. 头文件内联化:正确解决了头文件中定义函数的链接问题,优于 static
  2. 日志格式化:增强了代码在处理大容量数据时的日志准确性(尽管建议配合显式类型转换使用更佳)。
  3. 引用传递:优化了性能,避免了不必要的对象拷贝。

最终评价Approve。这些改进有助于提高程序的维护性、性能和健壮性。

Copy link
Copy Markdown

@sourcery-ai sourcery-ai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 3 issues, and left some high level feedback:

  • For the logging changes that switch %d to %lld, the container size()/count() methods typically return int or qsizetype rather than long long, so consider casting to long long (e.g. static_cast<long long>(keys.size())) or using a format specifier that matches the actual type to avoid UB and keep format/argument alignment strict.
  • In loadTranslation, the range-based loop still uses for (auto item : translationDirs()), which copies each QString; consider making this consistent with the other changes by using for (const auto &item : translationDirs()) to avoid unnecessary copies.
  • Changing static functions in a header to plain inline alters their linkage; if these helpers are intended to remain TU-local or to avoid any risk of ODR issues, consider whether static inline or keeping them in an anonymous namespace would better match the original intent while still resolving the linker warnings.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- For the logging changes that switch `%d` to `%lld`, the container `size()`/`count()` methods typically return `int` or `qsizetype` rather than `long long`, so consider casting to `long long` (e.g. `static_cast<long long>(keys.size())`) or using a format specifier that matches the actual type to avoid UB and keep format/argument alignment strict.
- In `loadTranslation`, the range-based loop still uses `for (auto item : translationDirs())`, which copies each `QString`; consider making this consistent with the other changes by using `for (const auto &item : translationDirs())` to avoid unnecessary copies.
- Changing `static` functions in a header to plain `inline` alters their linkage; if these helpers are intended to remain TU-local or to avoid any risk of ODR issues, consider whether `static inline` or keeping them in an anonymous namespace would better match the original intent while still resolving the linker warnings.

## Individual Comments

### Comment 1
<location path="dconfig-center/dde-dconfig-daemon/dconfigserver.cpp" line_range="360" />
<code_context>
 {
     const QList<ConfigCacheKey> &keys = request.data;
-    qCInfo(cfLog, "Do sync config cache, keys count:%d", keys.size());
+    qCInfo(cfLog, "Do sync config cache, keys count:%lld", keys.size());
     for (auto key: keys) {
         auto resourceKey = getResourceKeyByConfigCache(key);
</code_context>
<issue_to_address>
**issue (bug_risk):** The `%lld` format specifier likely mismatches the type of `keys.size()`.

`QList::size()` / `count()` returns `int` (Qt5) or `qsizetype` (Qt6), neither of which is guaranteed to be `long long`, so `%lld` is technically UB even if it seems to work. Please either:

- keep `%d` and cast to `int` if the size is known to fit, or
- cast to `long long` and keep `%lld`, or
- use `%zd` with a cast to `size_t` / `qsizetype`.

The format specifier should match the actual argument type.
</issue_to_address>

### Comment 2
<location path="dconfig-center/dde-dconfig-daemon/dconfigresource.cpp" line_range="443" />
<code_context>
     }

-    qDebug(cfLog, "Removed connection:%s, remaining %d connection.", qPrintable(connKey), m_conns.count());
+    qDebug(cfLog, "Removed connection:%s, remaining %lld connection.", qPrintable(connKey), m_conns.count());
 }

</code_context>
<issue_to_address>
**issue (bug_risk):** `%lld` may not match the type returned by `m_conns.count()`.

`m_conns.count()` is `int` (Qt5) or `qsizetype` (Qt6), which may not be `long long`, so using `%lld` without a cast is technically UB. Please either use `%d` to match `int` or explicitly cast to `long long`, e.g. `static_cast<long long>(m_conns.count())`, when using `%lld`.
</issue_to_address>

### Comment 3
<location path="dconfig-center/dde-dconfig-daemon/dconfigresource.cpp" line_range="453" />
<code_context>
 void DSGConfigResource::save()
 {
-    qDebug(cfLog, "Save resource's cache for [%s], and cache count:%d", qPrintable(m_key), m_caches.count());
+    qDebug(cfLog, "Save resource's cache for [%s], and cache count:%lld", qPrintable(m_key), m_caches.count());
     for (auto item : m_files)
         item->save(m_localPrefix);
</code_context>
<issue_to_address>
**issue (bug_risk):** Format specifier for `m_caches.count()` should be aligned with its actual type.

`m_caches.count()` is unlikely to be `long long`, so `%lld` may not match its actual type. Either use `%d` if `count()` is `int`, or keep `%lld` and cast explicitly: `static_cast<long long>(m_caches.count())`. Apply the same approach consistently in all similar logging calls to avoid UB from format/type mismatches.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

{
const QList<ConfigCacheKey> &keys = request.data;
qCInfo(cfLog, "Do sync config cache, keys count:%d", keys.size());
qCInfo(cfLog, "Do sync config cache, keys count:%lld", keys.size());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): The %lld format specifier likely mismatches the type of keys.size().

QList::size() / count() returns int (Qt5) or qsizetype (Qt6), neither of which is guaranteed to be long long, so %lld is technically UB even if it seems to work. Please either:

  • keep %d and cast to int if the size is known to fit, or
  • cast to long long and keep %lld, or
  • use %zd with a cast to size_t / qsizetype.

The format specifier should match the actual argument type.

}

qDebug(cfLog, "Removed connection:%s, remaining %d connection.", qPrintable(connKey), m_conns.count());
qDebug(cfLog, "Removed connection:%s, remaining %lld connection.", qPrintable(connKey), m_conns.count());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): %lld may not match the type returned by m_conns.count().

m_conns.count() is int (Qt5) or qsizetype (Qt6), which may not be long long, so using %lld without a cast is technically UB. Please either use %d to match int or explicitly cast to long long, e.g. static_cast<long long>(m_conns.count()), when using %lld.

void DSGConfigResource::save()
{
qDebug(cfLog, "Save resource's cache for [%s], and cache count:%d", qPrintable(m_key), m_caches.count());
qDebug(cfLog, "Save resource's cache for [%s], and cache count:%lld", qPrintable(m_key), m_caches.count());
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

issue (bug_risk): Format specifier for m_caches.count() should be aligned with its actual type.

m_caches.count() is unlikely to be long long, so %lld may not match its actual type. Either use %d if count() is int, or keep %lld and cast explicitly: static_cast<long long>(m_caches.count()). Apply the same approach consistently in all similar logging calls to avoid UB from format/type mismatches.

@deepin-bot
Copy link
Copy Markdown
Contributor

deepin-bot Bot commented Mar 12, 2026

TAG Bot

New tag: 1.0.42
DISTRIBUTION: unstable
Suggest: synchronizing this PR through rebase #146

The issue was that during hot reload operations, override configuration
paths were being incorrectly matched by the getMetaConfigureId function
instead of being handled by getOverrideConfigureId. This caused override
configurations to fail during reload operations.

The fix modifies the regular expression in getMetaConfigureId to exclude
override paths using negative lookahead (?!overrides/). This ensures
that override paths are properly routed to getOverrideConfigureId for
correct processing. Additionally, the getConfigureIdByPath function was
updated to not check for file existence before parsing, as files may not
exist during deletion operations but still need path parsing.

Log: Fixed hot reload functionality for override configuration paths

Influence:
1. Test hot reload functionality with override configurations
2. Verify that override paths are correctly identified and processed
3. Test configuration deletion and reload scenarios
4. Validate both standard and override configuration paths work
correctly
5. Test edge cases with special characters in configuration paths

fix: 修复热加载中覆盖路径匹配问题

问题在于热重载操作期间,覆盖配置路径被 getMetaConfigureId 函数错误匹配,
而不是由 getOverrideConfigureId 处理。这导致覆盖配置在重载操作期间失效。

修复方案修改了 getMetaConfigureId 中的正则表达式,使用负向先
行断言 (?!overrides/) 排除覆盖路径。这确保覆盖路径能正确路由到
getOverrideConfigureId 进行处理。此外,更新了 getConfigureIdByPath 函
数,使其在解析前不检查文件是否存在,因为在删除操作期间文件可能不存在但仍
需要路径解析。

Log: 修复了覆盖配置路径的热重载功能

Influence:
1. 测试覆盖配置的热重载功能
2. 验证覆盖路径是否正确识别和处理
3. 测试配置删除和重载场景
4. 验证标准和覆盖配置路径都能正常工作
5. 测试包含特殊字符的配置路径边界情况
@18202781743 18202781743 changed the title fix: replace static with inline to resolve compilation warnings fix: fix override path matching in reload hotloading Mar 24, 2026
@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: 18202781743, BLumia

The full list of commands accepted by this bot can be found here.

Details Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@18202781743 18202781743 merged commit c1f7371 into linuxdeepin:master Mar 24, 2026
22 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants