From 85a4aeedcdc1e1afb30a3094311ab2aa13632547 Mon Sep 17 00:00:00 2001 From: droak Date: Fri, 23 Aug 2024 17:23:10 +0900 Subject: [PATCH] refactor merge fn --- packages/crdt/src/builtins/OORSet/index.ts | 44 +++++++++------------- 1 file changed, 17 insertions(+), 27 deletions(-) diff --git a/packages/crdt/src/builtins/OORSet/index.ts b/packages/crdt/src/builtins/OORSet/index.ts index 44a781fd..50d8a128 100644 --- a/packages/crdt/src/builtins/OORSet/index.ts +++ b/packages/crdt/src/builtins/OORSet/index.ts @@ -51,35 +51,25 @@ export class OORSet { } merge(peerSet: OORSet): void { - let M = new Set>(); - let A = new Set>(); - let B = new Set>(); + // place: [local, remote, both] + // sets: [elements, removed] + // existence: [in, notIn] + let bothInElements = [...this._elements].filter((element) => peerSet.getElements().has(element)); + let localInElementsRemoteNotInRemoved = [...this._elements].filter((element) => + !peerSet.getElements().has(element) && element.tag > peerSet.getSummary().get(element.nodeId)! + ); + let localNotInRemovedRemoteInElements = [...peerSet._elements].filter((element) => + !this._elements.has(element) && element.tag > this.getSummary().get(element.nodeId)! + ); - // Adds the elements common to the two sets - this._elements.forEach((element) => { - if (peerSet.getElements().has(element)) { - M.add(element); - } - }); - - // in the local payload but not recently removed from the remote payload - this._elements.forEach((element) => { - const tag = peerSet.getSummary().get(element.nodeId); - if (!peerSet.getElements().has(element) && tag !== undefined && element.tag > tag) { - A.add(element); - } - }); - - //vice-versa - peerSet.getElements().forEach((element) => { - const tag = this._summary.get(element.nodeId); - if (!this._elements.has(element) && tag !== undefined && element.tag > tag) { - B.add(element); - } - }); - - this._elements = new Set>([...M, ...A, ...B]); + this._elements = new Set>([...bothInElements, ...localInElementsRemoteNotInRemoved, ...localNotInRemovedRemoteInElements]); + this._elements = new Set( + [...this._elements].filter((e) => + [...this._elements].every((e2) => e.tag > e2.tag) + ) + ); + // update summary for (let e of peerSet.getSummary().entries()) { this._summary.set(e[0], Math.max(e[1], this._summary.get(e[0])!)); }