Skip to content

Commit 40e29e9

Browse files
committed
Avoid cloning stored_buckets on BucketQueueView::pre_save
1 parent 5505ae2 commit 40e29e9

File tree

1 file changed

+37
-26
lines changed

1 file changed

+37
-26
lines changed

linera-views/src/views/bucket_queue_view.rs

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -67,14 +67,10 @@ struct BucketDescription {
6767
}
6868

6969
impl 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

Comments
 (0)