Yjs解析

news2024/11/15 16:23:54

本文引用自 摸鱼wiki

1. YATA算法解析

YATA算法是Yjs库的核心冲突解决算法,这里主要讲解下这个算法成立的三个规则:

规则1:禁止发生冲突的插入操作之间的origin连线(红线)发生交叉。

如上图所示,图中展示了两个冲突的插入操作基状态 O 1 O_{1} O1 O 2 O_{2} O2,以及他们对应的插入内容 O 1 ′ O'_{1} O1 O 2 ′ O'_{2} O2,插入后的最终状态,只能出现两种情况: O 1 O 1 ′ O 2 O 2 ′ O_{1}O'_{1}O_{2}O'_{2} O1O1O2O2或者 O 1 O 2 O 2 ′ O 1 ′ O_{1}O_{2}O'_{2}O'_{1} O1O2O2O1,绝对不能出现 O 1 O 2 O 1 ′ O 2 ′ O_{1}O_{2}O'_{1}O'_{2} O1O2O1O2 这种交叉的情况,否则算法的正确性不能保证。即满足:

o 1 < r u l e s 1 o 2 ⇔ o 1 < o r i g i n 2 ∨ o r i g i n 2 ≤ o r i g i n 1 o_{1} <_{rules1}o_{2} \Leftrightarrow o_{1} < origin_{2} \lor origin_{2} \leq origin_{1} o1<rules1o2o1<origin2origin2origin1

规则2:指定 < c <_{c} <c 上的传递性。 o 1 < c o 2 o_{1} <_{c} o_{2} o1<co2确保没有大于 o 2 o_{2} o2但小于 o 1 o_{1} o1的操作 o o o

o 1 < r u l e s 2 o 2 ⇔ ∀ o : o 2 < c o → o 1 ≤ o ⇔ ∄ o : o 2 < c o < o 1 o_{1} <_{rules2} o_{2} \Leftrightarrow \forall o : o_{2} <_{c} o \rightarrow o_{1} \leq o \Leftrightarrow \nexists o : o_{2} <_{c} o < o_{1} o1<rules2o2o:o2<coo1oo:o2<co<o1

规则3:当两个冲突操作具有相同的原点时,创建者id较小的操作位于左侧

o 1 < r u l e s 3 o 2 ⇔ o r i g i n 1 ≡ o r i g i n 2 → c r e a t o r 1 < c r e a t o r 2 o_{1} <_{rules3} o2 \Leftrightarrow origin_{1} \equiv origin_{2} \rightarrow creator_{1} < creator_{2} o1<rules3o2origin1origin2creator1<creator2

2. 操作序列号生成

Yjs会给每个操作生成一个操作id,该id由一个(clientId, clockId)元组构成。clientId表示房间内客户端的标识符,全局唯一;clockId采用名为 Lamport timestamp 的逻辑时间戳,可以理解为是个从零开始的单调递增计数器,具体的更新逻辑为:

收到本地事件时,localClock += 1

收到远端事件时,localClock = max(remoteClock, localClock) + 1

3. 存储结构

  • StructStore:依据逻辑时序创建的结构化数据。其为房间内每个客户端分配一个扁平的数组,数组内存储该客户端的操作列表。该数据类型方便进行二分查找对应某一客户端的某一操作。

  • 双向链表:依据文档结构顺序创建的结构化数据。文档的每个操作都会插入到此链表中,可以理解为这个链表维护整个文档的最新状态。

4. 删除机制

采用双缓冲队列机制。删除的节点先放到一个临时队列A中,一段时间后再放到可删除队列B,最后清空B队列即完成删除。

5. 撤销机制

Yjs每次更新都会生成一次Transaction(转换),主要有以下两个流程:

  • 记录本次更新新增的item

  • 往DeleteSet中添加本次更新导致被删除的item

基于上述的数据结构,撤销一次Transaction可以简化为下面两个操作:

  • 将该次Transaction新增的item标记为删除

  • 重新插入该次Transaction删除的item

6. 同步机制

各客户端维护一个StateVector。Yjs 通过 StateVector 的概念来定位逻辑时间轴,这种数据结构实际上就是一组记录了某时刻全部客户端 (clientId, clockId) 的元组。

同步文档状态时,Yjs划分了两个阶段:

  • 阶段1:待同步用户向房间内所有其他用户发送自身的StateVector;

  • 阶段2:其他用户收到该用户的StateVector后,用各自的本地数据计算出最小所需Update数据,然后发回给待同步用户。

7. 参考文献

[1] https://zhuanlan.zhihu.com/p/452980520

[2] https://juejin.cn/post/7027487213525041166

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/171126.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

IDEA创建SpringBoot的Web项目,并使用外部Tomcat

IDEA创建SpringBoot的Web项目&#xff0c;并使用外部Tomcat 目录IDEA创建SpringBoot的Web项目&#xff0c;并使用外部Tomcat一、创建工程二、使用外部Tomcat一、创建工程 1.首先新建一个springboot的war工程&#xff0c;并且将外部的Tomcat整合进我们的idea中&#xff0c;我们…

GW1NSR-LV4CQN48GC6/I5 FPGA呼吸灯

环境 pwm.v $ cat pwm.v module Pwm( input clk, input [31:0] period, input [31:0] duty, output pwmout ); reg [31:0] counter; reg r_pwmout; always (posedge clk) begin if(counter < duty) begin r_pwmout 1; end…

裸机与RTOS到FreeRTOS基础 | FreeRTOS一

目录 一、裸机与RTOS 1.1、裸机 1.2、RTOS 二、FreeRTOS简介 2.1、介绍 2.2、特点 2.3、如何查找相关资料 三、FreeROTS基础 3.1、任务调度 3.2、任务状态 一、裸机与RTOS 1.1、裸机 不带操作系统&#xff0c;又称为前后台系统&#xff0c;前台系统指中断服务函数&a…

docker搭建Openldapphpldapadmin

1&#xff1a;拉取镜像 docker pull osixia/openldap:1.5.0 docker pull osixia/phpldapadmin:0.9.0 2: 编写docker-compose.yaml cd /data/docker/ldap vi docker-compose.yaml docker-compose.yaml内容如下&#xff1a; version: 3.1 services:openldap:image: osixia/o…

python入门常用知识

文章目录前言一、定义二、Tips1.常用方法2. 常用modulestatistics 统计分析常用模块SciPy 算法及统计分析库总结前言 本文用来记录在使用python时一些基础的定义、基础用法或Tips。 一、定义 多变量定义&#xff1a; a, b, c 0, 0, 0数组定义&#xff1a; # 变量定义 a …

CANN 2022 | 开放升级,跃升新台阶

每一位开发者&#xff0c;都是改变世界的力量每一位开发者&#xff0c;都在创造一往无前的AI时代每一位开发者&#xff0c;都在2022砥砺前行&#xff0c;期待在2023再露锋芒逆光而行&#xff0c;只为拂晓回忆2022&#xff0c;哪些年度关键事件让你记忆犹新&#xff1f;是披星戴…

聊聊红黑树,B/B+树和键树

RB树 RB树和AVL树类似&#xff0c;是一种自平衡式的平衡二叉搜索树&#xff0c;AVL不是保证平衡因子不能超过1&#xff0c;红黑的话没有这个要求&#xff0c;他的结点非黑即红&#xff0c;可以达到Logn的查找&#xff0c;插入&#xff0c;删除 RB树的五条性质&#xff1a; 1…

【markdown】语法 添加`emoji`表情

&#x1f4bb; 【markdown】语法添加emoji表情&#x1f3e0;专栏&#xff1a;其他 &#x1f440;个人主页&#xff1a;繁星学编程&#x1f341; &#x1f9d1;个人简介&#xff1a;一个不断提高自我的平凡人&#x1f680; &#x1f50a;分享方向&#xff1a;目前主攻前端&#…

与资源限制有关的题目

文章目录0、资源限制技巧汇总1、题目一&#xff1a;40亿个数&#xff0c;内存限制为1G&#xff0c;如何找到出现次数最多的数2、题目二&#xff1a;40亿个数&#xff0c;内存限制为10MB&#xff0c;找到所有未出现过的数进阶问题1&#xff1a;40亿个数&#xff0c;内存限制为3K…

【计算机体系结构-02】机器模型

1. 机器模型 (Machine Model) 计算机的基本工作就是进行运算&#xff0c;那么计算就需要有用来处理计算方法的处理单元和提供或保存数值的存储单元。一般将用来处理计算方法的处理单元称为 算术逻辑单元 (ALU--Arithmetic Logic Unit)。在一个计算过程中可能会是这样的一个流程…

springboot整合flowable

自动部署 流程图提前画好&#xff0c;放入 指定文件夹 配置&#xff1a; spring.datasource.usernameroot spring.datasource.passwordroot # nullCatalogMeansCurrenttrue 自动生成表 spring.datasource.urljdbc:mysql:///flowable_process?serverTimezoneUTC&nullCat…

CISP_VULHUB_HACK ME PLEASE

vulhub_HACK ME PLEASE简介扫描开放端口探测web服务搜集seedms的信息登录mysql&#xff0c;尝试获得seeddms的密码利用RCE漏洞提权简介 靶机链接&#xff1a;https://www.vulnhub.com/entry/hack-me-please-1,731/难度&#xff1a;简单描述&#xff1a;一个完全为OSCP设计的简…

数据结构之经典八大排序的实现(万字详谈)

文章目录前言1.插入排序2.希尔排序3.选择排序4.堆排序5.冒泡排序6.快速排序hoare方式版本快排实现非递归方式实现快排挖坑法实现快排前后指针法(双指针法&#xff09;快排的各种优化1.减少后几层的递归调用(小区间优化&#xff09;2.三数取中优化3.三路划分(处理大量重复数据&a…

信息论复习—信息的度量

目录 离散信源信息的度量&#xff1a; 离散信源的信息量&#xff1a; 单符号离散无记忆信源&#xff1a; 离散无记忆信源及熵&#xff1a; 自信息&#xff1a; 信息量的定义&#xff1a; 信息熵的定义&#xff1a; 熵的性质&#xff1a; 离散信源的最大熵定理&#xf…

Elasticsearch高级查询—— 关键字精确查询文档

目录一、初始化文档数据二、字段匹配查询文档2.1、概述2.2、示例一、初始化文档数据 在 Postman 中&#xff0c;向 ES 服务器发 POST 请求 &#xff1a;http://localhost:9200/user/_doc/1&#xff0c;请求体内容为&#xff1a; {"name":"张三","age&…

LINUX学习之了解系统目录结构(一)

前言 Linux 系统目录结构是一个由各种目录和文件组成的树形结构&#xff0c;每个目录都有特定的用途。在这篇文章中&#xff0c;我们将讨论 Linux 系统中最常见的目录&#xff0c;并解释它们的用途 登录系统后输入ls命令查看系统目录 树状目录结构图 系统常用目录 目录名描述…

单目相机标定实现--张正友标定法

文章目录一&#xff1a;相机坐标系&#xff0c;像素平面坐标系&#xff0c;世界坐标系&#xff0c;归一化坐标系介绍1&#xff1a;概述公式二:实现1&#xff1a;整体流程4&#xff1a;求出每张图像的单应性矩阵并用LMA优化5&#xff1a;求解理想无畸变情况下的摄像机的内参数和…

SpringBoot项目集成liquibase,数据库版本控制解决方案

liquibase 数据库版本留痕解决方案&#xff0c;在实际生产过程中如何高效管理数据库的DDL与DML语句&#xff0c;对这些语句留痕处理。如果能将sql的执行与SpringBoot项目启动结合在一起&#xff0c;每次启动项目自动执行新增的sql语句&#xff0c;这样就可以使得项目组成员各个…

在 VMware Workstation 16 Pro 中安装 Ubuntu Server 22.04.1 并配置静态 IP 地址

文章目录1.下载 Ubuntu Server 22.04.12.新建虚拟机向导3.编辑虚拟机设置4.开启此虚拟机并配置Ubuntu系统5.设置 root 用户的密码6.允许远程连接 root 用户7.配置静态 IP 地址7.1 查看 Windows 的网络信息7.2 查看 Ubuntu 的网络信息7.3 修改配置文件7.4 测试 Windows 能否互相…

springcloud--xxl-job

xxl-job 虽然java自带定时器&#xff0c;但是在springcloud内&#xff0c;如果对多个模块进行统一任务调度&#xff0c;这是自带的定时器就显得不够用&#xff0c;这时就可以使用xxl-job。 xxl-job是一个轻量级分布式任务调度平台&#xff0c;其核心设计目标是开发迅速、学习…