1
- use std:: { io:: Write , process:: Stdio } ;
2
-
3
1
use bstr:: { BStr , BString , ByteSlice } ;
2
+ use std:: cmp:: Ordering ;
3
+ use std:: { io:: Write , process:: Stdio } ;
4
4
5
5
use super :: Algorithm ;
6
6
use crate :: blob:: { pipeline, Pipeline , Platform , ResourceKind } ;
@@ -325,6 +325,7 @@ impl Platform {
325
325
old : None ,
326
326
new : None ,
327
327
diff_cache : Default :: default ( ) ,
328
+ free_list : Vec :: with_capacity ( 2 ) ,
328
329
options,
329
330
filter,
330
331
filter_mode,
@@ -542,7 +543,7 @@ impl Platform {
542
543
543
544
/// Every call to [set_resource()](Self::set_resource()) will keep the diffable data in memory, and that will never be cleared.
544
545
///
545
- /// Use this method to clear the cache, releasing memory. Note that this will also loose all information about resources
546
+ /// Use this method to clear the cache, releasing memory. Note that this will also lose all information about resources
546
547
/// which means diffs would fail unless the resources are set again.
547
548
///
548
549
/// Note that this also has to be called if the same resource is going to be diffed in different states, i.e. using different
@@ -551,6 +552,37 @@ impl Platform {
551
552
self . old = None ;
552
553
self . new = None ;
553
554
self . diff_cache . clear ( ) ;
555
+ self . free_list . clear ( ) ;
556
+ }
557
+
558
+ /// Every call to [set_resource()](Self::set_resource()) will keep the diffable data in memory, and that will never be cleared.
559
+ ///
560
+ /// Use this method to clear the cache, but keep the previously used buffers around for later re-use.
561
+ ///
562
+ /// If there are more buffers on the free-list than there are stored sources, we half that amount each time this method is called,
563
+ /// or keep as many resources as were previously stored, or 2 buffers, whatever is larger.
564
+ /// If there are fewer buffers in the free-list than are in the resource cache, we will keep as many as needed to match the
565
+ /// number of previously stored resources.
566
+ ///
567
+ /// Returns the number of available buffers.
568
+ pub fn clear_resource_cache_keep_allocation ( & mut self ) -> usize {
569
+ self . old = None ;
570
+ self . new = None ;
571
+
572
+ let diff_cache = std:: mem:: take ( & mut self . diff_cache ) ;
573
+ match self . free_list . len ( ) . cmp ( & diff_cache. len ( ) ) {
574
+ Ordering :: Less => {
575
+ let to_take = diff_cache. len ( ) - self . free_list . len ( ) ;
576
+ self . free_list
577
+ . extend ( diff_cache. into_values ( ) . map ( |v| v. buffer ) . take ( to_take) ) ;
578
+ }
579
+ Ordering :: Equal => { }
580
+ Ordering :: Greater => {
581
+ let new_len = ( self . free_list . len ( ) / 2 ) . max ( diff_cache. len ( ) ) . max ( 2 ) ;
582
+ self . free_list . truncate ( new_len) ;
583
+ }
584
+ }
585
+ self . free_list . len ( )
554
586
}
555
587
}
556
588
@@ -591,7 +623,7 @@ impl Platform {
591
623
kind,
592
624
rela_path : rela_path. to_owned ( ) ,
593
625
} ) ?;
594
- let mut buf = Vec :: new ( ) ;
626
+ let mut buf = self . free_list . pop ( ) . unwrap_or_default ( ) ;
595
627
let out = self . filter . convert_to_diffable (
596
628
& id,
597
629
mode,
0 commit comments