实现一个CRDT工具库——ORSet
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的更多相关文章
- 如何手写一个js工具库?同时发布到npm上
自从工作以来,写项目的时候经常需要手写一些方法和引入一些js库 JS基础又十分重要,于是就萌生出自己创建一个JS工具库并发布到npm上的想法 于是就创建了一个名为learnjts的项目,在空余时间也写 ...
- [js高手之路] 跟GhostWu一起封装一个字符串工具库-架构篇(1)
所谓字符串工具库就是利用javascript面向对象的知识封装一个常用的字符串处理方法库,首先给这个库起个名字,好吧就叫ghostwu.js. 看下ghostwu.js的整体架构: ; (functi ...
- [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展trim,trimLeft,trimRight方法(2)
我们接着上一篇的继续,在上一篇我们完成了工具库的架构,本文扩展字符串去空格的方法, 一共有3个 1,trimLeft: 去除字符串左边的空格 2,trimRight: 去除字符串右边的空格 3,tri ...
- [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展字符串位置方法(4)
本文,我们接着之前的框架继续扩展,这次扩展了一共有5个与字符串位置相关的方法 between( left, right ) 返回两个字符串之间的内容, 如果第二个参数没有传递,返回的是找到的第一个参数 ...
- [js高手之路] 跟GhostWu一起封装一个字符串工具库-扩展camelize与dasherize方法(3)
在此之前,我们已经完成了4个方法: trimLeft, trimRight, trim, capitalize 本文,我们扩展驼峰式与下划线转化这两个对称的方法 camelize: 把空格,下划线,中 ...
- 一个PHP高性能、多并发、restful的工具库(基于multi_curl)
This is high performance curl wrapper written in pure PHP. It's compatible with PHP 5.4+ and HHVM. N ...
- Underscore.js工具库
Underscore 是一个 JavaScript 工具库,它提供了一整套函数式编程的实用功能,但是没有扩展任何 JavaScript 内置对象. 他解决了这个问题:“如果我面对一个空白的 HTML ...
- JavaScript工具库
jPublic 交流QQ群:1017567122 前言 在我们开发项目的时候,无论项目规模大小,在所难免会写一些工具型函数来解决一些问题,随着项目开发和维护的时间越来越长,这些工具型函数会越来越多,同 ...
- 手把手教你使用Rollup打包📦并发布自己的工具库🔧
DevUI是一支兼具设计视角和工程视角的团队,服务于华为云DevCloud平台和华为内部数个中后台系统,服务于设计师和前端工程师. 官方网站:devui.design Ng组件库:ng-devui(欢 ...
- 自己的一个LESS工具函数库
自己大概在一年前开始使用LESS编写样式,现在感觉不用LESS都不会写样式了.现在写静态页面完全离不开LESS与Zen Coding,我可以不用什么IDE,但这两个工具却必须要,当然也强烈推荐看到这篇 ...
随机推荐
- TensorFlow架构
Tensorflow基本信息 Tensorflow所需处理器 CPU,GPU,TPU(Google为AI研发的专用芯片) 平台 Windows,Linux,Android,iOS,Raspberry ...
- Java下 BigDecimal类型数值的计算(转)
BigDecimal bignum1 = new BigDecimal("40"); BigDecimal bignum2 = new BigDecimal("7&quo ...
- vue+element-ui+sortable.js实现表格行和列的拖拽
项目碰到一个需求是需要表格字段列进行顺序拖拽,查过一些资料,中途也碰到了很多坑,实现方式如下: 封装成公用组件操作 //父组件 <template> <div> <com ...
- jenkins - Asp.net 环境搭建(Windows)
jenkins - Asp.net 环境搭建(Windows) 安装环境 通过 Chocolatey自动安装 choco install ojdkbuild11 #或 choco install jd ...
- 对象和类复习题(c++ prime plus )
第一题: 为复习题5描述的类提供方法定义,并编写一个小程序来演示所有的特性: bank.h #ifndef BACK_H_ #define BACK_H_ #include <string> ...
- 微信小程序通过经纬度计算两点之间距离
小程序中通过经纬度计算两点之间的距离km 1.拾取两地经纬度坐标 . data:{ //当前定位位置 latitude: null, longitude: null, // 目的地坐标 latitud ...
- LeetCode刷题感想之滑动窗口
发现滑动窗口也是一种经典解题思路,这一篇简单聊一下滑动窗口. 通常在碰到求XX子数组,子字符串,连续XX等题眼,可以考试用滑动窗口的思路来解决问题. 窗口的类型有几种: 1. 固定长度的窗口. 2. ...
- Ajax属性
如何创建一个 Ajax <script> window.onload=function(){ 1)创建一个异步调用对象 va ...
- centos7 为文件夹添加写入权限
[root@VM-16-15-centos ~]# sudo su[root@VM-16-15-centos ~]# cd /www/wwwroot/www.htqq.sale/php/images[ ...
- HBuilder开发uniapp项目使用高德地图相关配置(整理)
一.高德地图开放平台申请key 1.进入高德地图开放平台 -> 登录或注册 -> 点击进入控制台主页 2.点击应用管理 -> 点击创建新应用 3.输入并选择应用类型 -> 点击 ...