背景
学了这么多数据结构的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。对于画板、智能表格也是一样的。