-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy path6-lww-set.js
More file actions
78 lines (65 loc) · 1.81 KB
/
6-lww-set.js
File metadata and controls
78 lines (65 loc) · 1.81 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
'use strict';
class LWWSet {
#added;
#removed;
constructor({ added = {}, removed = {} } = {}) {
this.#added = { ...added };
this.#removed = { ...removed };
}
add(item, timestamp = Date.now()) {
const prev = this.#added[item] || 0;
if (timestamp > prev) this.#added[item] = timestamp;
}
remove(item, timestamp = Date.now()) {
const prev = this.#removed[item] || 0;
if (timestamp > prev) this.#removed[item] = timestamp;
}
merge(instance) {
const added = Object.entries(instance.added);
for (const [item, timestamp] of added) {
const prev = this.#added[item] || 0;
if (timestamp > prev) this.#added[item] = timestamp;
}
const removed = Object.entries(instance.removed);
for (const [item, timestamp] of removed) {
const prev = this.#removed[item] || 0;
if (timestamp > prev) this.#removed[item] = timestamp;
}
}
get value() {
const result = [];
for (const item of Object.keys(this.#added)) {
const addTime = this.#added[item];
const removeTime = this.#removed[item] || 0;
if (addTime > removeTime) result.push(item);
}
return result;
}
get added() {
return this.#added;
}
get removed() {
return this.#removed;
}
}
// Usage
console.log('Replica 0');
const set0 = new LWWSet();
set0.add('a', 1);
set0.add('b', 2);
set0.remove('a', 3);
console.log({ id0: set0.value });
console.log('Replica 1');
const set1 = new LWWSet();
set1.add('b', 1);
set1.add('c', 2);
set1.remove('b', 3);
console.log({ id1: set1.value });
console.log('Sync');
set0.merge(set1);
set1.merge(set0);
console.log({ id0: { added: set0.added, removed: set0.removed } });
console.log({ id1: { added: set1.added, removed: set1.removed } });
console.log('Get value');
console.log({ id0: set0.value });
console.log({ id1: set1.value });