Skip to content

Commit bb3dc86

Browse files
committed
perf: ⚡️ find first patch using binary search
1 parent 2c60d52 commit bb3dc86

File tree

1 file changed

+14
-9
lines changed

1 file changed

+14
-9
lines changed

src/json-crdt-repo/local/server-crud/ServerCrudLocalHistorySync.ts

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {RemoteBlockPatch} from '../../remote/types';
33
import type {ServerCrudLocalHistoryCore} from './ServerCrudLocalHistoryCore';
44
import type {BlockSyncMetadata} from './types';
55
import {SESSION} from 'json-joy/lib/json-crdt-patch/constants';
6+
import {ts} from 'json-joy/lib/json-crdt-patch';
67

78
const SYNC_FILE_NAME = 'sync.cbor';
89

@@ -55,15 +56,19 @@ export class ServerCrudLocalHistorySync {
5556
const {history} = core.decoder.decode(blob, {format: 'seq.cbor', history: true});
5657
const patches: RemoteBlockPatch[] = [];
5758
let time = 0;
58-
// TODO: perf: use a binary search to find the first patch to sync.
59-
history!.patches.forEach(({v: patch}) => {
60-
const id = patch.getId();
61-
if (!id) return;
62-
if ((id.sid === core.sid || (id.sid === SESSION.GLOBAL)) && id.time > meta.time) {
63-
patches.push({blob: patch.toBinary()});
64-
time = id.time;
65-
}
66-
});
59+
const patchTree = history!.patches;
60+
let node = patchTree.getOrNextLower(ts(0, meta.time)) || patchTree.first();
61+
if (node) {
62+
do {
63+
const {k: id, v: patch} = node;
64+
const patchSid = id.sid;
65+
const patchTime = id.time;
66+
if ((patchSid === core.sid || (patchSid === SESSION.GLOBAL)) && (patchTime > meta.time)) {
67+
patches.push({blob: patch.toBinary()});
68+
time = patchTime;
69+
}
70+
} while (node = patchTree.next(node));
71+
}
6772
if (!patches.length) {
6873
await this.putMeta(collection, id, {time, ts: Date.now()});
6974
return true;

0 commit comments

Comments
 (0)