这是一篇关于用 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):以
nodes
和edges
为例,展示了如何使用 DataFrog 进行实际计算,并与 ASPLOS 论文中的结果进行比较,运行时间约为 1.5s 加载数据,3s 进行计算。 - 下一步(Next steps):指出目前的 ergonomics 存在一些问题,希望未来能通过更简单的 Datalog 语法实现自动化,同时希望更多人关注和改进该引擎。
- 附加内容(Addendum 2018-05-21: Treefrog Leapjoin):介绍了 Rust 团队感兴趣的更复杂的基准查询规则,以及“treefrog leapjoin”算法,通过
ExtendWith
和Leaper
trait 实现更高效的连接操作,还讨论了不同类型的约束实现,并在 Rust 的原型借用检查器中进行了性能测试,将时间从 6.985s 优化到 5.275s。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。