Skip to content

feat: move index storage from XDG_CACHE_HOME to XDG_DATA_HOME#211

Merged
deepin-bot[bot] merged 3 commits intolinuxdeepin:develop/snipefrom
wangrong1069:pr0417
Apr 20, 2026
Merged

feat: move index storage from XDG_CACHE_HOME to XDG_DATA_HOME#211
deepin-bot[bot] merged 3 commits intolinuxdeepin:develop/snipefrom
wangrong1069:pr0417

Conversation

@wangrong1069
Copy link
Copy Markdown
Contributor

@wangrong1069 wangrong1069 commented Apr 17, 2026

Summary by Sourcery

Migrate persistent index storage to XDG data directory and improve process running-flag handling.

New Features:

  • Store the persistent index in the XDG data directory instead of the cache directory and automatically migrate existing index data to the new location on startup.

Enhancements:

  • Improve robustness of the running-flag mechanism by avoiding recreation when it already exists and resetting it after potential index directory removal.

Added comprehensive image format support to the indexer by analyzing
Qt5 imageformat plugins. Extended pic_file_suffix field to include
modern formats (AVIF, HEIF, WebP), professional formats (EXR, EPS, PSD),
KDE/Krita formats (KRA, ORA), SGI legacy formats (RGB, SGI, BW), and
major camera RAW formats (CR2, NEF, DNG, ARW, etc.).

Influence:
1. Test index creation with new image formats - verify correct recognition
2. Test search functionality - verify new formats appear in image category
3. Verify backward compatibility - existing indexes continue to work
4. Test RAW format indexing on various camera files

Log: Extend image format support for Qt5 compatible formats

feat: 基于 Qt5 插件扩展图片格式支持

通过分析 Qt5 imageformat 插件,为索引器添加了全面的图片格式支持。
扩展 pic_file_suffix 字段,新增现代格式 (AVIF, HEIF, WebP)、专业格式 (EXR, EPS, PSD)、
KDE/Krita 格式 (KRA, ORA)、SGI 遗留格式 (RGB, SGI, BW) 以及主流相机 RAW 格式 (CR2, NEF, DNG, ARW 等)。

Influence:
1. 测试新图片格式的索引创建 - 验证正确识别
2. 测试搜索功能 - 验证新格式出现在图片类别中
3. 验证向后兼容性 - 现有索引继续工作
4. 测试各种相机文件的 RAW 格式索引

Log: 扩展图片格式支持以兼容 Qt5 格式
Changed the index storage location from XDG_CACHE_HOME to XDG_DATA_HOME
to ensure the index data survives cache cleaning operations. Added a
migration function that automatically moves existing index data from the
old location to the new one on first run.

Influence:
1. Test fresh installation - verify index created in ~/.local/share
2. Test upgrade scenario - verify migration from ~/.cache to ~/.local/share
3. Test migration with large index - verify performance and correctness
4. Test cross-device migration - verify fallback copy+remove works
5. Verify old directory cleanup after successful migration

Log: Migrate index storage to the XDG_DATA_HOME directory

feat: 将索引存储从 XDG_CACHE_HOME 迁移至 XDG_DATA_HOME

将索引存储位置从 XDG_CACHE_HOME 更改为 XDG_DATA_HOME,确保索引数据不会被
缓存清理工具删除。新增迁移函数,在首次运行时自动将现有索引数据从旧位置
移动到新位置。

Influence:
1. 测试全新安装 - 验证索引在 ~/.local/share 中创建
2. 测试升级场景 - 验证从 ~/.cache 迁移至 ~/.local/share
3. 测试大索引迁移 - 验证性能和正确性
4. 测试跨设备迁移 - 验证 copy+remove 回退方案
5. 验证迁移成功后旧目录已清理

Log: 将索引存储迁移至 XDG_DATA_HOME 目录
@sourcery-ai
Copy link
Copy Markdown

sourcery-ai Bot commented Apr 17, 2026

Reviewer's Guide

Moves the persistent index storage directory from XDG_CACHE_HOME to XDG_DATA_HOME, adds an on-start migration path for existing indexes, and adjusts running-flag handling to be idempotent and resilient to index directory deletion.

Sequence diagram for daemon startup with index migration and running flag

sequenceDiagram
    participant DaemonMain
    participant Config
    participant FileSystem
    participant Logger
    participant RunningFlag

    DaemonMain->>Config: make_event_handler_config()
    activate Config
    Config->>FileSystem: get_user_cache_dir()
    Config->>FileSystem: get_user_data_dir()
    Config->>Config: migrate_index_dir(old_index_dir, new_index_dir)
    activate Config
    Config->>FileSystem: exists(new_index_dir)
    alt new_index_dir exists
        Config-->>Config: return (no migration)
    else new_index_dir does not exist
        Config->>FileSystem: exists(old_index_dir)
        alt old_index_dir does not exist
            Config-->>Config: return (no migration)
        else old_index_dir exists
            Config->>Logger: info(migrating index)
            Config->>FileSystem: create_directories(parent_path)
            alt error creating parent
                Config->>Logger: error(failed to create parent)
                Config-->>Config: return
            else parent created
                Config->>FileSystem: rename(old_index_dir, new_index_dir)
                alt rename succeeds
                    Config->>Logger: info(migration completed)
                else rename fails
                    Config->>Logger: error(rename failed)
                    Config->>FileSystem: copy(old_index_dir, new_index_dir, recursive)
                    alt copy fails
                        Config->>Logger: error(copy failed)
                        Config-->>Config: return
                    else copy succeeds
                        Config->>FileSystem: remove_all(old_index_dir)
                        alt remove_all fails
                            Config->>Logger: warn(remove old dir failed)
                        end
                        Config->>Logger: info(migration completed)
                    end
                end
            end
        end
    end
    deactivate Config
    Config-->>DaemonMain: event_handler_config with persistent_index_dir=new_index_dir
    deactivate Config

    DaemonMain->>RunningFlag: set_running_flag()
    activate RunningFlag
    RunningFlag->>FileSystem: get_running_flag_path()
    RunningFlag->>FileSystem: file_exists(running_flag_path)
    alt running flag exists
        RunningFlag->>Logger: debug(flag exists, skipping)
        RunningFlag-->>DaemonMain: return
    else running flag missing
        RunningFlag->>FileSystem: write_file(running_flag_path)
        alt write fails
            RunningFlag->>Logger: warn(failed to set running flag)
        end
        RunningFlag-->>DaemonMain: return
    end
    deactivate RunningFlag

    DaemonMain->>DaemonMain: start event listener with handler
Loading

File-Level Changes

Change Details Files
Add migration helper to move existing index directory from cache to data location on startup.
  • Introduce migrate_index_dir helper using std::filesystem to move or copy+remove the existing index directory from the old cache path to the new data path with robust error handling and logging.
  • Ensure parent directories for the new index path are created before migration and log success or failures via spdlog.
src/daemon/src/core/config.cpp
Switch persistent index storage to XDG_DATA_HOME and invoke migration.
  • Change construction of persistent_index_dir from g_get_user_cache_dir to g_get_user_data_dir in event_handler_config.
  • Compute old and new index paths and call migrate_index_dir during event_handler_config creation so existing users are transparently migrated.
  • Keep volatile_index_dir aligned with persistent_index_dir.
src/daemon/src/core/config.cpp
Make running-flag creation idempotent and re-establish it after potential index-directory removal.
  • Before writing the running flag, check if the flag file already exists and early-return while logging a debug message to avoid redundant writes.
  • Call set_running_flag() again in main after the event handler setup to restore the flag if the index directory (and flag) were removed.
src/daemon/src/utils/running_flag.cpp
src/daemon/src/main.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

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 1 issue, and left some high level feedback:

  • In migrate_index_dir, consider only switching config.persistent_index_dir to new_index_dir when the migration actually succeeds; as written, a failed rename/copy will still point the config to an empty new directory and effectively drop the existing index.
  • The error handling in migrate_index_dir could be more robust by checking and logging std::filesystem::exists failures (when ec is set) instead of silently returning, so permission or I/O issues during migration are visible.
  • Re-running set_running_flag() in main to handle a removed index dir is somewhat implicit; consider encapsulating this logic inside set_running_flag or documenting the dependency so future changes to the running flag behavior don’t accidentally break this guarantee.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In `migrate_index_dir`, consider only switching `config.persistent_index_dir` to `new_index_dir` when the migration actually succeeds; as written, a failed rename/copy will still point the config to an empty new directory and effectively drop the existing index.
- The error handling in `migrate_index_dir` could be more robust by checking and logging `std::filesystem::exists` failures (when `ec` is set) instead of silently returning, so permission or I/O issues during migration are visible.
- Re-running `set_running_flag()` in `main` to handle a removed index dir is somewhat implicit; consider encapsulating this logic inside `set_running_flag` or documenting the dependency so future changes to the running flag behavior don’t accidentally break this guarantee.

## Individual Comments

### Comment 1
<location path="src/daemon/src/main.cpp" line_range="106-107" />
<code_context>
     event_listenser listenser;
     print_event_handler_config(event_handler_config);
     default_event_handler handler(event_handler_config);
+    // Set running flag again for index dir may removed
+    set_running_flag();
     listenser.set_handler([&handler](fs_event *event) {
         handler.handle(event);
</code_context>
<issue_to_address>
**suggestion:** Clarify the relationship between the running flag and index directory removal, and whether the second call is needed.

Right now it’s unclear why this second `set_running_flag()` depends on potential index directory removal, especially since `set_running_flag()` no-ops if the flag already exists. If the flag lives under the migrated index directory, consider creating it as part of the directory migration/initialization instead of re-calling it here, or document this coupling so future index layout changes don’t unintentionally break the running-flag behavior.
</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.

Comment thread src/daemon/src/main.cpp Outdated
Make set_running_flag() idempotent by checking if the flag file already
exists before attempting to create it. Also re-call set_running_flag()
in main after handler setup to handle cases where the index directory
may have been removed externally.

Influence:
1. Test daemon startup - verify running flag created once
2. Test repeated set_running_flag calls - verify no duplicate operations
3. Test with index dir removed externally - verify flag re-created

Log: Optimize running flag setup with idempotent check

fix: 为运行标志设置添加幂等检查并支持重复调用

使 set_running_flag() 具有幂等性,在创建标志文件前先检查是否已存在。同时
在 main 中 handler 设置后重新调用 set_running_flag(),以处理索引目录可能
被外部删除的情况。

Influence:
1. 测试守护进程启动 - 验证运行标志仅创建一次
2. 测试重复调用 set_running_flag - 验证无重复操作
3. 测试索引目录被外部删除 - 验证标志能重新创建

Log: 优化运行标志设置逻辑并添加幂等检查
@deepin-ci-robot
Copy link
Copy Markdown

deepin pr auto review

这份代码变更主要涉及将索引数据存储位置从缓存目录迁移到数据目录,并增加了对更多图片格式的支持。以下是对代码的详细审查意见:

1. 语法与逻辑

config.cpp 中的 migrate_index_dir 函数

  • 问题:在 std::filesystem::rename 失败后,尝试使用 copyremove_all 作为备选方案。但是,std::filesystem::copy 默认行为不会复制符号链接的属性,且对于大量文件的复制操作,这可能非常耗时。
  • 建议
    • 考虑在 copy 操作时添加 std::filesystem::copy_options::copy_symlinks | std::filesystem::copy_options::overwrite_existing 选项,以确保符号链接被正确复制。
    • 对于大型索引,直接复制可能导致长时间阻塞。建议考虑异步处理或至少在日志中提示用户这可能需要较长时间。

running_flag.cpp 中的 set_running_flag 函数

  • 问题:在文件已存在时直接返回,这可能导致在某些异常情况下(如进程崩溃后标志文件未清理)无法正确设置标志。
  • 建议
    • 虽然添加了 debug 级别的日志,但建议考虑是否需要更严格的检查,例如验证文件内容或进程是否存在。

2. 代码质量

错误处理

  • 问题:在 migrate_index_dir 函数中,虽然使用了 std::error_code 来避免异常,但错误处理逻辑可以更细致。
  • 建议
    • 对于 remove_all 失败的情况,虽然只是警告,但建议记录更多上下文信息,如目录大小或文件数量,以便后续排查。

代码注释

  • 优点:添加了清晰的注释说明更改原因(如使用 XDG_DATA_HOME 而非 XDG_CACHE_HOME)。
  • 建议
    • migrate_index_dir 函数中,可以添加注释说明为什么在 rename 失败后选择 copy + remove_all 的策略。

3. 代码性能

文件系统操作

  • 问题migrate_index_dir 中的 std::filesystem::copy 是同步操作,对于大型索引可能阻塞主线程。
  • 建议
    • 考虑将迁移操作移至后台线程执行,或至少在迁移期间提供进度反馈。

图片格式列表

  • 问题org.deepin.anything.json 中新增了大量图片格式后缀,这可能导致文件类型检查时的字符串匹配变慢。
  • 建议
    • 如果后缀列表很长,考虑使用更高效的数据结构(如 std::unordered_set)进行查找,而非简单的字符串分割和比较。

4. 代码安全

权限问题

  • 问题:在 migrate_index_dir 中,创建新目录时未显式设置权限,可能继承父目录的权限,导致权限过大或过小。
  • 建议
    • 使用 std::filesystem::permissions 显式设置适当的权限(如 0700)。

路径遍历

  • 问题:虽然使用了 g_get_user_cache_dirg_get_user_data_dir,但未对路径进行进一步验证。
  • 建议
    • 确保路径不包含符号链接或可疑组件,防止路径遍历攻击。

资源清理

  • 问题:如果 copy 操作中途失败,部分文件可能已复制到新目录,但旧目录未被清理,导致数据不一致。
  • 建议
    • copy 失败时,考虑清理已复制的部分文件,或至少记录状态以便后续恢复。

5. 其他建议

.gitignore 更新

  • 建议:确认 .claude/ 是否需要被忽略,如果是临时目录,建议添加注释说明。

main.cpp 中的 set_running_flag

  • 建议:在 default_event_handler 实例化后立即调用 set_running_flag 是合理的,但建议确保此操作是幂等的,避免多次调用导致问题。

总结

整体代码变更合理,主要改进了索引数据的持久化存储位置,并扩展了支持的图片格式。但在错误处理、性能优化和安全性方面仍有改进空间。建议重点关注文件迁移操作的健壮性和效率,以及权限和路径的安全性。

@deepin-ci-robot
Copy link
Copy Markdown

[APPROVALNOTIFIER] This PR is NOT APPROVED

This pull-request has been approved by: lzwind, wangrong1069

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

@wangrong1069
Copy link
Copy Markdown
Contributor Author

/merge

@deepin-bot deepin-bot Bot merged commit 39ec41f into linuxdeepin:develop/snipe Apr 20, 2026
22 checks passed
@wangrong1069 wangrong1069 deleted the pr0417 branch April 20, 2026 05:44
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