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>
This commit is contained in:
parent
5af6e059b7
commit
567270e177
14 changed files with 28 additions and 62 deletions
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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),
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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())
|
||||
}))
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue