【问题标题】:Algorithm for YAML minification that includes reference insertion包含引用插入的 YAML 缩小算法
【发布时间】:2018-06-05 18:07:54
【问题描述】:
是否存在通过引用插入实现 YAML 缩小的现有工具、库或算法?如果这个问题已经有一个通用的解决方案,我不想重新发明轮子。
我在这种情况下创造了术语引用插入,因此我想要的行为可能有不同的名称。让我解释一下我所说的引用插入是什么意思:
一个基本的 YAML 缩小算法没有引用插入,MinifyYamlBasic,将与 JSON 缩小同构,但会用最不冗长的等效 YAML 节点语法替换任何 JSON 原语。我在https://onlineyamltools.com/minify-yaml 找到了MinifyYamlBasic 实现的在线示例。
带有引用插入的 YAML 缩小算法,MinifyYamlWithReferences 将完成 MinifyYamlBasic 所做的所有事情,但随后会为任何多次出现的 YAML 节点生成锚点并替换重复的 YAML具有对生成锚点的引用的节点,按 YAML 节点文本长度的降序排列。
这是我正在寻求的行为的基本理念,尽管显然还有其他因素需要考虑。小于其别名的重复节点可能不应该被引用替换。需要对输入文档进行规范化,以便可以通过句法比较来识别语义上等价的节点,这至少包括:标量的规范形式替换;映射节点键的规范排序;取消引用和删除预先存在的锚点。
我可能还没有考虑到更多。在我花时间进一步考虑之前,
是否有任何可用资源提供MinifyYamlWithReferences(或类似的东西)的现有实现?
算法(或算法类别)是否有一个常用名称,我称之为“通过引用插入进行缩小”?
【问题讨论】:
标签:
algorithm
yaml
open-source
minify
bundling-and-minification
【解决方案1】:
你想要做的是一个转换。这种操作生成的 YAML 在语义上与原始 YAML 不等价。以这个小 YAML 为例:
[foo, foo]
此 YAML 表示以下文档图:
+----------------------+
| Sequence (root node) |
+--|----------------|--+
| |
+--v--+ +--v--+
| foo | | foo |
+-----+ +-----+
使用您的MinifyYamlWithReferences,这将变为:
[&a foo, *a]
代表如下文档图:
+----------------------+
| Sequence (root node) |
+--|----------------|--+
| |
+--v--+ |
| foo |<------------+
+-----+
所以你创建了一个语义不同的 YAML 文档!称此缩小 会产生误导,因为缩小通常被认为是将源转换为更小但在语义上等效的源的过程。您所追求的是去重(连同缩小),这是一种语义转换。
我不知道有任何现有的实现。实施它也很困难,因为您需要回答以下难题:
-
!!str a、"a"、'a' 和 a 中的哪一个是等效的?
- 这两个是否等效:
&a [ *a ]、[*a]?
(解释:在 1. 中,我们有两个引用的标量,它们都计算为带有 ! 标记的标量节点。标量上的 ! 使用 YAML 核心模式解析为 !!str。a 是标量不匹配任何比字符串更具体的正则表达式,所以它也会根据核心模式得到!!str。但是你确定使用核心模式吗?在2.中,我们有一个直接的序列循环,以及只链接到该循环的序列,但是通过无限递归进行(理论上)比较会说两者相等。他们是这样吗?)
我看不到这种转换的用例。如果您的目标是尽量减少通过网络发送的数据,我建议在初始 YAML 上使用压缩算法——这要简单得多(已经存在,内部也对字符流进行重复数据删除,但可逆)。