探索并发遍历 DAG

探索如何编写一个更简洁和优雅的并发 DAG 遍历算法。 背景 最近我有了新的 Idea,想要分析一个 Nix Derivation 的依赖图,并以树形结构打印。在这个图结构中,不是所有的 Derivation 或 Store Object 都会被打印,而是只有那些没有被构建或还没有从缓存服务器上同步的才会被显示。也就是说,分析出某 Store Object 的闭包中在本机上还不存在的部分。这个项目已经基本上完成,名为 DrvGraph。 在 DrvGraph 中,最核心的部分自然是对于 Nix Store 进行遍历,分析其中的 Derivation 和 Store Object 的连接关系。由于需要查询某些 Store Object 是否存在与缓存上,网络 IO 成为了遍历过程中的瓶颈,所以我们需要一个并发的遍历实现。 串行的有向无环图遍历算法非常简单,几乎是算法课的最基础部分。然而这样一种朴素的实现却难以迁移到并发环境下。本文则尝试探索更好的并发版本的 DAG 遍历。 基本概念 在讨论遍历算法实现之前,首先我们需要了解一下 DrvGraph 场景下 DAG 的组成。 DrvGraph 分析的是 Derivation 或 Store Object 之间的依赖关系,这也就是说 DAG 中存在这两种节点 Derivation 和 Store Object。这是由于 Nix 既是一个包管理器又是一个构建系统,Derivation 是一个包的构建过程的描述,Store Object 是构建的输入或产物。 Derivation 在 Nix 中,一个包实际上对于一个 Derivation,它存储于 Nix Store 中,路径包括内容的哈希、包名,并以 .drv 结尾。比如 g1w7hy3qg1w7hy3qg1w7hy3qg1w7hy3q-foo.drv 就是一个可能的 Derivation 的文件的路径,称为 Deriving Path。Deriving Path 可以看作是 Derivation 的唯一标识。 ...

September 23, 2026 · 9 min · Justin Chen