ORSet

这段代码实现了OR-Set,是一种基于版本向量的CRDT,用于实现集合的合并。OR-Set由两个集合add和remove组成,add集合存储添加的元素,remove集合存储删除的元素。每个元素都有一个版本向量,用于标识该元素的添加和删除操作。其中,add集合中的元素版本向量的值大于remove集合中的元素版本向量的值,表示该元素是存在的。OR-Set支持添加和删除元素,以及合并两个OR-Set。其中,添加元素时,会将该元素的版本向量加1,删除元素时,会将该元素的版本向量加1并放入remove集合中。合并两个OR-Set时,会将两个OR-Set的add集合和remove集合分别合并,然后将remove集合中版本向量小于add集合中版本向量的元素从remove集合中删除,最后返回合并后的OR-Set。

import VClock

def ORSet():
return (dict(), dict()) def zero():
return ORSet() def value(s: ORSet):
add, rem = s
return {key for key in set(add.keys()) | set(rem.keys())
if VClock.compare(add.get(key, VClock.zero()), rem.get(key, VClock.zero())) != VClock.Ord.Lt} def add(s: ORSet, replica_id, value):
add, rem = s
add[value] = VClock.inc(add.get(value, VClock.zero()), replica_id)
print(add[value]) def rem(s: ORSet, replica_id, value):
add, rem = s
rem[value] = VClock.inc(rem.get(value, VClock.zero()), replica_id) def merge(s1: ORSet, s2: ORSet):
add_1, rem_1 = s1
add_2, rem_2 = s2 merged_add = { key: VClock.merge(add_1.get(key, VClock.zero()), add_2.get(key, VClock.zero()))
for key in set(add_1.keys()) | set(add_2.keys()) } merged_rem = { key: VClock.merge(rem_1.get(key, VClock.zero()), rem_2.get(key, VClock.zero()))
for key in set(rem_1.keys()) | set(rem_2.keys()) } cleared_merged_rem = { key: merged_rem[key] for key in set(merged_rem.keys())
if VClock.compare(merged_add.get(key, VClock.zero()), merged_rem[key]) == VClock.Ord.Lt or
VClock.compare(merged_add.get(key, VClock.zero()), merged_rem[key]) == VClock.Ord.Cc } return (merged_add, cleared_merged_rem)
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set; public class ORSet {
private Map<String, Map<Integer, Integer>> add;
private Map<String, Map<Integer, Integer>> rem; public ORSet() {
add = new HashMap<>();
rem = new HashMap<>();
} public static ORSet zero() {
return new ORSet();
} public Set<String> value() {
Set<String> res = new HashSet<>();
for (String key : add.keySet()) {
if (!rem.containsKey(key) || !compare(add.get(key), rem.get(key)).equals(Ord.Lt)) {
res.add(key);
}
}
for (String key : rem.keySet()) {
if (!add.containsKey(key)) {
res.add(key);
}
}
return res;
} public void add(int replica_id, String value) {
if (!add.containsKey(value)) {
add.put(value, new HashMap<>());
}
Map<Integer, Integer> clock = add.get(value);
clock.put(replica_id, clock.getOrDefault(replica_id, 0) + 1);
} public void rem(int replica_id, String value) {
if (!rem.containsKey(value)) {
rem.put(value, new HashMap<>());
}
Map<Integer, Integer> clock = rem.get(value);
clock.put(replica_id, clock.getOrDefault(replica_id, 0) + 1);
} public void merge(ORSet other) {
for (String key : other.add.keySet()) {
if (!add.containsKey(key)) {
add.put(key, new HashMap<>());
}
Map<Integer, Integer> clock = add.get(key);
for (Map.Entry<Integer, Integer> entry : other.add.get(key).entrySet()) {
int replica_id = entry.getKey();
int timestamp = entry.getValue();
clock.put(replica_id, Math.max(clock.getOrDefault(replica_id, 0), timestamp));
}
}
for (String key : other.rem.keySet()) {
if (!rem.containsKey(key)) {
rem.put(key, new HashMap<>());
}
Map<Integer, Integer> clock = rem.get(key);
for (Map.Entry<Integer, Integer> entry : other.rem.get(key).entrySet()) {
int replica_id = entry.getKey();
int timestamp =

实现一个CRDT工具库——ORSet的更多相关文章

  1. 如何手写一个js工具库?同时发布到npm上

    自从工作以来,写项目的时候经常需要手写一些方法和引入一些js库 JS基础又十分重要,于是就萌生出自己创建一个JS工具库并发布到npm上的想法 于是就创建了一个名为learnjts的项目,在空余时间也写 ...

  2. [js高手之路] 跟GhostWu一起封装一个字符串工具库-架构篇(1)

    所谓字符串工具库就是利用javascript面向对象的知识封装一个常用的字符串处理方法库,首先给这个库起个名字,好吧就叫ghostwu.js. 看下ghostwu.js的整体架构: ; (functi ...

  3. [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展trim,trimLeft,trimRight方法(2)

    我们接着上一篇的继续,在上一篇我们完成了工具库的架构,本文扩展字符串去空格的方法, 一共有3个 1,trimLeft: 去除字符串左边的空格 2,trimRight: 去除字符串右边的空格 3,tri ...

  4. [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展字符串位置方法(4)

    本文,我们接着之前的框架继续扩展,这次扩展了一共有5个与字符串位置相关的方法 between( left, right ) 返回两个字符串之间的内容, 如果第二个参数没有传递,返回的是找到的第一个参数 ...

  5. [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展camelize与dasherize方法(3)

    在此之前,我们已经完成了4个方法: trimLeft, trimRight, trim, capitalize 本文,我们扩展驼峰式与下划线转化这两个对称的方法 camelize: 把空格,下划线,中 ...

  6. 一个PHP高性能、多并发、restful的工具库(基于multi_curl)

    This is high performance curl wrapper written in pure PHP. It's compatible with PHP 5.4+ and HHVM. N ...

  7. Underscore.js工具库

    Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:“如果我面对一个空白的 HTML ...

  8. JavaScript工具库

    jPublic 交流QQ群:1017567122 前言 在我们开发项目的时候,无论项目规模大小,在所难免会写一些工具型函数来解决一些问题,随着项目开发和维护的时间越来越长,这些工具型函数会越来越多,同 ...

  9. 手把手教你使用Rollup打包📦并发布自己的工具库🔧

    DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师. 官方网站:devui.design Ng组件库:ng-devui(欢 ...

  10. 自己的一个LESS工具函数库

    自己大概在一年前开始使用LESS编写样式,现在感觉不用LESS都不会写样式了.现在写静态页面完全离不开LESS与Zen Coding,我可以不用什么IDE,但这两个工具却必须要,当然也强烈推荐看到这篇 ...

随机推荐

  1. vue+antd实现PDF预览(后端返回的是文件流)

    操作步骤: 第一步:下载包   npm install --save vue-pdf 第二步:导入组件 第三步:使用pdf标签进行展示,showUrl指的是访问路径 第四步:定义要用到的变量 第五步: ...

  2. 一键搭建dns

    #!/bin/bash DOMAIN=wang.orgHOST=wwwHOST_IP=10.0.0.100LOCALHOST=`hostname -I | awk '{print $1}'` . /e ...

  3. deepin 调整微信、百度网盘、迅雷等等软件字体的方法

    一.修改微信字体大小方法: 1.方法一:修改deepinwine桌面环境字体 env WINEPREFIX="$HOME/.deepinwine/Deepin-WeChat" wi ...

  4. 主要的原型设计工具 :Axure RP

    一. Axure RP简介: Axure RP 能帮助网站需求设计者,快捷而简便的创建基于网站构架图的带注释页面示意图.操作流程图.以及交互设计,并可自动生成用于演示的网页文件和规格文件,以提供演示与 ...

  5. vue中模块化后mapState的使用

    代码如下: 相当于声明了一个变量name,然后以state入参取得其modules文件夹中user文件里的name属性.因为在模块(如user)中,在抛出时的export default中添加了一句: ...

  6. java mysql删除表中多余的重复记录(多个字段),只留有id最小的记录

    mysql 删除表中多余的重复记录(多个字段),只留有id最小的记录 DELETE FROM 表1 f WHERE (f.字段1,f.字段2) IN ( SELECT 字段1,字段2 FROM 表1 ...

  7. 2003031120—廖威—Python数据分析第三周作业—numpy的简单操

    项目 内容 课程班级博客链接 https://edu.cnblogs.com/campus/pexy/20sj 这个作业要求链接 https://edu.cnblogs.com/campus/pexy ...

  8. python 循环 类型转换

  9. X射线随笔

    2023-02-27 千里马与伯乐 如果把X射线(X光)比做千里马的话,那这匹千里马的发掘,离不开伯乐的贡献.说起X射线的伯乐,就得从一个简短的故事说起: 1895年11月8日的夜晚,德国物理学家伦琴 ...

  10. hexo相对路径图片显示

    说明 hexo的图片默认不支持相对路径.需要配置 post_asset_folder 选项,设置从false改成true之后支持.但是要求图片目录必须和文件名相同. 由于我在typore下的markd ...