blog/posts/2018 - 05 - 19.md 在 master 中 · frankmcsherry/blog

这是一篇关于用 Rust 实现相对简单的 Datalog 引擎(DataFrog)的文章,主要内容如下:

  • 背景与致谢:为响应 Rust 团队在新的改进型借用检查器方面的工作而构建,感谢 @lqd、@nikomatsakis 和 @qmx 的推动、测试等。
  • Datalog 简介:是几十年前重新流行起来的语言,从一些“元组”集合(常称为“事实”)开始,反复应用规则从现有元组推导出新元组,规则形式受限。
  • 关系(Relation):定义了 Relation<Tuple>,是排序且无重复的 Tuple 元素列表,通过 From<Vec<Tuple>> 实现从 Vec 创建,还通过 IntoIterator 实现接受其他可枚举类型,并有 merge 方法合并两个关系。
  • 变量(Variable):用于处理不断增长的关系,包含“稳定”(已处理过多次的元组)、“近期”(最近添加但未处理的元组)和“待添加”(即将添加的元组)三个部分,规则可根据不同部分进行操作。
  • 规则(Rules):以 nodes(y) <- nodes(x), edges(x,y) 为例,介绍了如何通过规则从已有关系中推导出新关系,只需关注涉及“近期”元组的匹配。
  • 辅助函数(Helpers):开发了用于连接关系的 join_helper 方法,通过合并两个已排序的关系来查找匹配的键值对,还介绍了 gallop 方法用于快速定位匹配位置。
  • 规则的实现(Rules (redux)):通过 join_into 方法实现规则,将两个输入变量的匹配结果添加到输出变量中,通过多次调用 join_helper 并进行转换来实现。
  • 去重(Distinctness):实现了 changed 方法来处理变量中的元组,将“近期”元组合并到“稳定”元组中,将“待添加”元组移动到“近期”元组中,并去除已存在于“稳定”元组中的元素。
  • 注意事项(Caveats):由于各种 ergonomic 原因,一些字段被包装在 Rc<RefCell<_>> 中,实现中也有一些简化以提高性能。
  • 示例(An example):以 nodesedges 为例,展示了如何使用 DataFrog 进行实际计算,并与 ASPLOS 论文中的结果进行比较,运行时间约为 1.5s 加载数据,3s 进行计算。
  • 下一步(Next steps):指出目前的 ergonomics 存在一些问题,希望未来能通过更简单的 Datalog 语法实现自动化,同时希望更多人关注和改进该引擎。
  • 附加内容(Addendum 2018-05-21: Treefrog Leapjoin):介绍了 Rust 团队感兴趣的更复杂的基准查询规则,以及“treefrog leapjoin”算法,通过 ExtendWithLeaper trait 实现更高效的连接操作,还讨论了不同类型的约束实现,并在 Rust 的原型借用检查器中进行了性能测试,将时间从 6.985s 优化到 5.275s。
阅读 8
0 条评论