Browse Source

move StackVec to melib

closes #120
tags/pre-alpha-0.0
parent
commit
6f7b3f20de
WARNING! Although there is a key with this ID in the database it does not verify this commit! This commit is SUSPICIOUS. GPG Key ID: 73627C2F690DF710
5 changed files with 126 additions and 86 deletions
  1. +2
    -0
      melib/src/lib.rs
  2. +8
    -7
      melib/src/mailbox/thread.rs
  3. +115
    -0
      melib/src/structs.rs
  4. +1
    -1
      ui/src/conf/accounts.rs
  5. +0
    -78
      ui/src/types.rs

+ 2
- 0
melib/src/lib.rs View File

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


+ 8
- 7
melib/src/mailbox/thread.rs View File

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


+ 115
- 0
melib/src/structs.rs 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);
}
}
}

+ 1
- 1
ui/src/conf/accounts.rs View File

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


+ 0
- 78
ui/src/types.rs View File

@@ -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…
Cancel
Save