melib/threads: rename thread hashes

- Rename ThreadHash to ThreadNodeHash
- Rename ThreadGroupHash to ThreadHash
async
Manos Pitsidianakis 2020-01-18 02:00:39 +02:00
parent 47a69f8eb9
commit d9269335a1
Signed by: Manos Pitsidianakis
GPG Key ID: 73627C2F690DF710
11 changed files with 129 additions and 133 deletions

View File

@ -41,7 +41,7 @@ pub mod signatures;
use crate::backends::BackendOp; use crate::backends::BackendOp;
use crate::datetime::UnixTimestamp; use crate::datetime::UnixTimestamp;
use crate::error::{MeliError, Result}; use crate::error::{MeliError, Result};
use crate::thread::ThreadHash; use crate::thread::ThreadNodeHash;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::borrow::Cow; use std::borrow::Cow;
@ -127,7 +127,7 @@ pub struct Envelope {
other_headers: FnvHashMap<String, String>, other_headers: FnvHashMap<String, String>,
timestamp: UnixTimestamp, timestamp: UnixTimestamp,
thread: ThreadHash, thread: ThreadNodeHash,
hash: EnvelopeHash, hash: EnvelopeHash,
@ -166,7 +166,7 @@ impl Envelope {
timestamp: 0, timestamp: 0,
thread: ThreadHash::null(), thread: ThreadNodeHash::null(),
hash, hash,
has_attachments: false, has_attachments: false,
@ -560,10 +560,10 @@ impl Envelope {
&mut self.other_headers &mut self.other_headers
} }
pub fn thread(&self) -> ThreadHash { pub fn thread(&self) -> ThreadNodeHash {
self.thread self.thread
} }
pub fn set_thread(&mut self, new_val: ThreadHash) { pub fn set_thread(&mut self, new_val: ThreadNodeHash) {
self.thread = new_val; self.thread = new_val;
} }
pub fn set_datetime(&mut self, new_val: UnixTimestamp) { pub fn set_datetime(&mut self, new_val: UnixTimestamp) {

View File

@ -86,14 +86,14 @@ macro_rules! uuid_hash_type {
}; };
} }
uuid_hash_type!(ThreadNodeHash);
uuid_hash_type!(ThreadHash); uuid_hash_type!(ThreadHash);
uuid_hash_type!(ThreadGroupHash);
/* Helper macros to avoid repeating ourselves */ /* Helper macros to avoid repeating ourselves */
macro_rules! remove_from_parent { macro_rules! remove_from_parent {
($buf:expr, $idx:expr) => {{ ($buf:expr, $idx:expr) => {{
let mut parent: Option<ThreadHash> = None; let mut parent: Option<ThreadNodeHash> = None;
let entry_parent = $buf.entry($idx).or_default().parent; let entry_parent = $buf.entry($idx).or_default().parent;
if let Some(p) = entry_parent { if let Some(p) = entry_parent {
parent = Some(p); parent = Some(p);
@ -272,7 +272,7 @@ impl FromStr for SortOrder {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub enum ThreadGroup { pub enum ThreadGroup {
Group { Group {
root: ThreadHash, root: ThreadNodeHash,
date: UnixTimestamp, date: UnixTimestamp,
len: usize, len: usize,
unseen: usize, unseen: usize,
@ -280,14 +280,14 @@ pub enum ThreadGroup {
snoozed: bool, snoozed: bool,
}, },
Node { Node {
parent: RefCell<ThreadGroupHash>, parent: RefCell<ThreadHash>,
}, },
} }
impl Default for ThreadGroup { impl Default for ThreadGroup {
fn default() -> Self { fn default() -> Self {
ThreadGroup::Group { ThreadGroup::Group {
root: ThreadHash::null(), root: ThreadNodeHash::null(),
date: 0, date: 0,
len: 0, len: 0,
unseen: 0, unseen: 0,
@ -314,7 +314,7 @@ macro_rules! property {
} }
} }
impl ThreadGroup { impl ThreadGroup {
property!(root: Option<ThreadHash>, None); property!(root: Option<ThreadNodeHash>, None);
property!(len: usize, 0); property!(len: usize, 0);
property!(unseen: usize, 0); property!(unseen: usize, 0);
property!(snoozed: bool, false); property!(snoozed: bool, false);
@ -338,13 +338,13 @@ impl ThreadGroup {
#[derive(Clone, Debug, Deserialize, Serialize)] #[derive(Clone, Debug, Deserialize, Serialize)]
pub struct ThreadNode { pub struct ThreadNode {
message: Option<EnvelopeHash>, message: Option<EnvelopeHash>,
parent: Option<ThreadHash>, parent: Option<ThreadNodeHash>,
children: Vec<ThreadHash>, children: Vec<ThreadNodeHash>,
date: UnixTimestamp, date: UnixTimestamp,
show_subject: bool, show_subject: bool,
pruned: bool, pruned: bool,
is_root: bool, is_root: bool,
pub group: ThreadGroupHash, pub group: ThreadHash,
unseen: bool, unseen: bool,
} }
@ -359,7 +359,7 @@ impl Default for ThreadNode {
show_subject: true, show_subject: true,
pruned: false, pruned: false,
is_root: false, is_root: false,
group: ThreadGroupHash::new(), group: ThreadHash::new(),
unseen: false, unseen: false,
} }
@ -400,7 +400,7 @@ impl ThreadNode {
self.message.is_some() self.message.is_some()
} }
pub fn parent(&self) -> Option<ThreadHash> { pub fn parent(&self) -> Option<ThreadNodeHash> {
self.parent self.parent
} }
@ -408,16 +408,16 @@ impl ThreadNode {
self.parent.is_some() self.parent.is_some()
} }
pub fn children(&self) -> &[ThreadHash] { pub fn children(&self) -> &[ThreadNodeHash] {
&self.children &self.children
} }
fn insert_child_pos( fn insert_child_pos(
vec: &[ThreadHash], vec: &[ThreadNodeHash],
child: ThreadHash, child: ThreadNodeHash,
sort: (SortField, SortOrder), sort: (SortField, SortOrder),
buf: &mut FnvHashMap<ThreadHash, ThreadNode>, buf: &mut FnvHashMap<ThreadNodeHash, ThreadNode>,
dates: &FnvHashMap<ThreadHash, UnixTimestamp>, dates: &FnvHashMap<ThreadNodeHash, UnixTimestamp>,
envelopes: &Envelopes, envelopes: &Envelopes,
) -> std::result::Result<usize, usize> { ) -> std::result::Result<usize, usize> {
let envelopes = envelopes.read().unwrap(); let envelopes = envelopes.read().unwrap();
@ -480,13 +480,12 @@ impl ThreadNode {
#[derive(Clone, Debug, Default, Deserialize, Serialize)] #[derive(Clone, Debug, Default, Deserialize, Serialize)]
pub struct Threads { pub struct Threads {
pub thread_nodes: FnvHashMap<ThreadHash, ThreadNode>, pub thread_nodes: FnvHashMap<ThreadNodeHash, ThreadNode>,
pub thread_dates: FnvHashMap<ThreadHash, UnixTimestamp>, root_set: RefCell<Vec<ThreadNodeHash>>,
root_set: RefCell<Vec<ThreadHash>>, tree_index: RefCell<Vec<ThreadNodeHash>>,
tree_index: RefCell<Vec<ThreadHash>>, pub groups: FnvHashMap<ThreadHash, ThreadGroup>,
pub groups: FnvHashMap<ThreadGroupHash, ThreadGroup>,
message_ids: FnvHashMap<Vec<u8>, ThreadHash>, message_ids: FnvHashMap<Vec<u8>, ThreadNodeHash>,
pub message_ids_set: FnvHashSet<Vec<u8>>, pub message_ids_set: FnvHashSet<Vec<u8>>,
pub missing_message_ids: FnvHashSet<Vec<u8>>, pub missing_message_ids: FnvHashSet<Vec<u8>>,
pub hash_set: FnvHashSet<EnvelopeHash>, pub hash_set: FnvHashSet<EnvelopeHash>,
@ -504,12 +503,12 @@ impl PartialEq for ThreadNode {
} }
impl Threads { impl Threads {
pub fn is_snoozed(&self, h: ThreadHash) -> bool { pub fn is_snoozed(&self, h: ThreadNodeHash) -> bool {
let root = &self.find_group(self.thread_nodes[&h].group); let root = &self.find_group(self.thread_nodes[&h].group);
self.groups[&root].snoozed() self.groups[&root].snoozed()
} }
pub fn find_group(&self, h: ThreadGroupHash) -> ThreadGroupHash { pub fn find_group(&self, h: ThreadHash) -> ThreadHash {
let p = match self.groups[&h] { let p = match self.groups[&h] {
ThreadGroup::Group { .. } => return h, ThreadGroup::Group { .. } => return h,
ThreadGroup::Node { ref parent } => *parent.borrow(), ThreadGroup::Node { ref parent } => *parent.borrow(),
@ -529,14 +528,13 @@ impl Threads {
/* To reconstruct thread information from the mails we need: */ /* To reconstruct thread information from the mails we need: */
/* a vector to hold thread members */ /* a vector to hold thread members */
let thread_nodes: FnvHashMap<ThreadHash, ThreadNode> = FnvHashMap::with_capacity_and_hasher( let thread_nodes: FnvHashMap<ThreadNodeHash, ThreadNode> =
(length as f64 * 1.2) as usize, FnvHashMap::with_capacity_and_hasher(
Default::default(), (length as f64 * 1.2) as usize,
); Default::default(),
let thread_dates: FnvHashMap<ThreadHash, UnixTimestamp> = );
FnvHashMap::with_capacity_and_hasher(thread_nodes.len(), Default::default());
/* A hash table of Message IDs */ /* A hash table of Message IDs */
let message_ids: FnvHashMap<Vec<u8>, ThreadHash> = let message_ids: FnvHashMap<Vec<u8>, ThreadNodeHash> =
FnvHashMap::with_capacity_and_hasher(length, Default::default()); FnvHashMap::with_capacity_and_hasher(length, Default::default());
/* A hash set of Message IDs we haven't encountered yet as an Envelope */ /* A hash set of Message IDs we haven't encountered yet as an Envelope */
let missing_message_ids: FnvHashSet<Vec<u8>> = let missing_message_ids: FnvHashSet<Vec<u8>> =
@ -549,7 +547,6 @@ impl Threads {
Threads { Threads {
thread_nodes, thread_nodes,
thread_dates,
message_ids, message_ids,
message_ids_set, message_ids_set,
missing_message_ids, missing_message_ids,
@ -580,7 +577,7 @@ impl Threads {
} }
} }
pub fn thread_group_iter(&self, index: ThreadGroupHash) -> ThreadGroupIterator { pub fn thread_group_iter(&self, index: ThreadHash) -> ThreadGroupIterator {
ThreadGroupIterator { ThreadGroupIterator {
group: self.groups[&index].root().unwrap(), group: self.groups[&index].root().unwrap(),
pos: 0, pos: 0,
@ -634,7 +631,7 @@ impl Threads {
pub fn remove(&mut self, envelope_hash: EnvelopeHash) { pub fn remove(&mut self, envelope_hash: EnvelopeHash) {
self.hash_set.remove(&envelope_hash); self.hash_set.remove(&envelope_hash);
let t_id: ThreadHash = if let Some((pos, n)) = self let t_id: ThreadNodeHash = if let Some((pos, n)) = self
.thread_nodes .thread_nodes
.iter_mut() .iter_mut()
.find(|(_, n)| n.message.map(|n| n == envelope_hash).unwrap_or(false)) .find(|(_, n)| n.message.map(|n| n == envelope_hash).unwrap_or(false))
@ -675,7 +672,7 @@ impl Threads {
/// Update show_subject details of ThreadNode /// Update show_subject details of ThreadNode
pub fn update_show_subject( pub fn update_show_subject(
&mut self, &mut self,
id: ThreadHash, id: ThreadNodeHash,
env_hash: EnvelopeHash, env_hash: EnvelopeHash,
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
@ -726,7 +723,7 @@ impl Threads {
other_folder: bool, other_folder: bool,
) -> bool { ) -> bool {
let envelopes_lck = envelopes.read().unwrap(); let envelopes_lck = envelopes.read().unwrap();
let reply_to_id: Option<ThreadHash> = envelopes_lck[&env_hash] let reply_to_id: Option<ThreadNodeHash> = envelopes_lck[&env_hash]
.in_reply_to() .in_reply_to()
.map(crate::email::StrBuild::raw) .map(crate::email::StrBuild::raw)
.and_then(|r| self.message_ids.get(r).cloned()); .and_then(|r| self.message_ids.get(r).cloned());
@ -743,7 +740,7 @@ impl Threads {
.message_ids .message_ids
.get(envelopes_lck[&env_hash].message_id().raw()) .get(envelopes_lck[&env_hash].message_id().raw())
.cloned() .cloned()
.unwrap_or_else(|| ThreadHash::new()); .unwrap_or_else(|| ThreadNodeHash::new());
{ {
let mut node = self.thread_nodes.entry(new_id).or_default(); let mut node = self.thread_nodes.entry(new_id).or_default();
node.message = Some(env_hash); node.message = Some(env_hash);
@ -751,7 +748,6 @@ impl Threads {
node.parent = reply_to_id; node.parent = reply_to_id;
} }
node.date = envelopes_lck[&env_hash].date(); node.date = envelopes_lck[&env_hash].date();
*self.thread_dates.entry(new_id).or_default() = node.date;
node.unseen = !envelopes_lck[&env_hash].is_seen(); node.unseen = !envelopes_lck[&env_hash].is_seen();
} }
@ -788,7 +784,7 @@ impl Threads {
.in_reply_to() .in_reply_to()
.map(crate::email::StrBuild::raw) .map(crate::email::StrBuild::raw)
{ {
let reply_to_id = ThreadHash::new(); let reply_to_id = ThreadNodeHash::new();
self.thread_nodes.insert( self.thread_nodes.insert(
reply_to_id, reply_to_id,
ThreadNode { ThreadNode {
@ -832,7 +828,7 @@ impl Threads {
make!((id) parent of (current_descendant_id), self); make!((id) parent of (current_descendant_id), self);
current_descendant_id = id; current_descendant_id = id;
} else { } else {
let id = ThreadHash::new(); let id = ThreadNodeHash::new();
self.thread_nodes.insert( self.thread_nodes.insert(
id, id,
ThreadNode { ThreadNode {
@ -876,7 +872,7 @@ impl Threads {
.message_ids .message_ids
.iter() .iter()
.map(|(a, &b)| (b, a.to_vec())) .map(|(a, &b)| (b, a.to_vec()))
.collect::<FnvHashMap<ThreadHash, Vec<u8>>>(), .collect::<FnvHashMap<ThreadNodeHash, Vec<u8>>>(),
&envelopes, &envelopes,
); );
*/ */
@ -957,7 +953,7 @@ impl Threads {
pub fn group_inner_sort_by( pub fn group_inner_sort_by(
&self, &self,
vec: &mut [ThreadGroupHash], vec: &mut [ThreadHash],
sort: (SortField, SortOrder), sort: (SortField, SortOrder),
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
@ -1037,7 +1033,7 @@ impl Threads {
} }
pub fn node_inner_sort_by( pub fn node_inner_sort_by(
&self, &self,
vec: &mut [ThreadHash], vec: &mut [ThreadNodeHash],
sort: (SortField, SortOrder), sort: (SortField, SortOrder),
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
@ -1216,12 +1212,12 @@ impl Threads {
} }
} }
pub fn thread_to_mail(&self, i: ThreadHash) -> EnvelopeHash { pub fn thread_to_mail(&self, i: ThreadNodeHash) -> EnvelopeHash {
let thread = &self.thread_nodes[&i]; let thread = &self.thread_nodes[&i];
thread.message().unwrap() thread.message().unwrap()
} }
pub fn thread_nodes(&self) -> &FnvHashMap<ThreadHash, ThreadNode> { pub fn thread_nodes(&self) -> &FnvHashMap<ThreadNodeHash, ThreadNode> {
&self.thread_nodes &self.thread_nodes
} }
@ -1233,16 +1229,16 @@ impl Threads {
self.tree_index.borrow().len() self.tree_index.borrow().len()
} }
pub fn root_set(&self, idx: usize) -> ThreadHash { pub fn root_set(&self, idx: usize) -> ThreadNodeHash {
self.tree_index.borrow()[idx] self.tree_index.borrow()[idx]
} }
pub fn roots(&self) -> SmallVec<[ThreadGroupHash; 1024]> { pub fn roots(&self) -> SmallVec<[ThreadHash; 1024]> {
//FIXME: refactor filter //FIXME: refactor filter
self.groups self.groups
.iter() .iter()
.filter_map(|(h, g)| g.root().map(|_| *h)) .filter_map(|(h, g)| g.root().map(|_| *h))
.collect::<SmallVec<[ThreadGroupHash; 1024]>>() .collect::<SmallVec<[ThreadHash; 1024]>>()
} }
pub fn root_iter(&self) -> RootIterator { pub fn root_iter(&self) -> RootIterator {
@ -1254,10 +1250,10 @@ impl Threads {
} }
} }
impl Index<&ThreadHash> for Threads { impl Index<&ThreadNodeHash> for Threads {
type Output = ThreadNode; type Output = ThreadNode;
fn index(&self, index: &ThreadHash) -> &ThreadNode { fn index(&self, index: &ThreadNodeHash) -> &ThreadNode {
self.thread_nodes self.thread_nodes
.get(index) .get(index)
.expect("thread index out of bounds") .expect("thread index out of bounds")
@ -1266,14 +1262,14 @@ impl Index<&ThreadHash> for Threads {
/* /*
fn print_threadnodes( fn print_threadnodes(
node_hash: ThreadHash, node_hash: ThreadNodeHash,
nodes: &FnvHashMap<ThreadHash, ThreadNode>, nodes: &FnvHashMap<ThreadNodeHash, ThreadNode>,
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
fn help( fn help(
level: usize, level: usize,
node_hash: ThreadHash, node_hash: ThreadNodeHash,
nodes: &FnvHashMap<ThreadHash, ThreadNode>, nodes: &FnvHashMap<ThreadNodeHash, ThreadNode>,
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
eprint!("{}ThreadNode {}\n{}\tmessage: {}\n{}\tparent: {}\n{}\tthread_group: {}\n{}\tchildren (len: {}):\n", eprint!("{}ThreadNode {}\n{}\tmessage: {}\n{}\tparent: {}\n{}\tthread_group: {}\n{}\tchildren (len: {}):\n",
@ -1321,9 +1317,9 @@ struct Graph {
/* /*
fn save_graph( fn save_graph(
node_arr: &[ThreadHash], node_arr: &[ThreadNodeHash],
nodes: &FnvHashMap<ThreadHash, ThreadNode>, nodes: &FnvHashMap<ThreadNodeHash, ThreadNode>,
ids: &FnvHashMap<ThreadHash, Vec<u8>>, ids: &FnvHashMap<ThreadNodeHash, Vec<u8>>,
envelopes: &Envelopes, envelopes: &Envelopes,
) { ) {
let envelopes = envelopes.read().unwrap(); let envelopes = envelopes.read().unwrap();
@ -1331,7 +1327,7 @@ fn save_graph(
nodes: vec![], nodes: vec![],
links: vec![], links: vec![],
}; };
let mut stack: SmallVec<[(ThreadHash, String); 16]> = SmallVec::new(); let mut stack: SmallVec<[(ThreadNodeHash, String); 16]> = SmallVec::new();
for n in node_arr { for n in node_arr {
stack.extend( stack.extend(
nodes[n].children.iter().cloned().zip( nodes[n].children.iter().cloned().zip(

View File

@ -19,7 +19,7 @@
* along with meli. If not, see <http://www.gnu.org/licenses/>. * along with meli. If not, see <http://www.gnu.org/licenses/>.
*/ */
use super::{ThreadGroup, ThreadHash, ThreadNode}; use super::{ThreadNode, ThreadNodeHash};
use fnv::FnvHashMap; use fnv::FnvHashMap;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::Ref; use std::cell::Ref;
@ -42,12 +42,12 @@ use std::cell::Ref;
pub struct ThreadsIterator<'a> { pub struct ThreadsIterator<'a> {
pub(super) pos: usize, pub(super) pos: usize,
pub(super) stack: SmallVec<[usize; 16]>, pub(super) stack: SmallVec<[usize; 16]>,
pub(super) root_tree: Ref<'a, Vec<ThreadHash>>, pub(super) root_tree: Ref<'a, Vec<ThreadNodeHash>>,
pub(super) thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>, pub(super) thread_nodes: &'a FnvHashMap<ThreadNodeHash, ThreadNode>,
} }
impl<'a> Iterator for ThreadsIterator<'a> { impl<'a> Iterator for ThreadsIterator<'a> {
type Item = (usize, ThreadHash, bool); type Item = (usize, ThreadNodeHash, bool);
fn next(&mut self) -> Option<(usize, ThreadHash, bool)> { fn next(&mut self) -> Option<(usize, ThreadNodeHash, bool)> {
{ {
let mut tree = &(*self.root_tree); let mut tree = &(*self.root_tree);
for i in self.stack.iter() { for i in self.stack.iter() {
@ -101,12 +101,12 @@ pub struct ThreadIterator<'a> {
pub(super) init_pos: usize, pub(super) init_pos: usize,
pub(super) pos: usize, pub(super) pos: usize,
pub(super) stack: SmallVec<[usize; 16]>, pub(super) stack: SmallVec<[usize; 16]>,
pub(super) root_tree: Ref<'a, Vec<ThreadHash>>, pub(super) root_tree: Ref<'a, Vec<ThreadNodeHash>>,
pub(super) thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>, pub(super) thread_nodes: &'a FnvHashMap<ThreadNodeHash, ThreadNode>,
} }
impl<'a> Iterator for ThreadIterator<'a> { impl<'a> Iterator for ThreadIterator<'a> {
type Item = (usize, ThreadHash); type Item = (usize, ThreadNodeHash);
fn next(&mut self) -> Option<(usize, ThreadHash)> { fn next(&mut self) -> Option<(usize, ThreadNodeHash)> {
{ {
let mut tree = &(*self.root_tree); let mut tree = &(*self.root_tree);
for i in self.stack.iter() { for i in self.stack.iter() {
@ -141,13 +141,13 @@ impl<'a> Iterator for ThreadIterator<'a> {
pub struct RootIterator<'a> { pub struct RootIterator<'a> {
pub pos: usize, pub pos: usize,
pub root_tree: Ref<'a, Vec<ThreadHash>>, pub root_tree: Ref<'a, Vec<ThreadNodeHash>>,
pub thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>, pub thread_nodes: &'a FnvHashMap<ThreadNodeHash, ThreadNode>,
} }
impl<'a> Iterator for RootIterator<'a> { impl<'a> Iterator for RootIterator<'a> {
type Item = ThreadHash; type Item = ThreadNodeHash;
fn next(&mut self) -> Option<ThreadHash> { fn next(&mut self) -> Option<ThreadNodeHash> {
{ {
if self.pos == self.root_tree.len() { if self.pos == self.root_tree.len() {
return None; return None;
@ -167,15 +167,15 @@ impl<'a> Iterator for RootIterator<'a> {
} }
pub struct ThreadGroupIterator<'a> { pub struct ThreadGroupIterator<'a> {
pub(super) group: ThreadHash, pub(super) group: ThreadNodeHash,
pub(super) pos: usize, pub(super) pos: usize,
pub(super) stack: SmallVec<[usize; 16]>, pub(super) stack: SmallVec<[usize; 16]>,
pub(super) thread_nodes: &'a FnvHashMap<ThreadHash, ThreadNode>, pub(super) thread_nodes: &'a FnvHashMap<ThreadNodeHash, ThreadNode>,
} }
impl<'a> Iterator for ThreadGroupIterator<'a> { impl<'a> Iterator for ThreadGroupIterator<'a> {
type Item = (usize, ThreadHash); type Item = (usize, ThreadNodeHash);
fn next(&mut self) -> Option<(usize, ThreadHash)> { fn next(&mut self) -> Option<(usize, ThreadNodeHash)> {
{ {
let mut tree = &[self.group][..]; let mut tree = &[self.group][..];
for i in self.stack.iter() { for i in self.stack.iter() {

View File

@ -24,7 +24,7 @@
use super::*; use super::*;
use melib::backends::Folder; use melib::backends::Folder;
use melib::backends::FolderHash; use melib::backends::FolderHash;
use melib::thread::ThreadHash; use melib::thread::ThreadNodeHash;
pub mod listing; pub mod listing;
pub use crate::listing::*; pub use crate::listing::*;

View File

@ -53,7 +53,7 @@ pub trait MailListingTrait: ListingTrait {
fn perform_action( fn perform_action(
&mut self, &mut self,
context: &mut Context, context: &mut Context,
thread_hash: ThreadGroupHash, thread_hash: ThreadHash,
a: &ListingAction, a: &ListingAction,
) { ) {
let account = &mut context.accounts[self.coordinates().0]; let account = &mut context.accounts[self.coordinates().0];
@ -120,9 +120,9 @@ pub trait MailListingTrait: ListingTrait {
} }
} }
fn row_updates(&mut self) -> &mut SmallVec<[ThreadGroupHash; 8]>; fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]>;
fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadGroupHash; 8]>; fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]>;
fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadGroupHash>>) { fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadHash>>) {
unimplemented!() unimplemented!()
} }
} }

View File

@ -54,33 +54,33 @@ pub struct CompactListing {
length: usize, length: usize,
sort: (SortField, SortOrder), sort: (SortField, SortOrder),
subsort: (SortField, SortOrder), subsort: (SortField, SortOrder),
all_threads: fnv::FnvHashSet<ThreadGroupHash>, all_threads: fnv::FnvHashSet<ThreadHash>,
order: FnvHashMap<ThreadGroupHash, usize>, order: FnvHashMap<ThreadHash, usize>,
/// Cache current view. /// Cache current view.
data_columns: DataColumns, data_columns: DataColumns,
filter_term: String, filter_term: String,
filtered_selection: Vec<ThreadGroupHash>, filtered_selection: Vec<ThreadHash>,
filtered_order: FnvHashMap<ThreadGroupHash, usize>, filtered_order: FnvHashMap<ThreadHash, usize>,
selection: FnvHashMap<ThreadGroupHash, bool>, selection: FnvHashMap<ThreadHash, bool>,
/// If we must redraw on next redraw event /// If we must redraw on next redraw event
dirty: bool, dirty: bool,
force_draw: bool, force_draw: bool,
/// If `self.view` exists or not. /// If `self.view` exists or not.
unfocused: bool, unfocused: bool,
view: ThreadView, view: ThreadView,
row_updates: SmallVec<[ThreadGroupHash; 8]>, row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option<PageMovement>, movement: Option<PageMovement>,
id: ComponentId, id: ComponentId,
} }
impl MailListingTrait for CompactListing { impl MailListingTrait for CompactListing {
fn row_updates(&mut self) -> &mut SmallVec<[ThreadGroupHash; 8]> { fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates &mut self.row_updates
} }
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadGroupHash; 8]> { fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); 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 i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
let cursor_iter; let cursor_iter;
@ -469,7 +469,7 @@ impl ListingTrait for CompactListing {
self.redraw_list( self.redraw_list(
context, context,
Box::new(self.filtered_selection.clone().into_iter()) Box::new(self.filtered_selection.clone().into_iter())
as Box<dyn Iterator<Item = ThreadGroupHash>>, as Box<dyn Iterator<Item = ThreadHash>>,
); );
} }
Err(e) => { Err(e) => {
@ -547,7 +547,7 @@ impl CompactListing {
e: &Envelope, e: &Envelope,
context: &Context, context: &Context,
threads: &Threads, threads: &Threads,
hash: ThreadGroupHash, hash: ThreadHash,
) -> EntryStrings { ) -> EntryStrings {
let thread = &threads.groups[&hash]; let thread = &threads.groups[&hash];
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1] let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
@ -675,7 +675,7 @@ impl CompactListing {
self.redraw_list( self.redraw_list(
context, context,
Box::new(roots.into_iter()) as Box<dyn Iterator<Item = ThreadGroupHash>>, Box::new(roots.into_iter()) as Box<dyn Iterator<Item = ThreadHash>>,
); );
if old_cursor_pos == self.new_cursor_pos { if old_cursor_pos == self.new_cursor_pos {
@ -687,7 +687,7 @@ impl CompactListing {
} }
} }
fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadGroupHash>>) { fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadHash>>) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let mailbox = &account[self.cursor_pos.1].unwrap(); let mailbox = &account[self.cursor_pos.1].unwrap();
@ -961,7 +961,7 @@ impl CompactListing {
} }
} }
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadGroupHash { fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash {
//let account = &context.accounts[self.cursor_pos.0]; //let account = &context.accounts[self.cursor_pos.0];
//let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); //let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
if self.filter_term.is_empty() { if self.filter_term.is_empty() {
@ -979,7 +979,7 @@ impl CompactListing {
} }
} }
fn update_line(&mut self, context: &Context, thread_hash: ThreadGroupHash) { fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
let threads = &account.collection.threads[&folder_hash]; let threads = &account.collection.threads[&folder_hash];
@ -1316,7 +1316,7 @@ impl Component for CompactListing {
if !threads.thread_nodes.contains_key(&new_env_thread_hash) { if !threads.thread_nodes.contains_key(&new_env_thread_hash) {
return false; return false;
} }
let thread: ThreadGroupHash = let thread: ThreadHash =
threads.find_group(threads.thread_nodes()[&new_env_thread_hash].group); threads.find_group(threads.thread_nodes()[&new_env_thread_hash].group);
if self.order.contains_key(&thread) { if self.order.contains_key(&thread) {
self.row_updates.push(thread); self.row_updates.push(thread);

View File

@ -85,33 +85,33 @@ pub struct ConversationsListing {
length: usize, length: usize,
sort: (SortField, SortOrder), sort: (SortField, SortOrder),
subsort: (SortField, SortOrder), subsort: (SortField, SortOrder),
all_threads: fnv::FnvHashSet<ThreadGroupHash>, all_threads: fnv::FnvHashSet<ThreadHash>,
order: FnvHashMap<ThreadGroupHash, usize>, order: FnvHashMap<ThreadHash, usize>,
/// Cache current view. /// Cache current view.
content: CellBuffer, content: CellBuffer,
filter_term: String, filter_term: String,
filtered_selection: Vec<ThreadGroupHash>, filtered_selection: Vec<ThreadHash>,
filtered_order: FnvHashMap<ThreadGroupHash, usize>, filtered_order: FnvHashMap<ThreadHash, usize>,
selection: FnvHashMap<ThreadGroupHash, bool>, selection: FnvHashMap<ThreadHash, bool>,
/// If we must redraw on next redraw event /// If we must redraw on next redraw event
dirty: bool, dirty: bool,
force_draw: bool, force_draw: bool,
/// If `self.view` exists or not. /// If `self.view` exists or not.
unfocused: bool, unfocused: bool,
view: ThreadView, view: ThreadView,
row_updates: SmallVec<[ThreadGroupHash; 8]>, row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option<PageMovement>, movement: Option<PageMovement>,
id: ComponentId, id: ComponentId,
} }
impl MailListingTrait for ConversationsListing { impl MailListingTrait for ConversationsListing {
fn row_updates(&mut self) -> &mut SmallVec<[ThreadGroupHash; 8]> { fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates &mut self.row_updates
} }
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadGroupHash; 8]> { fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); 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 i = [self.get_thread_under_cursor(self.cursor_pos.2, context)];
let cursor_iter; let cursor_iter;
@ -441,7 +441,7 @@ impl ListingTrait for ConversationsListing {
self.redraw_list( self.redraw_list(
context, context,
Box::new(self.filtered_selection.clone().into_iter()) Box::new(self.filtered_selection.clone().into_iter())
as Box<dyn Iterator<Item = ThreadGroupHash>>, as Box<dyn Iterator<Item = ThreadHash>>,
); );
} }
Err(e) => { Err(e) => {
@ -520,7 +520,7 @@ impl ConversationsListing {
context: &Context, context: &Context,
from: &Vec<Address>, from: &Vec<Address>,
threads: &Threads, threads: &Threads,
hash: ThreadGroupHash, hash: ThreadHash,
) -> EntryStrings { ) -> EntryStrings {
let thread = &threads.groups[&hash]; let thread = &threads.groups[&hash];
let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1] let folder_hash = &context.accounts[self.cursor_pos.0][self.cursor_pos.1]
@ -648,7 +648,7 @@ impl ConversationsListing {
self.redraw_list( self.redraw_list(
context, context,
Box::new(roots.into_iter()) as Box<dyn Iterator<Item = ThreadGroupHash>>, Box::new(roots.into_iter()) as Box<dyn Iterator<Item = ThreadHash>>,
); );
if old_cursor_pos == self.new_cursor_pos { if old_cursor_pos == self.new_cursor_pos {
@ -660,7 +660,7 @@ impl ConversationsListing {
} }
} }
fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadGroupHash>>) { fn redraw_list(&mut self, context: &Context, items: Box<dyn Iterator<Item = ThreadHash>>) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let mailbox = &account[self.cursor_pos.1].unwrap(); let mailbox = &account[self.cursor_pos.1].unwrap();
@ -895,7 +895,7 @@ impl ConversationsListing {
} }
} }
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadGroupHash { fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash {
//let account = &context.accounts[self.cursor_pos.0]; //let account = &context.accounts[self.cursor_pos.0];
//let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); //let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
//let threads = &account.collection.threads[&folder_hash]; //let threads = &account.collection.threads[&folder_hash];
@ -915,7 +915,7 @@ impl ConversationsListing {
} }
} }
fn update_line(&mut self, context: &Context, thread_hash: ThreadGroupHash) { fn update_line(&mut self, context: &Context, thread_hash: ThreadHash) {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash(); let folder_hash = account[self.cursor_pos.1].unwrap().folder.hash();
let threads = &account.collection.threads[&folder_hash]; let threads = &account.collection.threads[&folder_hash];
@ -1209,7 +1209,7 @@ impl Component for ConversationsListing {
if !threads.thread_nodes.contains_key(&new_env_thread_hash) { if !threads.thread_nodes.contains_key(&new_env_thread_hash) {
return false; return false;
} }
let thread: ThreadGroupHash = let thread: ThreadHash =
threads.find_group(threads.thread_nodes()[&new_env_thread_hash].group); threads.find_group(threads.thread_nodes()[&new_env_thread_hash].group);
if self.order.contains_key(&thread) { if self.order.contains_key(&thread) {
self.row_updates.push(thread); self.row_updates.push(thread);

View File

@ -62,7 +62,7 @@ pub struct PlainListing {
filtered_selection: Vec<EnvelopeHash>, filtered_selection: Vec<EnvelopeHash>,
filtered_order: FnvHashMap<EnvelopeHash, usize>, filtered_order: FnvHashMap<EnvelopeHash, usize>,
selection: FnvHashMap<EnvelopeHash, bool>, selection: FnvHashMap<EnvelopeHash, bool>,
thread_hashes: FnvHashMap<EnvelopeHash, ThreadHash>, thread_hashes: FnvHashMap<EnvelopeHash, ThreadNodeHash>,
local_collection: Vec<EnvelopeHash>, local_collection: Vec<EnvelopeHash>,
/// If we must redraw on next redraw event /// If we must redraw on next redraw event
dirty: bool, dirty: bool,
@ -71,18 +71,18 @@ pub struct PlainListing {
unfocused: bool, unfocused: bool,
view: MailView, view: MailView,
row_updates: SmallVec<[EnvelopeHash; 8]>, row_updates: SmallVec<[EnvelopeHash; 8]>,
_row_updates: SmallVec<[ThreadGroupHash; 8]>, _row_updates: SmallVec<[ThreadHash; 8]>,
movement: Option<PageMovement>, movement: Option<PageMovement>,
id: ComponentId, id: ComponentId,
} }
impl MailListingTrait for PlainListing { impl MailListingTrait for PlainListing {
fn row_updates(&mut self) -> &mut SmallVec<[ThreadGroupHash; 8]> { fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self._row_updates &mut self._row_updates
} }
fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadGroupHash; 8]> { fn get_focused_items(&self, context: &Context) -> SmallVec<[ThreadHash; 8]> {
return SmallVec::new(); return SmallVec::new();
/* /*
let is_selection_empty = self.selection.values().cloned().any(std::convert::identity); let is_selection_empty = self.selection.values().cloned().any(std::convert::identity);
@ -892,7 +892,7 @@ impl PlainListing {
} }
} }
fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadHash { fn get_thread_under_cursor(&self, cursor: usize, context: &Context) -> ThreadNodeHash {
let account = &context.accounts[self.cursor_pos.0]; let account = &context.accounts[self.cursor_pos.0];
let env_hash = self.get_env_under_cursor(cursor, context); let env_hash = self.get_env_under_cursor(cursor, context);
account.collection.get_env(env_hash).thread() account.collection.get_env(env_hash).thread()

View File

@ -37,7 +37,7 @@ pub struct ThreadListing {
/// Cache current view. /// Cache current view.
content: CellBuffer, content: CellBuffer,
row_updates: SmallVec<[ThreadGroupHash; 8]>, row_updates: SmallVec<[ThreadHash; 8]>,
locations: Vec<EnvelopeHash>, locations: Vec<EnvelopeHash>,
/// If we must redraw on next redraw event /// If we must redraw on next redraw event
dirty: bool, dirty: bool,
@ -50,11 +50,11 @@ pub struct ThreadListing {
} }
impl MailListingTrait for ThreadListing { impl MailListingTrait for ThreadListing {
fn row_updates(&mut self) -> &mut SmallVec<[ThreadGroupHash; 8]> { fn row_updates(&mut self) -> &mut SmallVec<[ThreadHash; 8]> {
&mut self.row_updates &mut self.row_updates
} }
fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadGroupHash; 8]> { fn get_focused_items(&self, _context: &Context) -> SmallVec<[ThreadHash; 8]> {
SmallVec::new() SmallVec::new()
} }
} }
@ -319,7 +319,7 @@ impl ThreadListing {
let mut thread_idx = 0; // needed for alternate thread colors let mut thread_idx = 0; // needed for alternate thread colors
/* Draw threaded view. */ /* Draw threaded view. */
threads.sort_by(self.sort, self.subsort, &account.collection.envelopes); threads.sort_by(self.sort, self.subsort, &account.collection.envelopes);
let thread_nodes: &FnvHashMap<ThreadHash, ThreadNode> = &threads.thread_nodes(); let thread_nodes: &FnvHashMap<ThreadNodeHash, ThreadNode> = &threads.thread_nodes();
let mut iter = threads.threads_iter().peekable(); let mut iter = threads.threads_iter().peekable();
/* This is just a desugared for loop so that we can use .peek() */ /* This is just a desugared for loop so that we can use .peek() */
let mut idx = 0; let mut idx = 0;
@ -429,7 +429,7 @@ impl ThreadListing {
envelope: &Envelope, envelope: &Envelope,
idx: usize, idx: usize,
indent: usize, indent: usize,
node_idx: ThreadHash, node_idx: ThreadNodeHash,
threads: &Threads, threads: &Threads,
indentations: &[bool], indentations: &[bool],
has_sibling: bool, has_sibling: bool,

View File

@ -34,7 +34,7 @@ const INDENTATION_COLORS: &'static [u8] = &[
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
struct ThreadEntry { struct ThreadEntry {
index: (usize, ThreadHash, usize), index: (usize, ThreadNodeHash, usize),
/// (indentation, thread_node index, line number in listing) /// (indentation, thread_node index, line number in listing)
indentation: usize, indentation: usize,
msg_hash: EnvelopeHash, msg_hash: EnvelopeHash,
@ -52,7 +52,7 @@ pub struct ThreadView {
new_expanded_pos: usize, new_expanded_pos: usize,
reversed: bool, reversed: bool,
coordinates: (usize, usize, usize), coordinates: (usize, usize, usize),
thread_group: ThreadGroupHash, thread_group: ThreadHash,
mailview: MailView, mailview: MailView,
show_mailview: bool, show_mailview: bool,
show_thread: bool, show_thread: bool,
@ -76,8 +76,8 @@ impl ThreadView {
*/ */
pub fn new( pub fn new(
coordinates: (usize, usize, usize), coordinates: (usize, usize, usize),
thread_group: ThreadGroupHash, thread_group: ThreadHash,
expanded_hash: Option<ThreadHash>, expanded_hash: Option<ThreadNodeHash>,
context: &Context, context: &Context,
) -> Self { ) -> Self {
let mut view = ThreadView { let mut view = ThreadView {
@ -160,7 +160,7 @@ impl ThreadView {
} }
self.set_dirty(true); self.set_dirty(true);
} }
fn initiate(&mut self, expanded_hash: Option<ThreadHash>, context: &Context) { fn initiate(&mut self, expanded_hash: Option<ThreadNodeHash>, context: &Context) {
/* stack to push thread messages in order in order to pop and print them later */ /* stack to push thread messages in order in order to pop and print them later */
let account = &context.accounts[self.coordinates.0]; let account = &context.accounts[self.coordinates.0];
let mailbox = &account[self.coordinates.1].unwrap(); let mailbox = &account[self.coordinates.1].unwrap();
@ -384,7 +384,7 @@ impl ThreadView {
fn make_entry( fn make_entry(
&mut self, &mut self,
i: (usize, ThreadHash, usize), i: (usize, ThreadNodeHash, usize),
msg_hash: EnvelopeHash, msg_hash: EnvelopeHash,
seen: bool, seen: bool,
) -> ThreadEntry { ) -> ThreadEntry {

View File

@ -32,7 +32,7 @@ use melib::backends::{
}; };
use melib::error::{MeliError, Result}; use melib::error::{MeliError, Result};
use melib::mailbox::*; use melib::mailbox::*;
use melib::thread::{SortField, SortOrder, ThreadHash, ThreadNode, Threads}; use melib::thread::{SortField, SortOrder, ThreadNode, ThreadNodeHash, Threads};
use melib::AddressBook; use melib::AddressBook;
use smallvec::SmallVec; use smallvec::SmallVec;
use text_processing::GlobMatch; use text_processing::GlobMatch;
@ -957,7 +957,7 @@ impl Account {
} }
} }
pub fn thread(&self, h: ThreadHash, f: FolderHash) -> &ThreadNode { pub fn thread(&self, h: ThreadNodeHash, f: FolderHash) -> &ThreadNode {
&self.collection.threads[&f].thread_nodes()[&h] &self.collection.threads[&f].thread_nodes()[&h]
} }