@@ -3,6 +3,7 @@ import type {RemoteBlockPatch} from '../../remote/types';
33import type { ServerCrudLocalHistoryCore } from './ServerCrudLocalHistoryCore' ;
44import type { BlockSyncMetadata } from './types' ;
55import { SESSION } from 'json-joy/lib/json-crdt-patch/constants' ;
6+ import { ts } from 'json-joy/lib/json-crdt-patch' ;
67
78const 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