@@ -767,6 +767,42 @@ pub(crate) struct BitmapBatchLayer<const N: usize> {
767767
768768impl < const N : usize > BitmapBatch < N > {
769769 const CHUNK_SIZE_BITS : u64 = BitMap :: < N > :: CHUNK_SIZE_BITS ;
770+
771+ /// Walk to the terminal [`SharedBitmap`] at the bottom of the chain.
772+ fn shared ( & self ) -> & Arc < SharedBitmap < N > > {
773+ let mut current = self ;
774+ loop {
775+ match current {
776+ Self :: Base ( s) => return s,
777+ Self :: Layer ( layer) => current = & layer. parent ,
778+ }
779+ }
780+ }
781+
782+ /// Return a chain equivalent to `self` with any `Layer` whose overlay is now fully committed
783+ /// replaced by a direct reference to the committed bitmap. Since `apply_batch` commits
784+ /// contiguous prefixes, committed `Layer`s are always at the bottom of the chain.
785+ fn trim_committed ( & self ) -> Self {
786+ let shared = self . shared ( ) ;
787+ let committed = shared. read ( ) . len ( ) ;
788+ let mut kept: Vec < Arc < ChunkOverlay < N > > > = Vec :: new ( ) ;
789+ let mut current = self ;
790+ while let Self :: Layer ( layer) = current {
791+ if layer. overlay . len <= committed {
792+ let mut result = Self :: Base ( Arc :: clone ( shared) ) ;
793+ for overlay in kept. into_iter ( ) . rev ( ) {
794+ result = Self :: Layer ( Arc :: new ( BitmapBatchLayer {
795+ parent : result,
796+ overlay,
797+ } ) ) ;
798+ }
799+ return result;
800+ }
801+ kept. push ( Arc :: clone ( & layer. overlay ) ) ;
802+ current = & layer. parent ;
803+ }
804+ self . clone ( )
805+ }
770806}
771807
772808impl < const N : usize > BitmapReadable < N > for BitmapBatch < N > {
@@ -861,7 +897,7 @@ where
861897 UnmerkleizedBatch :: new (
862898 self . inner . new_batch :: < H > ( ) ,
863899 Arc :: clone ( & self . grafted ) ,
864- self . bitmap . clone ( ) ,
900+ self . bitmap . trim_committed ( ) ,
865901 )
866902 }
867903
0 commit comments