parent
42654410e3
commit
6f7b3f20de
|
@ -86,6 +86,8 @@ pub mod mailbox;
|
||||||
mod wcwidth;
|
mod wcwidth;
|
||||||
pub use self::grapheme_clusters::*;
|
pub use self::grapheme_clusters::*;
|
||||||
pub use self::wcwidth::*;
|
pub use self::wcwidth::*;
|
||||||
|
mod structs;
|
||||||
|
pub use self::structs::*;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
|
|
@ -35,6 +35,7 @@
|
||||||
use crate::grapheme_clusters::*;
|
use crate::grapheme_clusters::*;
|
||||||
use crate::mailbox::email::parser::BytesExt;
|
use crate::mailbox::email::parser::BytesExt;
|
||||||
use crate::mailbox::email::*;
|
use crate::mailbox::email::*;
|
||||||
|
use crate::structs::StackVec;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
use fnv::{FnvHashMap, FnvHashSet};
|
use fnv::{FnvHashMap, FnvHashSet};
|
||||||
|
@ -350,7 +351,7 @@ impl ThreadTree {
|
||||||
|
|
||||||
pub struct ThreadsIterator<'a> {
|
pub struct ThreadsIterator<'a> {
|
||||||
pos: usize,
|
pos: usize,
|
||||||
stack: Vec<usize>,
|
stack: StackVec<usize>,
|
||||||
tree: Ref<'a, Vec<ThreadTree>>,
|
tree: Ref<'a, Vec<ThreadTree>>,
|
||||||
}
|
}
|
||||||
impl<'a> Iterator for ThreadsIterator<'a> {
|
impl<'a> Iterator for ThreadsIterator<'a> {
|
||||||
|
@ -358,7 +359,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
|
||||||
fn next(&mut self) -> Option<(usize, ThreadHash, bool)> {
|
fn next(&mut self) -> Option<(usize, ThreadHash, bool)> {
|
||||||
{
|
{
|
||||||
let mut tree = &(*self.tree);
|
let mut tree = &(*self.tree);
|
||||||
for i in &self.stack {
|
for i in self.stack.iter() {
|
||||||
tree = &tree[*i].children;
|
tree = &tree[*i].children;
|
||||||
}
|
}
|
||||||
if self.pos == tree.len() {
|
if self.pos == tree.len() {
|
||||||
|
@ -402,7 +403,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
|
||||||
pub struct ThreadIterator<'a> {
|
pub struct ThreadIterator<'a> {
|
||||||
init_pos: usize,
|
init_pos: usize,
|
||||||
pos: usize,
|
pos: usize,
|
||||||
stack: Vec<usize>,
|
stack: StackVec<usize>,
|
||||||
tree: Ref<'a, Vec<ThreadTree>>,
|
tree: Ref<'a, Vec<ThreadTree>>,
|
||||||
}
|
}
|
||||||
impl<'a> Iterator for ThreadIterator<'a> {
|
impl<'a> Iterator for ThreadIterator<'a> {
|
||||||
|
@ -410,7 +411,7 @@ impl<'a> Iterator for ThreadIterator<'a> {
|
||||||
fn next(&mut self) -> Option<(usize, ThreadHash)> {
|
fn next(&mut self) -> Option<(usize, ThreadHash)> {
|
||||||
{
|
{
|
||||||
let mut tree = &(*self.tree);
|
let mut tree = &(*self.tree);
|
||||||
for i in &self.stack {
|
for i in self.stack.iter() {
|
||||||
tree = &tree[*i].children;
|
tree = &tree[*i].children;
|
||||||
}
|
}
|
||||||
if self.pos == tree.len() || (self.stack.is_empty() && self.pos > self.init_pos) {
|
if self.pos == tree.len() || (self.stack.is_empty() && self.pos > self.init_pos) {
|
||||||
|
@ -823,7 +824,7 @@ impl Threads {
|
||||||
pub fn threads_iter(&self) -> ThreadsIterator {
|
pub fn threads_iter(&self) -> ThreadsIterator {
|
||||||
ThreadsIterator {
|
ThreadsIterator {
|
||||||
pos: 0,
|
pos: 0,
|
||||||
stack: Vec::with_capacity(4),
|
stack: StackVec::new(),
|
||||||
tree: self.tree.borrow(),
|
tree: self.tree.borrow(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -832,7 +833,7 @@ impl Threads {
|
||||||
ThreadIterator {
|
ThreadIterator {
|
||||||
init_pos: index,
|
init_pos: index,
|
||||||
pos: index,
|
pos: index,
|
||||||
stack: Vec::with_capacity(4),
|
stack: StackVec::new(),
|
||||||
tree: self.tree.borrow(),
|
tree: self.tree.borrow(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1057,7 +1058,7 @@ impl Threads {
|
||||||
/* Update thread tree information on envelope insertion */
|
/* Update thread tree information on envelope insertion */
|
||||||
fn rebuild_thread(&mut self, id: ThreadHash, envelopes: &Envelopes) {
|
fn rebuild_thread(&mut self, id: ThreadHash, envelopes: &Envelopes) {
|
||||||
let mut node_idx = id;
|
let mut node_idx = id;
|
||||||
let mut stack = Vec::with_capacity(32);
|
let mut stack = StackVec::new();
|
||||||
|
|
||||||
{
|
{
|
||||||
let tree = self.tree.get_mut();
|
let tree = self.tree.get_mut();
|
||||||
|
|
|
@ -0,0 +1,115 @@
|
||||||
|
use std::iter::Extend;
|
||||||
|
use std::ops::Index;
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct StackVec<T: Default + Copy + std::fmt::Debug> {
|
||||||
|
len: usize,
|
||||||
|
array: [T; 32],
|
||||||
|
heap_vec: Vec<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T: Default + Copy + std::fmt::Debug> StackVec<T> {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
StackVec {
|
||||||
|
len: 0,
|
||||||
|
array: [T::default(); 32],
|
||||||
|
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(32);
|
||||||
|
for _ in 0..8 {
|
||||||
|
self.heap_vec.push(T::default());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
self.heap_vec[0..8].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 = 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 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> Extend<T> for StackVec<T> {
|
||||||
|
fn extend<I>(&mut self, iter: I)
|
||||||
|
where
|
||||||
|
I: IntoIterator<Item = T>,
|
||||||
|
{
|
||||||
|
for elem in iter {
|
||||||
|
self.push(elem);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -25,7 +25,6 @@
|
||||||
|
|
||||||
use super::AccountConf;
|
use super::AccountConf;
|
||||||
use super::ToggleFlag;
|
use super::ToggleFlag;
|
||||||
use crate::StackVec;
|
|
||||||
use fnv::FnvHashMap;
|
use fnv::FnvHashMap;
|
||||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||||
use melib::backends::FolderHash;
|
use melib::backends::FolderHash;
|
||||||
|
@ -37,6 +36,7 @@ use melib::mailbox::backends::{
|
||||||
use melib::mailbox::*;
|
use melib::mailbox::*;
|
||||||
use melib::thread::ThreadHash;
|
use melib::thread::ThreadHash;
|
||||||
use melib::AddressBook;
|
use melib::AddressBook;
|
||||||
|
use melib::StackVec;
|
||||||
|
|
||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
|
|
@ -30,8 +30,6 @@ use melib::backends::FolderHash;
|
||||||
use melib::{EnvelopeHash, RefreshEvent};
|
use melib::{EnvelopeHash, RefreshEvent};
|
||||||
use std;
|
use std;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::iter::Extend;
|
|
||||||
use std::ops::Index;
|
|
||||||
use std::thread;
|
use std::thread;
|
||||||
use uuid::Uuid;
|
use uuid::Uuid;
|
||||||
|
|
||||||
|
@ -129,79 +127,3 @@ pub struct Notification {
|
||||||
|
|
||||||
_timestamp: std::time::Instant,
|
_timestamp: std::time::Instant,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub(crate) struct StackVec<T: Default + Copy + std::fmt::Debug> {
|
|
||||||
len: usize,
|
|
||||||
array: [T; 32],
|
|
||||||
heap_vec: Vec<T>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T: Default + Copy + std::fmt::Debug> StackVec<T> {
|
|
||||||
pub(crate) fn new() -> Self {
|
|
||||||
StackVec {
|
|
||||||
len: 0,
|
|
||||||
array: [T::default(); 32],
|
|
||||||
heap_vec: Vec::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub(crate) fn push(&mut self, ind: T) {
|
|
||||||
if self.len == self.array.len() {
|
|
||||||
if self.heap_vec.is_empty() {
|
|
||||||
self.heap_vec.reserve(32);
|
|
||||||
for _ in 0..8 {
|
|
||||||
self.heap_vec.push(T::default());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.heap_vec[0..8].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(crate) 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 = self.len - 1;
|
|
||||||
Some(ret)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub(crate) fn len(&self) -> usize {
|
|
||||||
self.len
|
|
||||||
}
|
|
||||||
pub(crate) fn is_empty(&self) -> bool {
|
|
||||||
self.len == 0
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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> Extend<T> for StackVec<T> {
|
|
||||||
fn extend<I>(&mut self, iter: I)
|
|
||||||
where
|
|
||||||
I: IntoIterator<Item = T>,
|
|
||||||
{
|
|
||||||
for elem in iter {
|
|
||||||
self.push(elem);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
Loading…
Reference in New Issue