move StackVec to melib

closes #120
embed
Manos Pitsidianakis 2019-05-26 21:34:34 +03:00
parent 42654410e3
commit 6f7b3f20de
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
5 changed files with 126 additions and 86 deletions

View File

@ -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;

View File

@ -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();

View File

@ -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);
}
}
}

View File

@ -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;

View File

@ -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);
}
}
}