惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

酷 壳 – CoolShell
酷 壳 – CoolShell
T
Threatpost
Latest news
Latest news
N
News | PayPal Newsroom
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
Help Net Security
Help Net Security
D
Darknet – Hacking Tools, Hacker News & Cyber Security
AI
AI
Simon Willison's Weblog
Simon Willison's Weblog
TaoSecurity Blog
TaoSecurity Blog
The Last Watchdog
The Last Watchdog
L
LINUX DO - 热门话题
Google DeepMind News
Google DeepMind News
T
Threat Research - Cisco Blogs
O
OpenAI News
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
T
The Exploit Database - CXSecurity.com
NISL@THU
NISL@THU
Application and Cybersecurity Blog
Application and Cybersecurity Blog
S
Securelist
小众软件
小众软件
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
Martin Fowler
Martin Fowler
S
SegmentFault 最新的问题
Cisco Talos Blog
Cisco Talos Blog
云风的 BLOG
云风的 BLOG
AWS News Blog
AWS News Blog
GbyAI
GbyAI
N
News and Events Feed by Topic
cs.CV updates on arXiv.org
cs.CV updates on arXiv.org
美团技术团队
Engineering at Meta
Engineering at Meta
A
About on SuperTechFans
博客园 - 三生石上(FineUI控件)
S
Schneier on Security
博客园 - 聂微东
V2EX - 技术
V2EX - 技术
T
Troy Hunt's Blog
SecWiki News
SecWiki News
S
Secure Thoughts
B
Blog RSS Feed
Hugging Face - Blog
Hugging Face - Blog
WordPress大学
WordPress大学
腾讯CDC
H
Heimdal Security Blog
Exploit-DB.com RSS Feed
Exploit-DB.com RSS Feed
Apple Machine Learning Research
Apple Machine Learning Research
月光博客
月光博客
www.infosecurity-magazine.com
www.infosecurity-magazine.com
P
Privacy International News Feed

依云's Blog

通过字幕总结YouTube视频内容 - 依云's Blog 自定义系统默认中文字体 - 依云's Blog Wayfire支持不缩放Xwayland啦 - 依云's Blog 使用wayvnc远程访问无头Wayfire会话 - 依云's Blog 给论坛用上了文本嵌入模型 - 依云's Blog 使用 Restic 备份数据 - 依云's Blog Arch Linux 中文论坛迁移杂记 - 依云's Blog 用 Android 手机当电脑的话筒 - 依云's Blog 使用 ffmpeg 对音频文件进行响度归一化 - 依云's Blog 为团队部署邮件服务 - 依云's Blog 使用 nftables 屏蔽大量 IP - 依云's Blog YubiKey 初体验 - 依云's Blog fcitx5 码表同步方案 - 依云's Blog 我正在使用的火狐扩展(2024年版) - 依云's Blog
pacfiles: 高速的 pacman -F 替代品
依云 · 2025-03-05 · via 依云's Blog

缘起

Linux 发行版的软件包管理器通常都会提供这么一个功能——查找文件在哪个仓库中存在的软件包里。实现起来也挺简单:仓库维护一个每个软件包里都有哪些文件的数据库,软件去查就可以了——假如用户不介意性能问题的话。

最开始,我使用的是 pkgfile。它是使用 C++ 编写的,会把 Arch 官方提供的 .files 数据库(压缩的 tar 归档)转成 cpio 归档再用(压缩可以靠 btrfs,问题倒是不大)。它比 pacman -F 可快多了,但是我后来不用了,因为它当时不支持多架构——即在 pacman.conf 里把 Architecture 设置为多个值,比如我用的 x86_64 x86_64_v3。现在等我写好了 pacfiles,才发现它终于在大半年之前支持多架构了……不过它看起来开发还是不太活跃,选项和输出格式也和 pacman -F 有很大的差别。

效果对比

最主要的功能是按文件名搜索,因此让我们先看看这个:

pacman -F vim 截图

pkgfile vim 截图

pacfiles -F vim 截图

pacman -F 和 pkgfile 都是遍历整个数据库。pacman -F 和 pacfiles 是单线程的,pkgfile 是多线程,但我不知道为什么 pacman -F 会慢那么多。pkgfile 比 pacfiles 快一些,毕竟它提供的信息少、又不好看、还是多线程并行工作。另外值得注意的是,pacman -F 由于会预先加载整个数据库到内存,因此内存占用了近 3G。

有时候也会想要按完整路径搜索

pacman -F /usr/bin/vim 截图

pkgfile /usr/bin/vim 截图

pacfiles -F /usr/bin/vim 截图

这次 pacfiles 因为有索引的帮助,并且不需要检查软件包是否已安装,比 pkgfile 快了不少。pacman -F 依旧又慢又吃内存。

接下来看看输出软件包的文件列表。这个由于输出结果多、输出格式又都差不多,我就重定向扔掉了,只看性能数据。

pacman -Fl vim-lily 截图

pkgfile -l vim-lily 截图

pacfiles -l vim-lily 截图

这次 pkgfile 比 pacfiles 略快。

有时候也会想用正则搜索

pacman -F --regex '.*libpython3\.11.*'

pkgfile --regex '.*libpython3\.11.*'

pacfiles -F --regex '.*libpython3\.11.*'

这次 pkgfile 比 pacfiles 快了不少。使用正则搜索时,pacfiles 没有使用索引,也是遍历数据,所以快不起来了。

不过 pacfiles 是支持通配符搜索的,也能用上索引,很快的。pacman -F 不支持这个。而 pkgfile 嘛……它不仅慢,好像还又出 bug 了。

pkgfile -g '*libpython3.11*'

pacfiles '*libpython3.11*'

如果我写 pacfiles 之前得知 pkgfile 修了多架构那个 bug,我也许就不会写 pacfiles 了。不过现在对比下来,我也不后悔啦。

另外值得注意的是,pacfiles 无论是输出、还是命令行选项,都尽力兼容 pacman -F 的,以方便用户迁移。

幕后

其实我很早就想弄一个更快的 pacman -F 了。我首先想到的是,把数据塞进 SQLite3 里让它查。性能确实是好得不得了,但是一看生成的数据库,好几个 G……后来又尝试像 pacman -F 那样直接读压缩包,但是不一次性加载到内存,因此不需要那么多内存。但结果并不理想:解压和遍历搜索都不太能快得起来,最多并行处理多个数据库而已。plocate 是很快啦,但是它的数据结构是自己定制的,并不是库,不能直接拿来用。于是此事便放下了。

直到前不久,我读到《Succinct data structures》一文,特别是文中提到的 FM-index——这不正好能用来搜索文件名吗?不过,plocate 用的是什么数据结构来着?于是我去翻代码恢复了一下久远的记忆。哦,是 zstd 压缩的 trigram 倒排索引啊。好像也不错,还支持通配符呢。正则搜索它倒是没用上索引,因为作者认为「使用 locate 进行正则搜索太小众了」所以没有花精力去实现。

但是,以上关于数据结构的内容都不是重点!重点是,我发现了个 plocate-build 命令!它支持从纯文本创建 plocate 数据库!那我不是直接把文件名传给它就好了嘛~唯一有点遗憾的是,它不支持从管道读取文件名列表,因此需要先输出到临时文件中再给它使用,过程中会占用不少内存(/tmp 空间)。至于查询,调用 plocate 命令拿到结果再稍微处理一下就好了。于是想到就做,这就有了现在的 pacfiles(其实早期版本也在 git 历史里有)。

项目地址:https://github.com/lilydjwg/pacfiles。AUR 有 pacfiles-git 包。也可以 cargo install pacfiles 安装。