CRDT宝典 - SpreadSheet

240 阅读2分钟

背景

学了这么多数据结构的CRDT,并且还讲解了CRDT-文档的核心yata算法

那电子表格场景下如何设计一个CRDT呢?

如果拥有了CRDT-电子表格,我们就不需要写一大堆ot算法,还有令人生恐的维护工作。

思维链

indexable-CRDT不谋而合,使用LSeq足以

ps:移动操作 = 删 + 增

与行一致

单元格元素

存储方式

二维数组,内存占用太大,我们用Map来存储

冲突解决

我们先用最基础的方式:LWW-Registry,每个单元格数据里存着更新的最新时间,产生冲突时,使用最新的覆盖即可

映射

表格的顺序完全由行、列的顺序来决定。

所以单元格不需要考虑这个问题,只需要做好行、列的id和单元格的映射。

最直接的方式:Map[rowId][columnId]

selection

selection是表格应用很重要的组成部分,用户会经常使用选择,分类如下:

row selection

[minRowIndex,maxRowIndex]

col selection

[minColIndex,maxColIndex]

area selection

由于行列可能是随时变化,所以area selection并不会用rowIndex、colIndex来表达。

比如[1A,3C],代表(第一行,一个列)到(第三行,第三列)之间的单元格,直接遍历获取即可。

我们有别的好玩的优化方式:

R-Tree,一个由B+树组成的树,用于多维数据的范围查询(地图的区域选择等),我们这里是(x,y)形式的区域选择,符合R-Tree的能力。

merge

一个Map-CRDT即可,遇到冲突用LWW-Register

实现

代码就不写了,用yjs的库,不复杂

总结

我们用了indexable-CRDT、map-CRDT两个就能实现电子表格-CRDT。对于画板智能表格也是一样的。