@@ -123,7 +123,7 @@ struct QuickListNode {
123123
124124impl QuickListNode {
125125 /// Ensures the node is decompressed. Must be called before any read/write.
126- fn ensure_decompressed ( & mut self , fill_factor : & FillFactor ) {
126+ fn ensure_decompressed ( & mut self , fill_factor : & FillFactor ) -> & mut Ziplist {
127127 let current_data =
128128 std:: mem:: replace ( & mut self . data , NodeData :: Uncompressed ( Ziplist :: default ( ) ) ) ;
129129 self . data = match current_data {
@@ -138,6 +138,9 @@ impl QuickListNode {
138138 } ,
139139 | uncompressed => uncompressed,
140140 } ;
141+
142+ let NodeData :: Uncompressed ( ziplist) = & mut self . data else { panic ! ( ) } ;
143+ ziplist
141144 }
142145
143146 /// Attempts to compress the node.
@@ -308,21 +311,13 @@ impl QuickList {
308311 if should_merge {
309312 // First, remove the next node from the list.
310313 let mut removed_node = self . nodes . remove ( index + 1 ) . unwrap ( ) ;
311- removed_node. ensure_decompressed ( & self . fill_factor ) ;
314+ let removed_ziplist = removed_node. ensure_decompressed ( & self . fill_factor ) ;
312315
313316 // Now, get mutable access to the current node to merge into.
314317 let current_node = & mut self . nodes [ index] ;
315- current_node. ensure_decompressed ( & self . fill_factor ) ;
316318
317- // Use pattern matching to get the ziplists and perform the merge.
318- if let (
319- NodeData :: Uncompressed ( current_ziplist) ,
320- NodeData :: Uncompressed ( removed_ziplist) ,
321- ) = ( & mut current_node. data , & mut removed_node. data )
322- {
323- current_ziplist. extend_from_slice ( removed_ziplist) ;
324- current_node. entry_count += removed_node. entry_count ;
325- }
319+ current_node. ensure_decompressed ( & self . fill_factor ) . extend_from_slice ( removed_ziplist) ;
320+ current_node. entry_count += removed_node. entry_count ;
326321
327322 self . return_node ( removed_node) ;
328323 }
@@ -451,21 +446,21 @@ impl QuickList {
451446 }
452447
453448 // 3. Decompress the node and read its entries
454- node. ensure_decompressed ( & self . fill_factor ) ;
455- if let NodeData :: Uncompressed ( ziplist) = & node. data {
456- let entries = ziplist. to_vec ( ) ;
457- for ( i, entry) in entries. iter ( ) . enumerate ( ) {
458- let overall_index = current_index + i;
459- if overall_index >= start && overall_index <= stop {
460- // Clone the Bytes object and add it to our result.
461- // Cloning is cheap (reference counted).
462- result. push ( entry. clone ( ) ) ;
463- }
464- if overall_index >= stop {
465- break ;
466- }
449+ let ziplist = node. ensure_decompressed ( & self . fill_factor ) ;
450+
451+ let entries = ziplist. to_vec ( ) ;
452+ for ( i, entry) in entries. iter ( ) . enumerate ( ) {
453+ let overall_index = current_index + i;
454+ if overall_index >= start && overall_index <= stop {
455+ // Clone the Bytes object and add it to our result.
456+ // Cloning is cheap (reference counted).
457+ result. push ( entry. clone ( ) ) ;
458+ }
459+ if overall_index >= stop {
460+ break ;
467461 }
468462 }
463+
469464 current_index += node_len;
470465 }
471466 result
@@ -522,10 +517,8 @@ impl QuickList {
522517 let mut current_index = 0 ;
523518 for node in & mut self . nodes {
524519 if current_index + node. entry_count > index {
525- node. ensure_decompressed ( & self . fill_factor ) ;
526- if let NodeData :: Uncompressed ( ziplist) = & node. data {
527- return ziplist. to_vec ( ) . get ( index - current_index) . cloned ( ) ;
528- }
520+ let ziplist = node. ensure_decompressed ( & self . fill_factor ) ;
521+ return ziplist. to_vec ( ) . get ( index - current_index) . cloned ( ) ;
529522 }
530523 current_index += node. entry_count ;
531524 }
@@ -547,45 +540,44 @@ impl QuickList {
547540
548541 // Find the node containing this index
549542 let mut current_index = 0 ;
543+
550544 for node in & mut self . nodes {
551- if current_index + node. entry_count > abs_index {
552- let local_index = abs_index - current_index;
553-
554- node. ensure_decompressed ( & self . fill_factor ) ;
555- if let NodeData :: Uncompressed ( ziplist) = & mut node. data {
556- let new_bytes = Bytes :: from ( value) ;
557- let mut cursor = 0 ;
558-
559- // Skip to the target entry
560- for _ in 0 ..local_index {
561- let entry_len =
562- u32:: from_le_bytes ( ziplist[ cursor..cursor + 4 ] . try_into ( ) . unwrap ( ) )
563- as usize ;
564- cursor += 4 + entry_len;
565- }
545+ if current_index + node. entry_count <= abs_index {
546+ current_index += node. entry_count ;
547+ continue ;
548+ }
566549
567- let old_entry_len =
568- u32:: from_le_bytes ( ziplist[ cursor..cursor + 4 ] . try_into ( ) . unwrap ( ) )
569- as usize ;
550+ let local_index = abs_index - current_index;
570551
571- if new_bytes. len ( ) == old_entry_len {
572- // Same size - overwrite in place
573- ziplist[ cursor + 4 ..cursor + 4 + old_entry_len] . copy_from_slice ( & new_bytes) ;
574- } else {
575- // Different size - rebuild ziplist
576- let mut new_ziplist =
577- Vec :: with_capacity ( ziplist. len ( ) - old_entry_len + new_bytes. len ( ) ) ;
578- new_ziplist. extend_from_slice ( & ziplist[ 0 ..cursor] ) ;
579- new_ziplist. extend_from_slice ( & ( new_bytes. len ( ) as u32 ) . to_le_bytes ( ) ) ;
580- new_ziplist. extend_from_slice ( & new_bytes) ;
581- new_ziplist. extend_from_slice ( & ziplist[ cursor + 4 + old_entry_len..] ) ;
582- ziplist. 0 = new_ziplist;
583- }
552+ let ziplist = node. ensure_decompressed ( & self . fill_factor ) ;
553+ let new_bytes = Bytes :: from ( value) ;
554+ let mut cursor = 0 ;
584555
585- return Ok ( ( ) ) ;
586- }
556+ // Skip to the target entry
557+ for _ in 0 ..local_index {
558+ let entry_len =
559+ u32:: from_le_bytes ( ziplist[ cursor..cursor + 4 ] . try_into ( ) . unwrap ( ) ) as usize ;
560+ cursor += 4 + entry_len;
587561 }
588- current_index += node. entry_count ;
562+
563+ let old_entry_len =
564+ u32:: from_le_bytes ( ziplist[ cursor..cursor + 4 ] . try_into ( ) . unwrap ( ) ) as usize ;
565+
566+ if new_bytes. len ( ) == old_entry_len {
567+ // Same size - overwrite in place
568+ ziplist[ cursor + 4 ..cursor + 4 + old_entry_len] . copy_from_slice ( & new_bytes) ;
569+ } else {
570+ // Different size - rebuild ziplist
571+ let mut new_ziplist =
572+ Vec :: with_capacity ( ziplist. len ( ) - old_entry_len + new_bytes. len ( ) ) ;
573+ new_ziplist. extend_from_slice ( & ziplist[ 0 ..cursor] ) ;
574+ new_ziplist. extend_from_slice ( & ( new_bytes. len ( ) as u32 ) . to_le_bytes ( ) ) ;
575+ new_ziplist. extend_from_slice ( & new_bytes) ;
576+ new_ziplist. extend_from_slice ( & ziplist[ cursor + 4 + old_entry_len..] ) ;
577+ ziplist. 0 = new_ziplist;
578+ }
579+
580+ return Ok ( ( ) ) ;
589581 }
590582
591583 Err ( anyhow:: anyhow!( "Index not found" ) )
0 commit comments