@@ -67,14 +67,10 @@ struct BucketDescription {
6767}
6868
6969impl BucketStore {
70- fn new < T > ( stored_data : & VecDeque < Bucket < T > > , position : usize ) -> Self {
71- let descriptions = stored_data
72- . iter ( )
73- . map ( Bucket :: to_description)
74- . collect :: < Vec < _ > > ( ) ;
70+ fn new ( descriptions : Vec < BucketDescription > , front_position : usize ) -> Self {
7571 Self {
7672 descriptions,
77- front_position : position ,
73+ front_position,
7874 }
7975 }
8076
@@ -249,58 +245,73 @@ where
249245
250246 fn pre_save ( & self , batch : & mut Batch ) -> Result < bool , ViewError > {
251247 let mut delete_view = false ;
252- let mut stored_buckets = self . stored_buckets . clone ( ) ;
248+ let mut bucket_descriptions = Vec :: new ( ) ;
253249 let mut stored_front_position = self . stored_front_position ;
250+
254251 if self . stored_count ( ) == 0 {
255252 let key_prefix = self . context . base_key ( ) . bytes . clone ( ) ;
256253 batch. delete_key_prefix ( key_prefix) ;
257254 delete_view = true ;
258- stored_buckets. clear ( ) ;
259255 stored_front_position = 0 ;
260256 } else if let Some ( cursor) = self . cursor {
261- for _ in 0 ..cursor. offset {
262- let bucket = stored_buckets. pop_front ( ) . unwrap ( ) ;
263- let index = bucket. index ;
264- let key = self . get_bucket_key ( index) ?;
257+ for offset in 0 ..cursor. offset {
258+ let bucket = & self . stored_buckets [ offset] ;
259+ let key = self . get_bucket_key ( bucket. index ) ?;
265260 batch. delete_key ( key) ;
266261 }
267262 stored_front_position = cursor. position ;
268- // We need to ensure that the first index is in the front.
269- let first_index = stored_buckets[ 0 ] . index ;
263+
264+ let first_bucket = & self . stored_buckets [ cursor. offset ] ;
265+ let first_index = first_bucket. index ;
266+
270267 if first_index != 0 {
271- stored_buckets[ 0 ] . index = 0 ;
272268 let key = self . get_bucket_key ( first_index) ?;
273269 batch. delete_key ( key) ;
274270 let key = self . get_bucket_key ( 0 ) ?;
275- let bucket = stored_buckets. front ( ) . unwrap ( ) ;
276- let State :: Loaded { data } = & bucket. state else {
271+ let State :: Loaded { data } = & first_bucket. state else {
277272 unreachable ! ( "The front bucket is always loaded." ) ;
278273 } ;
279274 batch. put_key_value ( key, data) ?;
275+ bucket_descriptions. push ( BucketDescription {
276+ length : first_bucket. len ( ) ,
277+ index : 0 ,
278+ } ) ;
279+ } else {
280+ bucket_descriptions. push ( first_bucket. to_description ( ) ) ;
281+ }
282+
283+ for offset in ( cursor. offset + 1 ) ..self . stored_buckets . len ( ) {
284+ let bucket = & self . stored_buckets [ offset] ;
285+ bucket_descriptions. push ( bucket. to_description ( ) ) ;
280286 }
281287 }
288+
282289 if !self . new_back_values . is_empty ( ) {
283290 delete_view = false ;
284- let mut index = match stored_buckets. back ( ) {
285- Some ( bucket) => bucket. index + 1 ,
286- None => 0 ,
291+ let mut index = if !bucket_descriptions. is_empty ( ) {
292+ bucket_descriptions
293+ . last ( )
294+ . expect ( "bucket_descriptions is not empty" )
295+ . index
296+ + 1
297+ } else {
298+ 0
287299 } ;
300+
288301 let new_back_values = self . new_back_values . iter ( ) . cloned ( ) . collect :: < Vec < _ > > ( ) ;
289302 for value_chunk in new_back_values. chunks ( N ) {
290303 let key = self . get_bucket_key ( index) ?;
291304 batch. put_key_value ( key, & value_chunk) ?;
292- stored_buckets . push_back ( Bucket {
305+ bucket_descriptions . push ( BucketDescription {
293306 index,
294- // This is only used for `BucketStore::new` below.
295- state : State :: NotLoaded {
296- length : value_chunk. len ( ) ,
297- } ,
307+ length : value_chunk. len ( ) ,
298308 } ) ;
299309 index += 1 ;
300310 }
301311 }
312+
302313 if !delete_view {
303- let bucket_store = BucketStore :: new ( & stored_buckets , stored_front_position) ;
314+ let bucket_store = BucketStore :: new ( bucket_descriptions , stored_front_position) ;
304315 let key = self . context . base_key ( ) . base_tag ( KeyTag :: Store as u8 ) ;
305316 batch. put_key_value ( key, & bucket_store) ?;
306317 }
0 commit comments