我认为这可能是一个相当普遍的问题,但不知何故很难找到合适的答案。
背景 我目前正在研究如何加快Patternlab的节点变体。它基本上是一个系统,您可以在其中创建包含一些基本元素(称为原子)的 HTML 模板文件,如标题、段落等,并将它们组合成更大的东西(分子),然后组合多个分子,直到您拥有完整的网页。模板文件由能够引用和包含其他模板文件的模板引擎处理。Patternlab 现在将读取所有文件并构建每个文件的前身和祖先的图表。
问题是,模板目录中的所有文件都被读取、处理,模板引擎的编译输出被写入某处,完成。对于 10-20 MB 的 HTML 模板,这大约需要 1 分钟(例如 Mustache)。有差异更新会好得多。
一般问题
给定文件(节点)的有向无环图,f
并且f1
→ f2
forf1
包含f2
在其内容中。当在f1
→中f2
也需要重新编译时(即编译顺序应该是f2
,f1
),当可能存在包含多个更改文件的路径和节点取决于多条路径?
给定两个并行路径(即f1
→ f2
→f5
和f1
→ f4
→ f5
),如何以最小长度找到并行编译的最佳路径集(即通过路径的总长度)l
?
注意事项
那么如何做到这一点呢?我们只需要观察事件的模板目录create
,modify
和delete
。这可以通过从内核收集文件系统事件来完成。
请记住,对于任何文件,我们还可以接收“最后修改”时间戳 ( mtime
)。
第一步,构建初始图已经由 patternlab 完成。图的每个节点包括:
- 源文件路径和
mtime
- 目标文件路径和
mtime
- 文件的一组参数(即用户名、页面标题等)
- 一个
changed
标志,指示文件是否通过检查被修改mtimes
(见下文)。这总是反映当前的文件系统状态(简单得多)。
即有一个“影子”图编译最新的编译输出。这导致了这些情况:
- source.mtime <= target.mtime:源代码已编译,之后未修改。如果在构建图形后更改了源文件,
- source.mtime > target.mtime:在构建图之前更改了源,必须重新编译
现在的想法是,如果设置了更改的标志,则重新编译每个节点,否则返回目标文件的内容。
- 当一个文件被编译时,所有引用这个文件的文件(例如,所有带有节点传入边的节点)也必须重新编译。
- 考虑当源 hsa 被编译到目标时,标志变为 false,因此它不会被编译两次。再次访问时返回目标内容是可以的。
- 有多个根节点(只有传出边,即页面),一些是“叶子”(只有传入边,即分子),还有没有
- 假设patternlab 不能并行运行,即有一个“忙”标志阻止并发整体运行。
- 然而,使用所有 CPU 内核更快地编译模板并为未修改的模板使用内容缓存可能是有益的。
- 如果一个文件
f1
包含另外两个文件和f2
,两者都有需要重新编译的文件作为后继文件,则必须先等待所有路径重新编译。f3
f2
f3
f1
例如(c = 已更改)
f5 -> f6 (c)
^
/
f1 -> f2 -> f3 -> f4(c)