project: Use VecDeque in SearchHistory (#31224)

`SearchHistory` internally enforced the max length of the search history
by popping elements from the front using `.remove(0)`. For a `Vec` this
is a `O(n)` operation. Use a `VecDeque` to make this `O(1)`

I also made it so the excess element is popped before the new one is
added, which keeps the allocation at the desired size.

Release Notes:

- N/A
This commit is contained in:
tidely 2025-05-23 14:25:40 +03:00 committed by GitHub
parent 1cad1cbbfc
commit c50093d68c
No known key found for this signature in database
GPG key ID: B5690EEEBB952194

View file

@ -1,3 +1,5 @@
use std::collections::VecDeque;
/// Determines the behavior to use when inserting a new query into the search history. /// Determines the behavior to use when inserting a new query into the search history.
#[derive(Default, Debug, Clone, PartialEq)] #[derive(Default, Debug, Clone, PartialEq)]
pub enum QueryInsertionBehavior { pub enum QueryInsertionBehavior {
@ -28,7 +30,7 @@ impl SearchHistoryCursor {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct SearchHistory { pub struct SearchHistory {
history: Vec<String>, history: VecDeque<String>,
max_history_len: Option<usize>, max_history_len: Option<usize>,
insertion_behavior: QueryInsertionBehavior, insertion_behavior: QueryInsertionBehavior,
} }
@ -38,7 +40,7 @@ impl SearchHistory {
SearchHistory { SearchHistory {
max_history_len, max_history_len,
insertion_behavior, insertion_behavior,
history: Vec::new(), history: VecDeque::new(),
} }
} }
@ -50,7 +52,7 @@ impl SearchHistory {
} }
if self.insertion_behavior == QueryInsertionBehavior::ReplacePreviousIfContains { if self.insertion_behavior == QueryInsertionBehavior::ReplacePreviousIfContains {
if let Some(previously_searched) = self.history.last_mut() { if let Some(previously_searched) = self.history.back_mut() {
if search_string.contains(previously_searched.as_str()) { if search_string.contains(previously_searched.as_str()) {
*previously_searched = search_string; *previously_searched = search_string;
cursor.selection = Some(self.history.len() - 1); cursor.selection = Some(self.history.len() - 1);
@ -59,12 +61,12 @@ impl SearchHistory {
} }
} }
self.history.push(search_string);
if let Some(max_history_len) = self.max_history_len { if let Some(max_history_len) = self.max_history_len {
if self.history.len() > max_history_len { if self.history.len() >= max_history_len {
self.history.remove(0); self.history.pop_front();
} }
} }
self.history.push_back(search_string);
cursor.selection = Some(self.history.len() - 1); cursor.selection = Some(self.history.len() - 1);
} }