Replace StackVec with smallvec::SmallVec
SmallVec has a less buggy and better implementation.memfd
parent
b6403f486b
commit
a365a846b8
|
@ -771,6 +771,7 @@ dependencies = [
|
|||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"text_processing 0.4.1",
|
||||
"uuid 0.7.4 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1553,8 +1554,11 @@ dependencies = [
|
|||
|
||||
[[package]]
|
||||
name = "smallvec"
|
||||
version = "1.0.0"
|
||||
version = "1.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sourcefile"
|
||||
|
@ -1860,6 +1864,7 @@ dependencies = [
|
|||
"serde 1.0.99 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_derive 1.0.92 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"serde_json 1.0.39 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"termion 1.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"text_processing 0.4.1",
|
||||
"toml 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
|
@ -1889,7 +1894,7 @@ name = "unicode-normalization"
|
|||
version = "0.1.11"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
dependencies = [
|
||||
"smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
"smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -2298,7 +2303,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
|||
"checksum signal-hook-registry 1.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "1797d48f38f91643908bb14e35e79928f9f4b3cefb2420a564dde0991b4358dc"
|
||||
"checksum slab 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c111b5bd5695e56cffe5129854aa230b39c93a305372fdbb2668ca2394eea9f8"
|
||||
"checksum smallvec 0.6.13 (registry+https://github.com/rust-lang/crates.io-index)" = "f7b0758c52e15a8b5e3691eae6cc559f08eee9406e548a4477ba4e67770a82b6"
|
||||
"checksum smallvec 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4ecf3b85f68e8abaa7555aa5abdb1153079387e60b718283d732f03897fcfc86"
|
||||
"checksum smallvec 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44e59e0c9fa00817912ae6e4e6e3c4fe04455e75699d06eedc7d85917ed8e8f4"
|
||||
"checksum sourcefile 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "4bf77cb82ba8453b42b6ae1d692e4cdc92f9a47beaf89a847c8be83f4e328ad3"
|
||||
"checksum spin 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
|
||||
"checksum string 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "d24114bfcceb867ca7f71a0d3fe45d45619ec47a6fbfa98cb14e14250bfa5d6d"
|
||||
|
|
|
@ -27,6 +27,7 @@ text_processing = { path = "../text_processing", version = "*", optional= true }
|
|||
libc = {version = "0.2.59", features = ["extra_traits",]}
|
||||
reqwest = { version ="0.10.0-alpha.2", optional=true, features = ["json", "blocking" ]}
|
||||
serde_json = { version = "1.0", optional = true, features = ["raw_value",] }
|
||||
smallvec = { version = "1.1.0", features = ["serde", ] }
|
||||
|
||||
[features]
|
||||
default = ["unicode_algorithms", "imap_backend", "maildir_backend", "mbox_backend", "vcard"]
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use smallvec::SmallVec;
|
||||
#[macro_use]
|
||||
mod protocol_parser;
|
||||
pub use protocol_parser::{UntaggedResponse::*, *};
|
||||
|
@ -677,7 +678,7 @@ impl ImapType {
|
|||
&self,
|
||||
query: String,
|
||||
folder_hash: FolderHash,
|
||||
) -> Result<crate::structs::StackVec<EnvelopeHash>> {
|
||||
) -> Result<SmallVec<[EnvelopeHash; 512]>> {
|
||||
let folders_lck = self.folders.read()?;
|
||||
let mut response = String::with_capacity(8 * 1024);
|
||||
let mut conn = self.connection.lock()?;
|
||||
|
@ -692,7 +693,7 @@ impl ImapType {
|
|||
if l.starts_with("* SEARCH") {
|
||||
use std::iter::FromIterator;
|
||||
let uid_index = self.uid_store.uid_index.lock()?;
|
||||
return Ok(crate::structs::StackVec::from_iter(
|
||||
return Ok(SmallVec::from_iter(
|
||||
l["* SEARCH".len()..]
|
||||
.trim()
|
||||
.split_whitespace()
|
||||
|
|
|
@ -21,9 +21,9 @@
|
|||
|
||||
use super::folder::JmapFolder;
|
||||
use super::*;
|
||||
use crate::structs::StackVec;
|
||||
use serde::Serialize;
|
||||
use serde_json::{json, Value};
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::convert::TryFrom;
|
||||
use std::hash::{Hash, Hasher};
|
||||
|
@ -327,10 +327,10 @@ pub fn get(
|
|||
}
|
||||
tag_hash
|
||||
})
|
||||
.collect::<StackVec<u64>>();
|
||||
.collect::<SmallVec<[u64; 1024]>>();
|
||||
(tags, obj.id.clone(), obj.blob_id.clone())
|
||||
})
|
||||
.collect::<Vec<(StackVec<u64>, Id, Id)>>();
|
||||
.collect::<Vec<(SmallVec<[u64; 1024]>, Id, Id)>>();
|
||||
drop(tag_lck);
|
||||
let mut ret = list
|
||||
.into_iter()
|
||||
|
|
|
@ -1,3 +1,24 @@
|
|||
/*
|
||||
* meli - notmuch backend
|
||||
*
|
||||
* Copyright 2019 - 2020 Manos Pitsidianakis
|
||||
*
|
||||
* This file is part of meli.
|
||||
*
|
||||
* meli is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* meli is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use crate::async_workers::{Async, AsyncBuilder, AsyncStatus, WorkContext};
|
||||
use crate::backends::FolderHash;
|
||||
use crate::backends::{
|
||||
|
@ -8,8 +29,8 @@ use crate::conf::AccountSettings;
|
|||
use crate::email::{Envelope, EnvelopeHash, Flag};
|
||||
use crate::error::{MeliError, Result};
|
||||
use crate::shellexpand::ShellExpandTrait;
|
||||
use crate::structs::StackVec;
|
||||
use fnv::FnvHashMap;
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
use std::collections::BTreeMap;
|
||||
use std::ffi::{CStr, CString};
|
||||
|
@ -229,7 +250,7 @@ impl NotmuchDb {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn search(&self, query_s: &str) -> Result<crate::structs::StackVec<EnvelopeHash>> {
|
||||
pub fn search(&self, query_s: &str) -> Result<SmallVec<[EnvelopeHash; 512]>> {
|
||||
let database_lck = self.database.inner.read().unwrap();
|
||||
let query_str = std::ffi::CString::new(query_s).unwrap();
|
||||
let query: *mut notmuch_query_t =
|
||||
|
@ -247,7 +268,7 @@ impl NotmuchDb {
|
|||
}
|
||||
assert!(!messages.is_null());
|
||||
let iter = MessageIterator { messages };
|
||||
let mut ret = StackVec::new();
|
||||
let mut ret = SmallVec::new();
|
||||
for message in iter {
|
||||
let fs_path = unsafe { notmuch_message_get_filename(message) };
|
||||
let c_str = unsafe { CStr::from_ptr(fs_path) };
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
use super::*;
|
||||
use crate::backends::FolderHash;
|
||||
use smallvec::SmallVec;
|
||||
use std::collections::BTreeMap;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
use std::sync::{Arc, RwLock, RwLockReadGuard, RwLockWriteGuard};
|
||||
|
@ -160,7 +161,7 @@ impl Collection {
|
|||
mut new_envelopes: FnvHashMap<EnvelopeHash, Envelope>,
|
||||
folder_hash: FolderHash,
|
||||
sent_folder: Option<FolderHash>,
|
||||
) -> Option<StackVec<FolderHash>> {
|
||||
) -> Option<SmallVec<[FolderHash; 8]>> {
|
||||
self.sent_folder = sent_folder;
|
||||
for (h, e) in new_envelopes.iter() {
|
||||
self.message_ids.insert(e.message_id().raw().to_vec(), *h);
|
||||
|
@ -198,7 +199,7 @@ impl Collection {
|
|||
});
|
||||
}
|
||||
|
||||
let mut ret = StackVec::new();
|
||||
let mut ret = SmallVec::new();
|
||||
let keys = threads.keys().cloned().collect::<Vec<FolderHash>>();
|
||||
for t_fh in keys {
|
||||
if t_fh == folder_hash {
|
||||
|
|
|
@ -61,7 +61,7 @@ pub fn timestamp_to_string(timestamp: UnixTimestamp, fmt: Option<&str>) -> Strin
|
|||
};
|
||||
let s: CString;
|
||||
unsafe {
|
||||
let mut vec: Vec<u8> = vec![0; 256];
|
||||
let mut vec: [u8; 256] = [0; 256];
|
||||
let ret = strftime(
|
||||
vec.as_mut_ptr() as *mut _,
|
||||
256,
|
||||
|
|
|
@ -43,6 +43,7 @@ use crate::datetime::UnixTimestamp;
|
|||
use crate::error::{MeliError, Result};
|
||||
use crate::thread::ThreadHash;
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::borrow::Cow;
|
||||
use std::cmp::Ordering;
|
||||
use std::collections::hash_map::DefaultHasher;
|
||||
|
@ -132,7 +133,7 @@ pub struct Envelope {
|
|||
|
||||
flags: Flag,
|
||||
has_attachments: bool,
|
||||
labels: crate::structs::StackVec<u64>,
|
||||
labels: SmallVec<[u64; 8]>,
|
||||
}
|
||||
|
||||
impl fmt::Debug for Envelope {
|
||||
|
@ -170,7 +171,7 @@ impl Envelope {
|
|||
hash,
|
||||
has_attachments: false,
|
||||
flags: Flag::default(),
|
||||
labels: crate::structs::StackVec::new(),
|
||||
labels: SmallVec::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -609,11 +610,11 @@ impl Envelope {
|
|||
self.has_attachments
|
||||
}
|
||||
|
||||
pub fn labels(&self) -> &crate::structs::StackVec<u64> {
|
||||
pub fn labels(&self) -> &SmallVec<[u64; 8]> {
|
||||
&self.labels
|
||||
}
|
||||
|
||||
pub fn labels_mut(&mut self) -> &mut crate::structs::StackVec<u64> {
|
||||
pub fn labels_mut(&mut self) -> &mut SmallVec<[u64; 8]> {
|
||||
&mut self.labels
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,9 +18,10 @@
|
|||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use super::parser;
|
||||
use super::Envelope;
|
||||
use crate::StackVec;
|
||||
use smallvec::SmallVec;
|
||||
use std::convert::From;
|
||||
|
||||
#[derive(Debug, Copy)]
|
||||
|
@ -46,7 +47,7 @@ impl<'a> From<&'a [u8]> for ListAction<'a> {
|
|||
}
|
||||
|
||||
impl<'a> ListAction<'a> {
|
||||
pub fn parse_options_list(input: &'a [u8]) -> Option<StackVec<ListAction<'a>>> {
|
||||
pub fn parse_options_list(input: &'a [u8]) -> Option<SmallVec<[ListAction<'a>; 4]>> {
|
||||
parser::angle_bracket_delimeted_list(input)
|
||||
.map(|mut vec| {
|
||||
/* Prefer email options first, since this _is_ a mail client after all and it's
|
||||
|
@ -61,20 +62,13 @@ impl<'a> ListAction<'a> {
|
|||
|
||||
vec.into_iter()
|
||||
.map(|elem| ListAction::from(elem))
|
||||
.collect::<StackVec<ListAction<'a>>>()
|
||||
.collect::<SmallVec<[ListAction<'a>; 4]>>()
|
||||
})
|
||||
.to_full_result()
|
||||
.ok()
|
||||
}
|
||||
}
|
||||
|
||||
/* Required for StackVec's place holder elements, never actually used */
|
||||
impl<'a> Default for ListAction<'a> {
|
||||
fn default() -> Self {
|
||||
ListAction::Email(b"")
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> Clone for ListAction<'a> {
|
||||
fn clone(&self) -> Self {
|
||||
match self {
|
||||
|
@ -88,8 +82,8 @@ impl<'a> Clone for ListAction<'a> {
|
|||
pub struct ListActions<'a> {
|
||||
pub id: Option<&'a str>,
|
||||
pub archive: Option<&'a str>,
|
||||
pub post: Option<StackVec<ListAction<'a>>>,
|
||||
pub unsubscribe: Option<StackVec<ListAction<'a>>>,
|
||||
pub post: Option<SmallVec<[ListAction<'a>; 4]>>,
|
||||
pub unsubscribe: Option<SmallVec<[ListAction<'a>; 4]>>,
|
||||
}
|
||||
|
||||
pub fn list_id_header<'a>(envelope: &'a Envelope) -> Option<&'a str> {
|
||||
|
|
|
@ -123,8 +123,6 @@ pub mod mailbox;
|
|||
pub mod thread;
|
||||
pub use crate::email::*;
|
||||
pub use crate::thread::*;
|
||||
mod structs;
|
||||
pub use self::structs::*;
|
||||
pub mod parsec;
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -1,253 +0,0 @@
|
|||
/*
|
||||
* meli - melib crate.
|
||||
*
|
||||
* Copyright 2019 Manos Pitsidianakis
|
||||
*
|
||||
* This file is part of meli.
|
||||
*
|
||||
* meli is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* meli is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use std::iter::{Extend, FromIterator};
|
||||
use std::ops::Index;
|
||||
use std::ops::IndexMut;
|
||||
|
||||
const STACK_VEC_CAPACITY: usize = 32;
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct StackVec<T: Default + Copy + std::fmt::Debug> {
|
||||
len: usize,
|
||||
array: [T; STACK_VEC_CAPACITY],
|
||||
heap_vec: Vec<T>,
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> StackVec<T> {
|
||||
pub fn new() -> Self {
|
||||
StackVec {
|
||||
len: 0,
|
||||
array: [T::default(); STACK_VEC_CAPACITY],
|
||||
heap_vec: Vec::new(),
|
||||
}
|
||||
}
|
||||
pub fn push(&mut self, ind: T) {
|
||||
if self.len == self.array.len() {
|
||||
if self.heap_vec.is_empty() {
|
||||
self.heap_vec.reserve(STACK_VEC_CAPACITY);
|
||||
for _ in 0..STACK_VEC_CAPACITY {
|
||||
self.heap_vec.push(T::default());
|
||||
}
|
||||
}
|
||||
self.heap_vec[0..STACK_VEC_CAPACITY].copy_from_slice(&self.array);
|
||||
self.heap_vec.push(ind);
|
||||
} else if self.len > self.array.len() {
|
||||
self.heap_vec.push(ind);
|
||||
} else {
|
||||
self.array[self.len] = ind;
|
||||
}
|
||||
self.len += 1;
|
||||
}
|
||||
pub fn pop(&mut self) -> Option<T> {
|
||||
if self.len == 0 {
|
||||
return None;
|
||||
}
|
||||
if self.len > self.array.len() {
|
||||
self.len -= 1;
|
||||
self.heap_vec.pop()
|
||||
} else {
|
||||
let ret = self.array[self.len - 1];
|
||||
self.len -= 1;
|
||||
Some(ret)
|
||||
}
|
||||
}
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
pub fn is_empty(&self) -> bool {
|
||||
self.len == 0
|
||||
}
|
||||
pub fn iter(&self) -> StackVecIter<T> {
|
||||
StackVecIter {
|
||||
stack: &self,
|
||||
range: 0..self.len,
|
||||
}
|
||||
}
|
||||
pub fn remove(&mut self, i: usize) -> T {
|
||||
if self.len > self.array.len() {
|
||||
self.len -= 1;
|
||||
self.heap_vec.remove(i)
|
||||
} else {
|
||||
let ret = std::mem::replace(&mut self.array[i], T::default());
|
||||
self.len -= 1;
|
||||
for i in i..self.len {
|
||||
self.array[i] = self.array[i + 1];
|
||||
}
|
||||
ret
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set(&mut self, i: usize, val: T) {
|
||||
debug_assert!(i < self.len);
|
||||
if self.len > self.array.len() {
|
||||
self.heap_vec[i] = val;
|
||||
if i < self.array.len() {
|
||||
self.array[i] = val;
|
||||
}
|
||||
} else {
|
||||
self.array[i] = val;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StackVecIter<'a, T: Default + Copy + std::fmt::Debug> {
|
||||
stack: &'a StackVec<T>,
|
||||
range: std::ops::Range<usize>,
|
||||
}
|
||||
|
||||
impl<'a, T: Default + Copy + std::fmt::Debug> Iterator for StackVecIter<'a, T> {
|
||||
type Item = &'a T;
|
||||
fn next(&mut self) -> Option<&'a T> {
|
||||
if self.range.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
let idx = self.range.start;
|
||||
self.range.start += 1;
|
||||
Some(&self.stack[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<'a, T: Default + Copy + std::fmt::Debug> std::iter::DoubleEndedIterator
|
||||
for StackVecIter<'a, T>
|
||||
{
|
||||
fn next_back(&mut self) -> Option<&'a T> {
|
||||
if self.range.len() == 0 {
|
||||
None
|
||||
} else {
|
||||
let idx = self.range.end - 1;
|
||||
self.range.end -= 1;
|
||||
Some(&self.stack[idx])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> Index<usize> for StackVec<T> {
|
||||
type Output = T;
|
||||
|
||||
fn index(&self, idx: usize) -> &T {
|
||||
if self.len > self.array.len() {
|
||||
&self.heap_vec[idx]
|
||||
} else {
|
||||
&self.array[idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> IndexMut<usize> for StackVec<T> {
|
||||
fn index_mut(&mut self, idx: usize) -> &mut T {
|
||||
if self.len > self.array.len() {
|
||||
&mut self.heap_vec[idx]
|
||||
} else {
|
||||
&mut self.array[idx]
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> Extend<T> for StackVec<T> {
|
||||
fn extend<I>(&mut self, iter: I)
|
||||
where
|
||||
I: IntoIterator<Item = T>,
|
||||
{
|
||||
for elem in iter {
|
||||
self.push(elem);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> FromIterator<T> for StackVec<T> {
|
||||
fn from_iter<I: IntoIterator<Item = T>>(iter: I) -> Self {
|
||||
let mut c = StackVec::new();
|
||||
|
||||
for i in iter {
|
||||
c.push(i);
|
||||
}
|
||||
|
||||
c
|
||||
}
|
||||
}
|
||||
|
||||
pub struct StackVecIterOwned<T: Default + Copy + std::fmt::Debug>(StackVec<T>);
|
||||
impl<T: Default + Copy + std::fmt::Debug> IntoIterator for StackVec<T> {
|
||||
type Item = T;
|
||||
type IntoIter = StackVecIterOwned<T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
StackVecIterOwned(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, T: Default + Copy + std::fmt::Debug> IntoIterator for &'a StackVec<T> {
|
||||
type Item = &'a T;
|
||||
type IntoIter = StackVecIter<'a, T>;
|
||||
|
||||
fn into_iter(self) -> Self::IntoIter {
|
||||
self.iter()
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Default + Copy + std::fmt::Debug> Iterator for StackVecIterOwned<T> {
|
||||
type Item = T;
|
||||
fn next(&mut self) -> Option<T> {
|
||||
if self.0.is_empty() {
|
||||
None
|
||||
} else {
|
||||
Some(self.0.remove(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
impl<T: Default + Copy + std::fmt::Debug> std::iter::DoubleEndedIterator for StackVecIterOwned<T> {
|
||||
fn next_back(&mut self) -> Option<T> {
|
||||
if self.0.is_empty() {
|
||||
None
|
||||
} else {
|
||||
self.0.pop()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn test_stackvec() {
|
||||
let mut stack = StackVec::from_iter(0..4 * STACK_VEC_CAPACITY);
|
||||
let mut ctr = 0;
|
||||
assert!(stack.iter().all(|&x| {
|
||||
let ret = x == ctr;
|
||||
ctr += 1;
|
||||
ret
|
||||
}));
|
||||
for _ in 0..(3 * STACK_VEC_CAPACITY) + 1 {
|
||||
stack.pop();
|
||||
}
|
||||
ctr = 0;
|
||||
assert!(stack.iter().all(|&x| {
|
||||
let ret = x == ctr;
|
||||
ctr += 1;
|
||||
ret
|
||||
}));
|
||||
}
|
||||
}
|
|
@ -35,7 +35,6 @@
|
|||
use crate::datetime::UnixTimestamp;
|
||||
use crate::email::parser::BytesExt;
|
||||
use crate::email::*;
|
||||
use crate::structs::StackVec;
|
||||
|
||||
#[cfg(feature = "unicode_algorithms")]
|
||||
use text_processing::grapheme_clusters::*;
|
||||
|
@ -53,6 +52,8 @@ use std::str::FromStr;
|
|||
use std::string::ToString;
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
|
||||
type Envelopes = Arc<RwLock<FnvHashMap<EnvelopeHash, Envelope>>>;
|
||||
|
||||
#[derive(PartialEq, Hash, Eq, Copy, Clone, Serialize, Deserialize, Default)]
|
||||
|
@ -279,7 +280,7 @@ impl FromStr for SortOrder {
|
|||
|
||||
pub struct ThreadsIterator<'a> {
|
||||
pos: usize,
|
||||
stack: StackVec<usize>,
|
||||
stack: SmallVec<[usize; 16]>,
|
||||
root_tree: Ref<'a, Vec<ThreadHash>>,
|
||||
thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>,
|
||||
}
|
||||
|
@ -332,7 +333,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
|
|||
pub struct ThreadIterator<'a> {
|
||||
init_pos: usize,
|
||||
pos: usize,
|
||||
stack: StackVec<usize>,
|
||||
stack: SmallVec<[usize; 16]>,
|
||||
root_tree: Ref<'a, Vec<ThreadHash>>,
|
||||
thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>,
|
||||
}
|
||||
|
@ -724,7 +725,7 @@ impl Threads {
|
|||
pub fn threads_iter(&self) -> ThreadsIterator {
|
||||
ThreadsIterator {
|
||||
pos: 0,
|
||||
stack: StackVec::new(),
|
||||
stack: SmallVec::new(),
|
||||
root_tree: self.tree_index.borrow(),
|
||||
thread_nodes: &self.thread_nodes,
|
||||
}
|
||||
|
@ -734,7 +735,7 @@ impl Threads {
|
|||
ThreadIterator {
|
||||
init_pos: index,
|
||||
pos: index,
|
||||
stack: StackVec::new(),
|
||||
stack: SmallVec::new(),
|
||||
root_tree: self.tree_index.borrow(),
|
||||
thread_nodes: &self.thread_nodes,
|
||||
}
|
||||
|
|
|
@ -256,7 +256,7 @@ fn run_app() -> Result<()> {
|
|||
|
||||
'inner: loop {
|
||||
/* Check if any components have sent reply events to State. */
|
||||
let events: Vec<UIEvent> = state.context.replies();
|
||||
let events: ui::smallvec::SmallVec<[UIEvent; 8]> = state.context.replies();
|
||||
for e in events {
|
||||
state.rcv_event(e);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
extern crate melib;
|
||||
use melib::Result;
|
||||
use melib::StackVec;
|
||||
|
||||
extern crate text_processing;
|
||||
use text_processing::line_break::*;
|
||||
|
@ -14,14 +13,14 @@ fn cost(i: usize, j: usize, width: usize, minima: &Vec<usize>, offsets: &Vec<usi
|
|||
}
|
||||
|
||||
fn smawk(
|
||||
rows: &mut StackVec<usize>,
|
||||
columns: &mut StackVec<usize>,
|
||||
rows: &mut Vec<usize>,
|
||||
columns: &mut Vec<usize>,
|
||||
minima: &mut Vec<usize>,
|
||||
breaks: &mut Vec<usize>,
|
||||
width: usize,
|
||||
offsets: &Vec<usize>,
|
||||
) {
|
||||
let mut stack = StackVec::new();
|
||||
let mut stack = Vec::new();
|
||||
let mut i = 0;
|
||||
while i < rows.len() {
|
||||
if stack.len() > 0 {
|
||||
|
@ -46,7 +45,7 @@ fn smawk(
|
|||
let mut odd_columns = columns.iter().skip(1).step_by(2).cloned().collect();
|
||||
smawk(rows, &mut odd_columns, minima, breaks, width, offsets);
|
||||
for (i, o) in odd_columns.into_iter().enumerate() {
|
||||
columns.set(2 * i + 1, o);
|
||||
columns[2 * i + 1] = o;
|
||||
}
|
||||
}
|
||||
let mut i = 0;
|
||||
|
|
|
@ -30,6 +30,7 @@ rusqlite = {version = "0.20.0", optional =true }
|
|||
rmp = "^0.8"
|
||||
rmpv = { version = "^0.4.2", features=["with-serde",] }
|
||||
rmp-serde = "^0.14.0"
|
||||
smallvec = { version = "1.1.0", features = ["serde", ] }
|
||||
|
||||
[features]
|
||||
default = ["sqlite3"]
|
||||
|
|
|
@ -25,7 +25,7 @@ use melib::{
|
|||
backends::{FolderHash, MailBackend},
|
||||
email::EnvelopeHash,
|
||||
thread::{SortField, SortOrder},
|
||||
Result, StackVec,
|
||||
Result,
|
||||
};
|
||||
use std::sync::{Arc, RwLock};
|
||||
|
||||
|
@ -429,7 +429,7 @@ pub fn imap_search(
|
|||
(_sort_field, _sort_order): (SortField, SortOrder),
|
||||
folder_hash: FolderHash,
|
||||
backend: &Arc<RwLock<Box<dyn MailBackend>>>,
|
||||
) -> Result<StackVec<EnvelopeHash>> {
|
||||
) -> Result<smallvec::SmallVec<[EnvelopeHash; 512]>> {
|
||||
let query = query().parse(term)?.1;
|
||||
let backend_lck = backend.read().unwrap();
|
||||
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
use super::*;
|
||||
use crate::types::segment_tree::SegmentTree;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
mod conversations;
|
||||
pub use self::conversations::*;
|
||||
|
@ -56,10 +57,10 @@ pub trait MailListingTrait: ListingTrait {
|
|||
a: &ListingAction,
|
||||
) {
|
||||
let account = &mut context.accounts[self.coordinates().0];
|
||||
let mut envs_to_set: StackVec<EnvelopeHash> = StackVec::new();
|
||||
let mut envs_to_set: SmallVec<[EnvelopeHash; 8]> = SmallVec::new();
|
||||
let folder_hash = account[self.coordinates().1].unwrap().folder.hash();
|
||||
{
|
||||
let mut stack = StackVec::new();
|
||||
let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
|
||||
stack.push(thread_hash);
|
||||
while let Some(thread_iter) = stack.pop() {
|
||||
{
|
||||
|
@ -138,8 +139,8 @@ pub trait MailListingTrait: ListingTrait {
|
|||
}
|
||||
}
|
||||
|
||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash>;
|
||||
fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash>;
|
||||
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]>;
|
||||
fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]>;
|
||||
}
|
||||
|
||||
pub trait ListingTrait: Component {
|
||||
|
|
|
@ -69,18 +69,18 @@ pub struct CompactListing {
|
|||
/// If `self.view` exists or not.
|
||||
unfocused: bool,
|
||||
view: ThreadView,
|
||||
row_updates: StackVec<ThreadHash>,
|
||||
row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
|
||||
movement: Option<PageMovement>,
|
||||
id: ComponentId,
|
||||
}
|
||||
|
||||
impl MailListingTrait for CompactListing {
|
||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
|
||||
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
|
||||
&mut self.row_updates
|
||||
}
|
||||
|
||||
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
|
||||
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
||||
let cursor_iter;
|
||||
|
@ -96,7 +96,7 @@ impl MailListingTrait for CompactListing {
|
|||
.flatten()
|
||||
.chain(cursor_iter.into_iter().flatten())
|
||||
.cloned();
|
||||
StackVec::from_iter(iter.into_iter())
|
||||
SmallVec::from_iter(iter.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -530,7 +530,7 @@ impl CompactListing {
|
|||
filtered_selection: Vec::new(),
|
||||
filtered_order: FnvHashMap::default(),
|
||||
selection: FnvHashMap::default(),
|
||||
row_updates: StackVec::new(),
|
||||
row_updates: SmallVec::new(),
|
||||
data_columns: DataColumns::default(),
|
||||
dirty: true,
|
||||
force_draw: true,
|
||||
|
@ -554,7 +554,7 @@ impl CompactListing {
|
|||
.hash();
|
||||
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
|
||||
let mut tags = String::new();
|
||||
let mut colors = StackVec::new();
|
||||
let mut colors: SmallVec<[_; 8]> = SmallVec::new();
|
||||
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
|
@ -681,17 +681,17 @@ impl CompactListing {
|
|||
let mut rows = Vec::with_capacity(1024);
|
||||
let mut min_width = (0, 0, 0, 0, 0);
|
||||
let mut row_widths: (
|
||||
StackVec<u8>,
|
||||
StackVec<u8>,
|
||||
StackVec<u8>,
|
||||
StackVec<u8>,
|
||||
StackVec<u8>,
|
||||
SmallVec<[u8; 1024]>,
|
||||
SmallVec<[u8; 1024]>,
|
||||
SmallVec<[u8; 1024]>,
|
||||
SmallVec<[u8; 1024]>,
|
||||
SmallVec<[u8; 1024]>,
|
||||
) = (
|
||||
StackVec::new(),
|
||||
StackVec::new(),
|
||||
StackVec::new(),
|
||||
StackVec::new(),
|
||||
StackVec::new(),
|
||||
SmallVec::new(),
|
||||
SmallVec::new(),
|
||||
SmallVec::new(),
|
||||
SmallVec::new(),
|
||||
SmallVec::new(),
|
||||
);
|
||||
|
||||
threads.sort_by(self.sort, self.subsort, &account.collection.envelopes);
|
||||
|
|
|
@ -73,7 +73,7 @@ column_str!(struct DateString(String));
|
|||
column_str!(struct FromString(String));
|
||||
column_str!(struct SubjectString(String));
|
||||
column_str!(struct FlagString(String));
|
||||
column_str!(struct TagString(String, StackVec<Color>));
|
||||
column_str!(struct TagString(String, SmallVec<[Color; 8]>));
|
||||
|
||||
/// A list of all mail (`Envelope`s) in a `Mailbox`. On `\n` it opens the `Envelope` content in a
|
||||
/// `ThreadView`.
|
||||
|
@ -100,18 +100,18 @@ pub struct ConversationsListing {
|
|||
/// If `self.view` exists or not.
|
||||
unfocused: bool,
|
||||
view: ThreadView,
|
||||
row_updates: StackVec<ThreadHash>,
|
||||
row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
|
||||
movement: Option<PageMovement>,
|
||||
id: ComponentId,
|
||||
}
|
||||
|
||||
impl MailListingTrait for ConversationsListing {
|
||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
|
||||
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
|
||||
&mut self.row_updates
|
||||
}
|
||||
|
||||
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
|
||||
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||
let i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
|
||||
let cursor_iter;
|
||||
|
@ -127,7 +127,7 @@ impl MailListingTrait for ConversationsListing {
|
|||
.flatten()
|
||||
.chain(cursor_iter.into_iter().flatten())
|
||||
.cloned();
|
||||
StackVec::from_iter(iter.into_iter())
|
||||
SmallVec::from_iter(iter.into_iter())
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -500,7 +500,7 @@ impl ConversationsListing {
|
|||
filtered_selection: Vec::new(),
|
||||
filtered_order: FnvHashMap::default(),
|
||||
selection: FnvHashMap::default(),
|
||||
row_updates: StackVec::new(),
|
||||
row_updates: SmallVec::new(),
|
||||
content: Default::default(),
|
||||
dirty: true,
|
||||
force_draw: true,
|
||||
|
@ -525,7 +525,7 @@ impl ConversationsListing {
|
|||
.hash();
|
||||
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
|
||||
let mut tags = String::new();
|
||||
let mut colors = StackVec::new();
|
||||
let mut colors = SmallVec::new();
|
||||
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
|
@ -690,7 +690,7 @@ impl ConversationsListing {
|
|||
}
|
||||
from_address_list.clear();
|
||||
from_address_set.clear();
|
||||
let mut stack = StackVec::new();
|
||||
let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
|
||||
stack.push(root_idx);
|
||||
while let Some(h) = stack.pop() {
|
||||
let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() {
|
||||
|
@ -952,7 +952,7 @@ impl ConversationsListing {
|
|||
let mut from_address_list = Vec::new();
|
||||
let mut from_address_set: std::collections::HashSet<Vec<u8>> =
|
||||
std::collections::HashSet::new();
|
||||
let mut stack = StackVec::new();
|
||||
let mut stack: SmallVec<[ThreadHash; 8]> = SmallVec::new();
|
||||
stack.push(thread_hash);
|
||||
while let Some(h) = stack.pop() {
|
||||
let env_hash = if let Some(h) = threads.thread_nodes()[&h].message() {
|
||||
|
|
|
@ -70,19 +70,19 @@ pub struct PlainListing {
|
|||
/// If `self.view` exists or not.
|
||||
unfocused: bool,
|
||||
view: MailView,
|
||||
row_updates: StackVec<EnvelopeHash>,
|
||||
_row_updates: StackVec<ThreadHash>,
|
||||
row_updates: SmallVec<[EnvelopeHash; 8]>,
|
||||
_row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
|
||||
movement: Option<PageMovement>,
|
||||
id: ComponentId,
|
||||
}
|
||||
|
||||
impl MailListingTrait for PlainListing {
|
||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
|
||||
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
|
||||
&mut self._row_updates
|
||||
}
|
||||
|
||||
fn get_focused_items(&self, context: &Context) -> StackVec<ThreadHash> {
|
||||
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
|
||||
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
|
||||
if is_selection_empty {
|
||||
self.selection
|
||||
|
@ -91,7 +91,7 @@ impl MailListingTrait for PlainListing {
|
|||
.map(|(k, _)| self.thread_hashes[k])
|
||||
.collect()
|
||||
} else {
|
||||
let mut ret = StackVec::new();
|
||||
let mut ret = SmallVec::new();
|
||||
ret.push(self.get_thread_under_cursor(self.cursor_pos.2, context));
|
||||
ret
|
||||
}
|
||||
|
@ -484,8 +484,8 @@ impl PlainListing {
|
|||
filtered_selection: Vec::new(),
|
||||
filtered_order: FnvHashMap::default(),
|
||||
selection: FnvHashMap::default(),
|
||||
row_updates: StackVec::new(),
|
||||
_row_updates: StackVec::new(),
|
||||
row_updates: SmallVec::new(),
|
||||
_row_updates: SmallVec::new(),
|
||||
data_columns: DataColumns::default(),
|
||||
dirty: true,
|
||||
force_draw: true,
|
||||
|
@ -503,7 +503,7 @@ impl PlainListing {
|
|||
.hash();
|
||||
let folder = &context.accounts[self.cursor_pos.0].folder_confs[&folder_hash];
|
||||
let mut tags = String::new();
|
||||
let mut colors = StackVec::new();
|
||||
let mut colors = SmallVec::new();
|
||||
let backend_lck = context.accounts[self.cursor_pos.0].backend.read().unwrap();
|
||||
if let Some(t) = backend_lck.tags() {
|
||||
let tags_lck = t.read().unwrap();
|
||||
|
@ -1086,7 +1086,7 @@ impl Component for PlainListing {
|
|||
.flatten()
|
||||
.chain(cursor_iter.into_iter().flatten())
|
||||
.cloned();
|
||||
let stack = StackVec::from_iter(iter.into_iter());
|
||||
let stack: SmallVec<[_; 8]> = SmallVec::from_iter(iter.into_iter());
|
||||
for i in stack {
|
||||
self.perform_action(context, i, a);
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@ pub struct ThreadListing {
|
|||
/// Cache current view.
|
||||
content: CellBuffer,
|
||||
|
||||
row_updates: StackVec<ThreadHash>,
|
||||
row_updates: SmallVec<[ThreadHash; 8]>,
|
||||
locations: Vec<EnvelopeHash>,
|
||||
/// If we must redraw on next redraw event
|
||||
dirty: bool,
|
||||
|
@ -50,12 +50,12 @@ pub struct ThreadListing {
|
|||
}
|
||||
|
||||
impl MailListingTrait for ThreadListing {
|
||||
fn row_updates(&mut self) -> &mut StackVec<ThreadHash> {
|
||||
fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
|
||||
&mut self.row_updates
|
||||
}
|
||||
|
||||
fn get_focused_items(&self, _context: &Context) -> StackVec<ThreadHash> {
|
||||
StackVec::new()
|
||||
fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]> {
|
||||
SmallVec::new()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -242,7 +242,7 @@ impl ThreadListing {
|
|||
sort: (Default::default(), Default::default()),
|
||||
subsort: (Default::default(), Default::default()),
|
||||
content,
|
||||
row_updates: StackVec::new(),
|
||||
row_updates: SmallVec::new(),
|
||||
locations: Vec::new(),
|
||||
dirty: true,
|
||||
unfocused: false,
|
||||
|
|
|
@ -22,6 +22,7 @@
|
|||
use super::*;
|
||||
use melib::list_management;
|
||||
use melib::parser::BytesExt;
|
||||
use smallvec::SmallVec;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::process::{Command, Stdio};
|
||||
|
@ -229,7 +230,7 @@ impl MailView {
|
|||
if body.count_attachments() > 1 {
|
||||
fn attachment_tree(
|
||||
(idx, (depth, att)): (&mut usize, (usize, &Attachment)),
|
||||
branches: &mut StackVec<bool>,
|
||||
branches: &mut SmallVec<[bool; 8]>,
|
||||
has_sibling: bool,
|
||||
s: &mut String,
|
||||
) {
|
||||
|
@ -286,7 +287,7 @@ impl MailView {
|
|||
_ => {}
|
||||
}
|
||||
}
|
||||
attachment_tree((&mut 0, (0, &body)), &mut StackVec::new(), false, &mut t);
|
||||
attachment_tree((&mut 0, (0, &body)), &mut SmallVec::new(), false, &mut t);
|
||||
}
|
||||
t
|
||||
}
|
||||
|
@ -1385,7 +1386,7 @@ impl Component for MailView {
|
|||
}
|
||||
_ => { /* error print message to user */ }
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
UIEvent::Action(Listing(OpenInNewTab)) => {
|
||||
context
|
||||
|
|
|
@ -848,7 +848,7 @@ impl ThreadView {
|
|||
.iter()
|
||||
.enumerate()
|
||||
.fold(
|
||||
(vec![Vec::new()], StackVec::new(), false),
|
||||
(vec![Vec::new()], SmallVec::<[_; 8]>::new(), false),
|
||||
|(mut visies, mut stack, is_prev_hidden), (idx, e)| {
|
||||
match (e.hidden, is_prev_hidden) {
|
||||
(true, false) => {
|
||||
|
|
|
@ -34,7 +34,7 @@ use melib::error::{MeliError, Result};
|
|||
use melib::mailbox::*;
|
||||
use melib::thread::{SortField, SortOrder, ThreadHash, ThreadNode, Threads};
|
||||
use melib::AddressBook;
|
||||
use melib::StackVec;
|
||||
use smallvec::SmallVec;
|
||||
use text_processing::GlobMatch;
|
||||
|
||||
use crate::types::UIEvent::{self, EnvelopeRemove, EnvelopeRename, EnvelopeUpdate, Notification};
|
||||
|
@ -384,7 +384,7 @@ impl Account {
|
|||
folder_names.insert(f.hash(), f.path().to_string());
|
||||
}
|
||||
|
||||
let mut stack: StackVec<FolderHash> = StackVec::new();
|
||||
let mut stack: SmallVec<[FolderHash; 8]> = SmallVec::new();
|
||||
let mut tree: Vec<FolderNode> = Vec::new();
|
||||
let mut collection: Collection = Collection::new(Default::default());
|
||||
for (h, f) in ref_folders.iter() {
|
||||
|
@ -442,7 +442,7 @@ impl Account {
|
|||
}
|
||||
});
|
||||
|
||||
let mut stack: StackVec<Option<&FolderNode>> = StackVec::new();
|
||||
let mut stack: SmallVec<[Option<&FolderNode>; 8]> = SmallVec::new();
|
||||
for n in tree.iter_mut() {
|
||||
folders_order.push(n.hash);
|
||||
n.kids.sort_unstable_by(|a, b| {
|
||||
|
@ -462,6 +462,7 @@ impl Account {
|
|||
stack.extend(next.kids.iter().rev().map(Some));
|
||||
}
|
||||
}
|
||||
drop(stack);
|
||||
|
||||
self.folders = folders;
|
||||
self.ref_folders = ref_folders;
|
||||
|
@ -1053,7 +1054,7 @@ impl Account {
|
|||
search_term: &str,
|
||||
sort: (SortField, SortOrder),
|
||||
folder_hash: FolderHash,
|
||||
) -> Result<StackVec<EnvelopeHash>> {
|
||||
) -> Result<SmallVec<[EnvelopeHash; 512]>> {
|
||||
if self.settings.account().format() == "imap" {
|
||||
return crate::cache::imap_search(search_term, sort, folder_hash, &self.backend);
|
||||
}
|
||||
|
@ -1081,7 +1082,7 @@ impl Account {
|
|||
|
||||
#[cfg(not(feature = "sqlite3"))]
|
||||
{
|
||||
let mut ret = StackVec::new();
|
||||
let mut ret = SmallVec::new();
|
||||
let envelopes = self.collection.envelopes.clone().read();
|
||||
let envelopes = envelopes.unwrap();
|
||||
|
||||
|
|
|
@ -40,6 +40,7 @@ extern crate termion;
|
|||
extern crate nom;
|
||||
|
||||
extern crate serde_json;
|
||||
pub extern crate smallvec;
|
||||
|
||||
use melib::*;
|
||||
use std::collections::VecDeque;
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
* along with meli. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use crate::cache::query;
|
||||
use crate::cache::Query::{self, *};
|
||||
use crate::melib::parsec::Parser;
|
||||
|
@ -27,7 +28,7 @@ use melib::{
|
|||
email::{Envelope, EnvelopeHash},
|
||||
log,
|
||||
thread::{SortField, SortOrder},
|
||||
MeliError, Result, StackVec, ERROR,
|
||||
MeliError, Result, ERROR,
|
||||
};
|
||||
use rusqlite::{params, Connection};
|
||||
use std::borrow::Cow;
|
||||
|
@ -389,7 +390,7 @@ pub fn index(context: &mut crate::state::Context, account_name: &str) -> Result<
|
|||
pub fn search(
|
||||
term: &str,
|
||||
(sort_field, sort_order): (SortField, SortOrder),
|
||||
) -> Result<StackVec<EnvelopeHash>> {
|
||||
) -> Result<SmallVec<[EnvelopeHash; 512]>> {
|
||||
let conn = open_db()?;
|
||||
|
||||
let sort_field = match debug!(sort_field) {
|
||||
|
@ -425,7 +426,7 @@ pub fn search(
|
|||
.map_err(|e: std::array::TryFromSliceError| MeliError::new(e.to_string()))?,
|
||||
))
|
||||
})
|
||||
.collect::<Result<StackVec<EnvelopeHash>>>();
|
||||
.collect::<Result<SmallVec<[EnvelopeHash; 512]>>>();
|
||||
results
|
||||
}
|
||||
|
||||
|
|
|
@ -103,7 +103,7 @@ pub struct Context {
|
|||
}
|
||||
|
||||
impl Context {
|
||||
pub fn replies(&mut self) -> Vec<UIEvent> {
|
||||
pub fn replies(&mut self) -> smallvec::SmallVec<[UIEvent; 8]> {
|
||||
self.replies.drain(0..).collect()
|
||||
}
|
||||
|
||||
|
@ -437,7 +437,8 @@ impl State {
|
|||
for i in 0..self.components.len() {
|
||||
self.draw_component(i);
|
||||
}
|
||||
let mut areas: Vec<Area> = self.context.dirty_areas.drain(0..).collect();
|
||||
let mut areas: smallvec::SmallVec<[Area; 8]> =
|
||||
self.context.dirty_areas.drain(0..).collect();
|
||||
if areas.is_empty() {
|
||||
return;
|
||||
}
|
||||
|
@ -682,7 +683,8 @@ impl State {
|
|||
}
|
||||
|
||||
if !self.context.replies.is_empty() {
|
||||
let replies: Vec<UIEvent> = self.context.replies.drain(0..).collect();
|
||||
let replies: smallvec::SmallVec<[UIEvent; 8]> =
|
||||
self.context.replies.drain(0..).collect();
|
||||
// Pass replies to self and call count on the map iterator to force evaluation
|
||||
replies.into_iter().map(|r| self.rcv_event(r)).count();
|
||||
}
|
||||
|
|
|
@ -152,24 +152,24 @@ pub mod segment_tree {
|
|||
/*! Simple segment tree implementation for maximum in range queries. This is useful if given an
|
||||
* array of numbers you want to get the maximum value inside an interval quickly.
|
||||
*/
|
||||
use melib::StackVec;
|
||||
use smallvec::SmallVec;
|
||||
use std::convert::TryFrom;
|
||||
use std::iter::FromIterator;
|
||||
|
||||
#[derive(Default, Debug, Clone)]
|
||||
pub struct SegmentTree {
|
||||
array: StackVec<u8>,
|
||||
tree: StackVec<u8>,
|
||||
array: SmallVec<[u8; 1024]>,
|
||||
tree: SmallVec<[u8; 1024]>,
|
||||
}
|
||||
|
||||
impl From<StackVec<u8>> for SegmentTree {
|
||||
fn from(val: StackVec<u8>) -> SegmentTree {
|
||||
impl From<SmallVec<[u8; 1024]>> for SegmentTree {
|
||||
fn from(val: SmallVec<[u8; 1024]>) -> SegmentTree {
|
||||
SegmentTree::new(val)
|
||||
}
|
||||
}
|
||||
|
||||
impl SegmentTree {
|
||||
pub fn new(val: StackVec<u8>) -> SegmentTree {
|
||||
pub fn new(val: SmallVec<[u8; 1024]>) -> SegmentTree {
|
||||
if val.is_empty() {
|
||||
return SegmentTree {
|
||||
array: val.clone(),
|
||||
|
@ -182,8 +182,8 @@ pub mod segment_tree {
|
|||
.ceil() as u32;
|
||||
let max_size = 2 * (2_usize.pow(height)) - 1;
|
||||
|
||||
let mut segment_tree: StackVec<u8> =
|
||||
StackVec::from_iter(core::iter::repeat(0).take(max_size));
|
||||
let mut segment_tree: SmallVec<[u8; 1024]> =
|
||||
SmallVec::from_iter(core::iter::repeat(0).take(max_size));
|
||||
for i in 0..val.len() {
|
||||
segment_tree[val.len() + i] = val[i];
|
||||
}
|
||||
|
@ -231,10 +231,10 @@ pub mod segment_tree {
|
|||
|
||||
#[test]
|
||||
fn test_segment_tree() {
|
||||
let array: StackVec<u8> = [9, 1, 17, 2, 3, 23, 4, 5, 6, 37]
|
||||
let array: SmallVec<[u8; 1024]> = [9, 1, 17, 2, 3, 23, 4, 5, 6, 37]
|
||||
.into_iter()
|
||||
.cloned()
|
||||
.collect::<StackVec<u8>>();
|
||||
.collect::<SmallVec<[u8; 1024]>>();
|
||||
let segment_tree = SegmentTree::from(array.clone());
|
||||
|
||||
assert_eq!(segment_tree.get_max(0, 5), 23);
|
||||
|
|
Loading…
Reference in New Issue