@@ -26,14 +26,15 @@ pub struct Buffer {
26
26
lamport_clock : LamportTimestamp ,
27
27
fragments : Tree < Fragment > ,
28
28
insertions : HashMap < ChangeId , Tree < FragmentMapping > > ,
29
- position_cache : RefCell < HashMap < Anchor , ( usize , Point ) > > ,
29
+ anchor_cache : RefCell < HashMap < Anchor , ( usize , Point ) > > ,
30
+ offset_cache : RefCell < HashMap < Point , usize > > ,
30
31
pub version : NotifyCell < Version >
31
32
}
32
33
33
34
#[ derive( Clone , Copy , Debug ) ]
34
35
pub struct Version ( LocalTimestamp ) ;
35
36
36
- #[ derive( Clone , Copy , Eq , PartialEq , Debug ) ]
37
+ #[ derive( Clone , Copy , Eq , PartialEq , Debug , Hash ) ]
37
38
pub struct Point {
38
39
pub row : u32 ,
39
40
pub column : u32
@@ -146,7 +147,8 @@ impl Buffer {
146
147
lamport_clock : 0 ,
147
148
fragments,
148
149
insertions : HashMap :: new ( ) ,
149
- position_cache : RefCell :: new ( HashMap :: new ( ) ) ,
150
+ anchor_cache : RefCell :: new ( HashMap :: new ( ) ) ,
151
+ offset_cache : RefCell :: new ( HashMap :: new ( ) ) ,
150
152
version : NotifyCell :: new ( Version ( 0 ) )
151
153
}
152
154
}
@@ -195,7 +197,8 @@ impl Buffer {
195
197
local_timestamp : self . local_clock
196
198
} ;
197
199
self . splice_fragments ( change_id, old_range, new_text) ;
198
- self . position_cache . borrow_mut ( ) . clear ( ) ;
200
+ self . anchor_cache . borrow_mut ( ) . clear ( ) ;
201
+ self . offset_cache . borrow_mut ( ) . clear ( ) ;
199
202
self . version . set ( Version ( self . local_clock ) ) ;
200
203
}
201
204
}
@@ -392,17 +395,13 @@ impl Buffer {
392
395
let fragment = cursor. item ( ) . unwrap ( ) ;
393
396
let offset_in_fragment = offset - cursor. start :: < CharacterCount > ( ) . 0 ;
394
397
let offset_in_insertion = fragment. start_offset + offset_in_fragment;
398
+ let point = cursor. start :: < Point > ( ) + & fragment. point_for_offset ( offset_in_fragment) ?;
395
399
let anchor = Anchor ( AnchorInner :: Middle {
396
400
insertion_id : fragment. insertion . id ,
397
401
offset : offset_in_insertion,
398
402
bias
399
403
} ) ;
400
-
401
- if let Ok ( mut position_cache) = self . position_cache . try_borrow_mut ( ) {
402
- let point = cursor. start :: < Point > ( ) + & fragment. point_for_offset ( offset_in_fragment) ?;
403
- position_cache. insert ( anchor. clone ( ) , ( offset, point. clone ( ) ) ) ;
404
- }
405
-
404
+ self . cache_position ( Some ( anchor. clone ( ) ) , offset, point) ;
406
405
Ok ( anchor)
407
406
}
408
407
@@ -448,12 +447,8 @@ impl Buffer {
448
447
offset : offset_in_insertion,
449
448
bias
450
449
} ) ;
451
-
452
- if let Ok ( mut position_cache) = self . position_cache . try_borrow_mut ( ) {
453
- let offset = cursor. start :: < CharacterCount > ( ) . 0 + offset_in_fragment;
454
- position_cache. insert ( anchor. clone ( ) , ( offset, point. clone ( ) ) ) ;
455
- }
456
-
450
+ let offset = cursor. start :: < CharacterCount > ( ) . 0 + offset_in_fragment;
451
+ self . cache_position ( Some ( anchor. clone ( ) ) , offset, point) ;
457
452
Ok ( anchor)
458
453
}
459
454
@@ -470,13 +465,13 @@ impl Buffer {
470
465
& AnchorInner :: Start => Ok ( ( 0 , Point { row : 0 , column : 0 } ) ) ,
471
466
& AnchorInner :: End => Ok ( ( self . len ( ) , self . fragments . len :: < Point > ( ) ) ) ,
472
467
& AnchorInner :: Middle { ref insertion_id, offset, ref bias } => {
473
- let position = {
474
- let position_cache = self . position_cache . try_borrow ( ) ;
475
- position_cache . ok ( ) . and_then ( |position_cache| position_cache . get ( & anchor) . cloned ( ) )
468
+ let cached_position = {
469
+ let anchor_cache = self . anchor_cache . try_borrow ( ) . ok ( ) ;
470
+ anchor_cache . as_ref ( ) . and_then ( |cache| cache . get ( anchor) . cloned ( ) )
476
471
} ;
477
472
478
- if position . is_some ( ) {
479
- Ok ( position . unwrap ( ) )
473
+ if let Some ( cached_position ) = cached_position {
474
+ Ok ( cached_position )
480
475
} else {
481
476
let seek_bias = match bias {
482
477
& AnchorBias :: Left => SeekBias :: Left ,
@@ -497,11 +492,7 @@ impl Buffer {
497
492
} ;
498
493
let offset = fragments_cursor. start :: < CharacterCount > ( ) . 0 + overshoot;
499
494
let point = fragments_cursor. start :: < Point > ( ) + & fragment. point_for_offset ( overshoot) ?;
500
-
501
- if let Ok ( mut position_cache) = self . position_cache . try_borrow_mut ( ) {
502
- position_cache. insert ( anchor. clone ( ) , ( offset, point) ) ;
503
- }
504
-
495
+ self . cache_position ( Some ( anchor. clone ( ) ) , offset, point) ;
505
496
Ok ( ( offset, point) )
506
497
} )
507
498
} )
@@ -511,19 +502,42 @@ impl Buffer {
511
502
}
512
503
513
504
fn offset_for_point ( & self , point : Point ) -> Result < usize > {
514
- let mut fragments_cursor = self . fragments . cursor ( ) ;
515
- fragments_cursor. seek ( & point, SeekBias :: Left ) ;
516
- fragments_cursor. item ( ) . ok_or ( Error :: OffsetOutOfRange ) . map ( |fragment| {
517
- let overshoot = fragment. offset_for_point ( point - & fragments_cursor. start :: < Point > ( ) ) . unwrap ( ) ;
518
- & fragments_cursor. start :: < CharacterCount > ( ) . 0 + & overshoot
519
- } )
505
+ let cached_offset = {
506
+ let offset_cache = self . offset_cache . try_borrow ( ) . ok ( ) ;
507
+ offset_cache. as_ref ( ) . and_then ( |cache| cache. get ( & point) . cloned ( ) )
508
+ } ;
509
+
510
+ if let Some ( cached_offset) = cached_offset {
511
+ Ok ( cached_offset)
512
+ } else {
513
+ let mut fragments_cursor = self . fragments . cursor ( ) ;
514
+ fragments_cursor. seek ( & point, SeekBias :: Left ) ;
515
+ fragments_cursor. item ( ) . ok_or ( Error :: OffsetOutOfRange ) . map ( |fragment| {
516
+ let overshoot = fragment. offset_for_point ( point - & fragments_cursor. start :: < Point > ( ) ) . unwrap ( ) ;
517
+ let offset = & fragments_cursor. start :: < CharacterCount > ( ) . 0 + & overshoot;
518
+ self . cache_position ( None , offset, point) ;
519
+ offset
520
+ } )
521
+ }
520
522
}
521
523
522
524
pub fn cmp_anchors ( & self , a : & Anchor , b : & Anchor ) -> Result < cmp:: Ordering > {
523
525
let a_offset = self . offset_for_anchor ( a) ?;
524
526
let b_offset = self . offset_for_anchor ( b) ?;
525
527
Ok ( a_offset. cmp ( & b_offset) )
526
528
}
529
+
530
+ fn cache_position ( & self , anchor : Option < Anchor > , offset : usize , point : Point ) {
531
+ anchor. map ( |anchor| {
532
+ if let Ok ( mut anchor_cache) = self . anchor_cache . try_borrow_mut ( ) {
533
+ anchor_cache. insert ( anchor, ( offset, point) ) ;
534
+ }
535
+ } ) ;
536
+
537
+ if let Ok ( mut offset_cache) = self . offset_cache . try_borrow_mut ( ) {
538
+ offset_cache. insert ( point, offset) ;
539
+ }
540
+ }
527
541
}
528
542
529
543
impl Point {
0 commit comments