@@ -146,12 +146,22 @@ struct MMapFile<V: ValueSerde> {
146146}
147147
148148impl < V : ValueSerde > MMapFile < V > {
149- /// Grows the file by the growth step.
150- fn grow ( & mut self ) {
149+ /// Grows the file to accommodate at least the target size.
150+ /// Grows in multiples of growth_step for efficiency.
151+ fn grow_to_target ( & mut self , target_size : usize ) {
152+ if self . size >= target_size {
153+ return ;
154+ }
151155 self . flush ( ) ;
152- let new_size = self . size + self . config . growth_step ;
156+ // Calculate how many growth steps needed, rounding up.
157+ let growth_needed = target_size. saturating_sub ( self . size ) ;
158+ let growth_steps = growth_needed. div_ceil ( self . config . growth_step ) ;
159+ let new_size = self . size + ( growth_steps * self . config . growth_step ) ;
153160 let new_size_u64 = u64:: try_from ( new_size) . expect ( "usize should fit in u64" ) ;
154- debug ! ( "Growing file to size: {}" , new_size) ;
161+ debug ! (
162+ "Growing file to size: {} (target: {}, steps: {})" ,
163+ new_size, target_size, growth_steps
164+ ) ;
155165 self . file . set_len ( new_size_u64) . expect ( "Failed to set the file size" ) ;
156166 self . size = new_size;
157167 }
@@ -162,6 +172,35 @@ impl<V: ValueSerde> MMapFile<V> {
162172 self . mmap . flush ( ) . expect ( "Failed to flush the mmap" ) ;
163173 self . should_flush = false ;
164174 }
175+
176+ /// Writes serialized data to the mmap at the current offset.
177+ /// Returns the location where data was written and updates the offset.
178+ fn write_at_current_offset ( & mut self , serialized : & [ u8 ] ) -> LocationInFile {
179+ let len = serialized. len ( ) ;
180+ let offset = self . offset ;
181+
182+ trace ! ( "Inserting object at offset: {}" , offset) ;
183+
184+ // Ensure we have enough space before writing.
185+ let final_offset = offset + len;
186+ self . grow_to_target ( final_offset) ;
187+
188+ // Copy data to mmap
189+ let mmap_slice = & mut self . mmap [ offset..final_offset] ;
190+ assert ! (
191+ mmap_slice. len( ) >= len,
192+ "Not enough space in mmap slice: available={}, needed={}" ,
193+ mmap_slice. len( ) ,
194+ len
195+ ) ;
196+ mmap_slice. copy_from_slice ( serialized) ;
197+
198+ // Update offset
199+ self . offset += len;
200+ self . should_flush = true ;
201+
202+ LocationInFile { offset, len }
203+ }
165204}
166205
167206/// Open a memory mapped file, create it if it doesn't exist.
@@ -214,11 +253,12 @@ impl<V: ValueSerde> FileHandler<V, RW> {
214253 fn grow_file_if_needed ( & mut self , offset : usize ) {
215254 let mut mmap_file = self . mmap_file . lock ( ) . expect ( "Lock should not be poisoned" ) ;
216255 if mmap_file. size < offset + mmap_file. config . max_object_size {
256+ let target_size = offset + mmap_file. config . max_object_size ;
217257 debug ! (
218- "Attempting to grow file. File size: {}, offset: {}, max_object_size: {}" ,
219- mmap_file. size, offset, mmap_file. config. max_object_size
258+ "Attempting to grow file. File size: {}, offset: {}, max_object_size: {}, target: {} " ,
259+ mmap_file. size, offset, mmap_file. config. max_object_size, target_size
220260 ) ;
221- mmap_file. grow ( ) ;
261+ mmap_file. grow_to_target ( target_size ) ;
222262 }
223263 }
224264}
0 commit comments