parent
42654410e3
commit
6f7b3f20de
|
@ -86,6 +86,8 @@ pub mod mailbox;
|
|||
mod wcwidth;
|
||||
pub use self::grapheme_clusters::*;
|
||||
pub use self::wcwidth::*;
|
||||
mod structs;
|
||||
pub use self::structs::*;
|
||||
|
||||
#[macro_use]
|
||||
extern crate serde_derive;
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
use crate::grapheme_clusters::*;
|
||||
use crate::mailbox::email::parser::BytesExt;
|
||||
use crate::mailbox::email::*;
|
||||
use crate::structs::StackVec;
|
||||
use uuid::Uuid;
|
||||
|
||||
use fnv::{FnvHashMap, FnvHashSet};
|
||||
|
@ -350,7 +351,7 @@ impl ThreadTree {
|
|||
|
||||
pub struct ThreadsIterator<'a> {
|
||||
pos: usize,
|
||||
stack: Vec<usize>,
|
||||
stack: StackVec<usize>,
|
||||
tree: Ref<'a, Vec<ThreadTree>>,
|
||||
}
|
||||
impl<'a> Iterator for ThreadsIterator<'a> {
|
||||
|
@ -358,7 +359,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
|
|||
fn next(&mut self) -> Option<(usize, ThreadHash, bool)> {
|
||||
{
|
||||
let mut tree = &(*self.tree);
|
||||
for i in &self.stack {
|
||||
for i in self.stack.iter() {
|
||||
tree = &tree[*i].children;
|
||||
}
|
||||
if self.pos == tree.len() {
|
||||
|
@ -402,7 +403,7 @@ impl<'a> Iterator for ThreadsIterator<'a> {
|
|||
pub struct ThreadIterator<'a> {
|
||||
init_pos: usize,
|
||||
pos: usize,
|
||||
stack: Vec<usize>,
|
||||
stack: StackVec<usize>,
|
||||
tree: Ref<'a, Vec<ThreadTree>>,
|
||||
}
|
||||
impl<'a> Iterator for ThreadIterator<'a> {
|
||||
|
@ -410,7 +411,7 @@ impl<'a> Iterator for ThreadIterator<'a> {
|
|||
fn next(&mut self) -> Option<(usize, ThreadHash)> {
|
||||
{
|
||||
let mut tree = &(*self.tree);
|
||||
for i in &self.stack {
|
||||
for i in self.stack.iter() {
|
||||
tree = &tree[*i].children;
|
||||
}
|
||||
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 {
|
||||
ThreadsIterator {
|
||||
pos: 0,
|
||||
stack: Vec::with_capacity(4),
|
||||
stack: StackVec::new(),
|
||||
tree: self.tree.borrow(),
|
||||
}
|
||||
}
|
||||
|
@ -832,7 +833,7 @@ impl Threads {
|
|||
ThreadIterator {
|
||||
init_pos: index,
|
||||
pos: index,
|
||||
stack: Vec::with_capacity(4),
|
||||
stack: StackVec::new(),
|
||||
tree: self.tree.borrow(),
|
||||
}
|
||||
}
|
||||
|
@ -1057,7 +1058,7 @@ impl Threads {
|
|||
/* Update thread tree information on envelope insertion */
|
||||
fn rebuild_thread(&mut self, id: ThreadHash, envelopes: &Envelopes) {
|
||||
let mut node_idx = id;
|
||||
let mut stack = Vec::with_capacity(32);
|
||||
let mut stack = StackVec::new();
|
||||
|
||||
{
|
||||
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::ToggleFlag;
|
||||
use crate::StackVec;
|
||||
use fnv::FnvHashMap;
|
||||
use melib::async_workers::{Async, AsyncBuilder, AsyncStatus};
|
||||
use melib::backends::FolderHash;
|
||||
|
@ -37,6 +36,7 @@ use melib::mailbox::backends::{
|
|||
use melib::mailbox::*;
|
||||
use melib::thread::ThreadHash;
|
||||
use melib::AddressBook;
|
||||
use melib::StackVec;
|
||||
|
||||
use std::collections::VecDeque;
|
||||
use std::fs;
|
||||
|
|
|
@ -30,8 +30,6 @@ use melib::backends::FolderHash;
|
|||
use melib::{EnvelopeHash, RefreshEvent};
|
||||
use std;
|
||||
use std::fmt;
|
||||
use std::iter::Extend;
|
||||
use std::ops::Index;
|
||||
use std::thread;
|
||||
use uuid::Uuid;
|
||||
|
||||
|
@ -129,79 +127,3 @@ pub struct Notification {
|
|||
|
||||
_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