Bladeren bron

melib: use Vec instead of SmallVec for search results

There was no point in using SmallVec with this large a size; it was
32768 bytes, or 32KiB. Let's allocate that to the heap instead.

Signed-off-by: Manos Pitsidianakis <manos@pitsidianak.is>
Manos Pitsidianakis 7 maanden geleden
bovenliggende
commit
567270e1

+ 2 - 3
meli/src/accounts.rs

@@ -46,7 +46,6 @@ use melib::{
     utils::{fnmatch::Fnmatch, futures::sleep, random, shellexpand::ShellExpandTrait},
     Contacts, SortField, SortOrder,
 };
-use smallvec::SmallVec;
 
 #[cfg(feature = "sqlite3")]
 use crate::command::actions::AccountAction;
@@ -1286,7 +1285,7 @@ impl Account {
         search_term: &str,
         _sort: (SortField, SortOrder),
         mailbox_hash: MailboxHash,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         let query = melib::search::Query::try_from(search_term)?;
         match self.settings.conf.search_backend {
             #[cfg(feature = "sqlite3")]
@@ -1303,7 +1302,7 @@ impl Account {
                         .search(query, Some(mailbox_hash))
                 } else {
                     use melib::search::QueryTrait;
-                    let mut ret = SmallVec::new();
+                    let mut ret = Vec::with_capacity(512);
                     let envelopes = self.collection.envelopes.read().unwrap();
                     for &env_hash in self.collection.get_mailbox(mailbox_hash).iter() {
                         if let Some(envelope) = envelopes.get(&env_hash) {

+ 1 - 7
meli/src/mail/listing.rs

@@ -1011,13 +1011,7 @@ pub trait ListingTrait: Component {
     fn prev_entry(&mut self, context: &mut Context);
     fn draw_list(&mut self, grid: &mut CellBuffer, area: Area, context: &mut Context);
     fn highlight_line(&mut self, grid: &mut CellBuffer, area: Area, idx: usize, context: &Context);
-    fn filter(
-        &mut self,
-        _filter_term: String,
-        _results: SmallVec<[EnvelopeHash; 512]>,
-        _context: &Context,
-    ) {
-    }
+    fn filter(&mut self, _filter_term: String, _results: Vec<EnvelopeHash>, _context: &Context) {}
     fn unfocused(&self) -> bool;
     fn view_area(&self) -> Option<Area>;
     fn set_modifier_active(&mut self, _new_val: bool);

+ 4 - 9
meli/src/mail/listing/compact.rs

@@ -143,9 +143,9 @@ pub struct CompactListing {
     rows: RowsState<(ThreadHash, EnvelopeHash)>,
 
     #[allow(clippy::type_complexity)]
-    search_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    search_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     #[allow(clippy::type_complexity)]
-    select_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    select_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     filter_term: String,
     filtered_selection: Vec<ThreadHash>,
     filtered_order: HashMap<ThreadHash, usize>,
@@ -764,12 +764,7 @@ impl ListingTrait for CompactListing {
         context.dirty_areas.push_back(area);
     }
 
-    fn filter(
-        &mut self,
-        filter_term: String,
-        results: SmallVec<[EnvelopeHash; 512]>,
-        context: &Context,
-    ) {
+    fn filter(&mut self, filter_term: String, results: Vec<EnvelopeHash>, context: &Context) {
         if filter_term.is_empty() {
             return;
         }
@@ -1374,7 +1369,7 @@ impl CompactListing {
     fn select(
         &mut self,
         search_term: &str,
-        results: Result<SmallVec<[EnvelopeHash; 512]>>,
+        results: Result<Vec<EnvelopeHash>>,
         context: &mut Context,
     ) {
         let account = &context.accounts[&self.cursor_pos.0];

+ 2 - 7
meli/src/mail/listing/conversations.rs

@@ -118,7 +118,7 @@ pub struct ConversationsListing {
     error: std::result::Result<(), String>,
 
     #[allow(clippy::type_complexity)]
-    search_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    search_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     filter_term: String,
     filtered_selection: Vec<ThreadHash>,
     filtered_order: HashMap<ThreadHash, usize>,
@@ -521,12 +521,7 @@ impl ListingTrait for ConversationsListing {
         context.dirty_areas.push_back(area);
     }
 
-    fn filter(
-        &mut self,
-        filter_term: String,
-        results: SmallVec<[EnvelopeHash; 512]>,
-        context: &Context,
-    ) {
+    fn filter(&mut self, filter_term: String, results: Vec<EnvelopeHash>, context: &Context) {
         if filter_term.is_empty() {
             return;
         }

+ 4 - 9
meli/src/mail/listing/plain.rs

@@ -140,9 +140,9 @@ pub struct PlainListing {
     data_columns: DataColumns<5>,
 
     #[allow(clippy::type_complexity)]
-    search_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    search_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     #[allow(clippy::type_complexity)]
-    select_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    select_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     filter_term: String,
     filtered_selection: Vec<EnvelopeHash>,
     filtered_order: HashMap<EnvelopeHash, usize>,
@@ -502,12 +502,7 @@ impl ListingTrait for PlainListing {
         context.dirty_areas.push_back(area);
     }
 
-    fn filter(
-        &mut self,
-        filter_term: String,
-        results: SmallVec<[EnvelopeHash; 512]>,
-        context: &Context,
-    ) {
+    fn filter(&mut self, filter_term: String, results: Vec<EnvelopeHash>, context: &Context) {
         if filter_term.is_empty() {
             return;
         }
@@ -1286,7 +1281,7 @@ impl PlainListing {
     fn select(
         &mut self,
         search_term: &str,
-        results: Result<SmallVec<[EnvelopeHash; 512]>>,
+        results: Result<Vec<EnvelopeHash>>,
         context: &mut Context,
     ) {
         let account = &context.accounts[&self.cursor_pos.0];

+ 4 - 9
meli/src/mail/listing/thread.rs

@@ -139,9 +139,9 @@ pub struct ThreadListing {
     color_cache: ColorCache,
 
     #[allow(clippy::type_complexity)]
-    search_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    search_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     #[allow(clippy::type_complexity)]
-    select_job: Option<(String, JoinHandle<Result<SmallVec<[EnvelopeHash; 512]>>>)>,
+    select_job: Option<(String, JoinHandle<Result<Vec<EnvelopeHash>>>)>,
     filter_term: String,
     filtered_selection: Vec<ThreadHash>,
     filtered_order: HashMap<ThreadHash, usize>,
@@ -671,12 +671,7 @@ impl ListingTrait for ThreadListing {
         }
     }
 
-    fn filter(
-        &mut self,
-        filter_term: String,
-        results: SmallVec<[EnvelopeHash; 512]>,
-        context: &Context,
-    ) {
+    fn filter(&mut self, filter_term: String, results: Vec<EnvelopeHash>, context: &Context) {
         if filter_term.is_empty() {
             return;
         }
@@ -1224,7 +1219,7 @@ impl ThreadListing {
     fn select(
         &mut self,
         search_term: &str,
-        results: Result<SmallVec<[EnvelopeHash; 512]>>,
+        results: Result<Vec<EnvelopeHash>>,
         context: &mut Context,
     ) {
         let account = &context.accounts[&self.cursor_pos.0];

+ 2 - 3
meli/src/sqlite3.rs

@@ -37,7 +37,6 @@ use melib::{
     utils::sqlite3::{rusqlite::params, DatabaseDescription},
     Error, Result, ResultIntoError, SortField, SortOrder,
 };
-use smallvec::SmallVec;
 
 const DB: DatabaseDescription = DatabaseDescription {
     name: "index.db",
@@ -401,7 +400,7 @@ impl AccountCache {
         acc_name: Arc<str>,
         query: Query,
         (sort_field, sort_order): (SortField, SortOrder),
-    ) -> Result<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> Result<Vec<EnvelopeHash>> {
         let db_desc = DatabaseDescription {
             identifier: Some(acc_name.to_string().into()),
             ..DB.clone()
@@ -443,7 +442,7 @@ impl AccountCache {
                 .query_map([], |row| row.get::<_, EnvelopeHash>(0))
                 .map_err(Error::from)?
                 .map(|item| item.map_err(Error::from))
-                .collect::<Result<SmallVec<[EnvelopeHash; 512]>>>();
+                .collect::<Result<Vec<EnvelopeHash>>>();
             x
         })
         .await

+ 1 - 1
melib/src/backends.rs

@@ -508,7 +508,7 @@ pub trait MailBackend: ::std::fmt::Debug + Send + Sync {
         &self,
         query: crate::search::Query,
         mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>>;
+    ) -> ResultFuture<Vec<EnvelopeHash>>;
 
     fn submit(
         &self,

+ 2 - 2
melib/src/imap/mod.rs

@@ -1307,7 +1307,7 @@ impl MailBackend for ImapType {
         &self,
         query: crate::search::Query,
         mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         if mailbox_hash.is_none() {
             return Err(Error::new(
                 "Cannot search without specifying mailbox on IMAP",
@@ -1340,7 +1340,7 @@ impl MailBackend for ImapType {
             for l in response.split_rn() {
                 if l.starts_with(b"* SEARCH") {
                     let uid_index = uid_store.uid_index.lock()?;
-                    return Ok(SmallVec::from_iter(
+                    return Ok(Vec::from_iter(
                         String::from_utf8_lossy(l[b"* SEARCH".len()..].trim())
                             .split_whitespace()
                             .map(UID::from_str)

+ 1 - 1
melib/src/jmap/mod.rs

@@ -626,7 +626,7 @@ impl MailBackend for JmapType {
         &self,
         q: crate::search::Query,
         mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         let store = self.store.clone();
         let connection = self.connection.clone();
         let filter = if let Some(mailbox_hash) = mailbox_hash {

+ 1 - 1
melib/src/maildir/backend.rs

@@ -578,7 +578,7 @@ impl MailBackend for MaildirType {
         &self,
         _query: crate::search::Query,
         _mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         Err(
             Error::new("Search is unimplemented for the maildir backend.")
                 .set_kind(ErrorKind::NotImplemented),

+ 1 - 1
melib/src/mbox/mod.rs

@@ -1243,7 +1243,7 @@ impl MailBackend for MboxType {
         &self,
         _query: crate::search::Query,
         _mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         Err(Error::new("Search is unimplemented for the mbox backend.")
             .set_kind(ErrorKind::NotImplemented))
     }

+ 1 - 1
melib/src/nntp/mod.rs

@@ -574,7 +574,7 @@ impl MailBackend for NntpType {
         &self,
         _query: crate::search::Query,
         _mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         Err(Error::new("Searching is not supported for nntp backend.")
             .set_kind(ErrorKind::NotSupported))
     }

+ 2 - 8
melib/src/notmuch/mod.rs

@@ -954,7 +954,7 @@ impl MailBackend for NotmuchDb {
         &self,
         melib_query: crate::search::Query,
         mailbox_hash: Option<MailboxHash>,
-    ) -> ResultFuture<SmallVec<[EnvelopeHash; 512]>> {
+    ) -> ResultFuture<Vec<EnvelopeHash>> {
         let database = Self::new_connection(
             self.path.as_path(),
             self.revision_uuid.clone(),
@@ -963,7 +963,6 @@ impl MailBackend for NotmuchDb {
         )?;
         let mailboxes = self.mailboxes.clone();
         Ok(Box::pin(async move {
-            let mut ret = SmallVec::new();
             let mut query_s = if let Some(mailbox_hash) = mailbox_hash {
                 if let Some(m) = mailboxes.read().unwrap().get(&mailbox_hash) {
                     let mut s = m.query_str.clone();
@@ -981,12 +980,7 @@ impl MailBackend for NotmuchDb {
             };
             melib_query.query_to_string(&mut query_s)?;
             let query: Query = Query::new(&database, &query_s)?;
-            let iter = query.search()?;
-            for message in iter {
-                ret.push(message.env_hash());
-            }
-
-            Ok(ret)
+            Ok(query.search()?.map(|message| message.env_hash()).collect())
         }))
     }