@@ -537,28 +537,57 @@ impl QuickList {
537537 return Err ( anyhow:: anyhow!( "List is empty" ) ) ;
538538 }
539539
540- // Calculate absolute index
540+ // Convert to absolute index
541541 let len = self . len as isize ;
542- let index = if index < 0 { ( len + index) . max ( 0 ) } else { index } as usize ;
542+ let abs_index = if index < 0 { ( len + index) . max ( 0 ) } else { index } as usize ;
543543
544- if index >= self . len {
544+ if abs_index >= self . len {
545545 return Err ( anyhow:: anyhow!( "Index out of bounds" ) ) ;
546546 }
547547
548+ // Find the node containing this index
548549 let mut current_index = 0 ;
549550 for node in & mut self . nodes {
550- if current_index + node. entry_count > index {
551+ if current_index + node. entry_count > abs_index {
552+ let local_index = abs_index - current_index;
553+
551554 node. ensure_decompressed ( & self . fill_factor ) ;
552555 if let NodeData :: Uncompressed ( ziplist) = & mut node. data {
553- let mut entries = ziplist. to_vec ( ) ;
554- if let Some ( entry) = entries. get_mut ( index - current_index) {
555- * entry = Bytes :: from ( value. clone ( ) ) ;
556- return Ok ( ( ) ) ;
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;
557565 }
566+
567+ let old_entry_len =
568+ u32:: from_le_bytes ( ziplist[ cursor..cursor + 4 ] . try_into ( ) . unwrap ( ) )
569+ as usize ;
570+
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+ }
584+
585+ return Ok ( ( ) ) ;
558586 }
559587 }
560588 current_index += node. entry_count ;
561589 }
590+
562591 Err ( anyhow:: anyhow!( "Index not found" ) )
563592 }
564593}
0 commit comments