Skip to content

Instantly share code, notes, and snippets.

@twfarland
Last active April 8, 2018 20:46
Show Gist options
  • Save twfarland/b48c97ec8feca3360982dac81462059c to your computer and use it in GitHub Desktop.
Save twfarland/b48c97ec8feca3360982dac81462059c to your computer and use it in GitHub Desktop.
Postitive - Negative Counter CvRDT
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