Last active
April 8, 2018 20:46
-
-
Save twfarland/b48c97ec8feca3360982dac81462059c to your computer and use it in GitHub Desktop.
Postitive - Negative Counter CvRDT
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
function uuid(): string { | |
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, c => { | |
var r = Math.random() * 16 | 0, v = c == 'x' ? r : (r & 0x3 | 0x8) | |
return v.toString(16) | |
}) | |
} | |
type NumberMap = { [id: string]: number } | |
class PNCounter { | |
id: string | |
ps: NumberMap | |
ns: NumberMap | |
constructor() { | |
let id = uuid() | |
this.id = id | |
this.ps[id] = 0 | |
this.ns[id] = 0 | |
} | |
incr(n: number) { | |
this.ps[this.id] += n | |
} | |
decr(n: number) { | |
this.ns[this.id] -= n | |
} | |
query() { | |
let value = 0 | |
for (let id in this.ps) { value += this.ps[id] } | |
for (let id in this.ns) { value += this.ns[id] } | |
return value | |
} | |
merge(c: PNCounter) { | |
this.ps = this._merge(this.ps, c.ps, Math.max) | |
this.ns = this._merge(this.ns, c.ns, Math.min) | |
} | |
private _merge(xs: NumberMap, ys: NumberMap, fn: (x: number, y: number) => number): NumberMap { | |
let merged = {} | |
for (let id in xs) { merged[id] = 1 } | |
for (let id in ys) { merged[id] = 1 } | |
for (let id in merged) { merged[id] = fn(xs[id] || 0, ys[id || 0]) } | |
return merged | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment