summaryrefslogtreecommitdiffstats
path: root/melib
diff options
context:
space:
mode:
authorManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-20 22:36:57 +0300
committerManos Pitsidianakis <el13635@mail.ntua.gr>2020-10-20 22:41:44 +0300
commit662706607b9d235f06567eb9cc2ccd26df85a725 (patch)
treed5cab83bbcec3740b96c4b02e58a4b70bfd3215f /melib
parentb904f91f45a9ae3a85b8328c28fbf61d3098124f (diff)
melib: remove memmap dependency
It's unmaintained, and the IO performance gains are negligible
Diffstat (limited to 'melib')
-rw-r--r--melib/Cargo.toml5
-rw-r--r--melib/src/backends/maildir.rs17
-rw-r--r--melib/src/backends/maildir/backend.rs38
-rw-r--r--melib/src/backends/maildir/stream.rs12
-rw-r--r--melib/src/backends/mbox.rs54
5 files changed, 72 insertions, 54 deletions
diff --git a/melib/Cargo.toml b/melib/Cargo.toml
index f16b63fa..f21232e7 100644
--- a/melib/Cargo.toml
+++ b/melib/Cargo.toml
@@ -23,7 +23,6 @@ bitflags = "1.0"
crossbeam = "0.7.2"
data-encoding = "2.1.1"
encoding = "0.2.33"
-memmap = { version = "0.5.2", optional = true }
nom = { version = "5.1.1" }
indexmap = { version = "^1.5", features = ["serde-1", ] }
@@ -61,8 +60,8 @@ http = ["isahc"]
http-static = ["isahc", "isahc/static-curl"]
imap_backend = ["tls"]
jmap_backend = ["http", "serde_json"]
-maildir_backend = ["notify", "memmap"]
-mbox_backend = ["notify", "memmap"]
+maildir_backend = ["notify"]
+mbox_backend = ["notify"]
notmuch_backend = []
smtp = ["tls", "base64"]
sqlite3 = ["rusqlite", ]
diff --git a/melib/src/backends/maildir.rs b/melib/src/backends/maildir.rs
index 70494ff5..86b4cd4f 100644
--- a/melib/src/backends/maildir.rs
+++ b/melib/src/backends/maildir.rs
@@ -31,11 +31,10 @@ use crate::email::Flag;
use crate::error::{MeliError, Result};
use crate::shellexpand::ShellExpandTrait;
pub use futures::stream::Stream;
-
-use memmap::{Mmap, Protection};
use std::collections::hash_map::DefaultHasher;
use std::fs;
use std::hash::{Hash, Hasher};
+use std::io::{BufReader, Read};
use std::path::{Path, PathBuf};
use std::sync::{Arc, Mutex};
@@ -45,7 +44,7 @@ pub struct MaildirOp {
hash_index: HashIndexes,
mailbox_hash: MailboxHash,
hash: EnvelopeHash,
- slice: Option<Mmap>,
+ slice: Option<Vec<u8>>,
}
impl Clone for MaildirOp {
@@ -92,10 +91,16 @@ impl MaildirOp {
impl<'a> BackendOp for MaildirOp {
fn as_bytes(&mut self) -> ResultFuture<Vec<u8>> {
if self.slice.is_none() {
- self.slice = Some(Mmap::open_path(self.path(), Protection::Read)?);
+ let file = std::fs::OpenOptions::new()
+ .read(true)
+ .write(false)
+ .open(&self.path())?;
+ let mut buf_reader = BufReader::new(file);
+ let mut contents = Vec::new();
+ buf_reader.read_to_end(&mut contents)?;
+ self.slice = Some(contents);
}
- /* Unwrap is safe since we use ? above. */
- let ret = Ok((unsafe { self.slice.as_ref().unwrap().as_slice() }).to_vec());
+ let ret = Ok(self.slice.as_ref().unwrap().as_slice().to_vec());
Ok(Box::pin(async move { ret }))
}
diff --git a/melib/src/backends/maildir/backend.rs b/melib/src/backends/maildir/backend.rs
index 422b1d75..c5b5d96f 100644
--- a/melib/src/backends/maildir/backend.rs
+++ b/melib/src/backends/maildir/backend.rs
@@ -27,7 +27,6 @@ use crate::error::{ErrorKind, MeliError, Result};
use crate::shellexpand::ShellExpandTrait;
use futures::prelude::Stream;
-use memmap::{Mmap, Protection};
extern crate notify;
use self::notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use std::time::Duration;
@@ -241,6 +240,7 @@ impl MailBackend for MaildirType {
Ok(Box::pin(async move {
let thunk = move |sender: &BackendEventConsumer| {
debug!("refreshing");
+ let mut buf = Vec::with_capacity(4096);
let mut path = path.clone();
path.push("new");
for d in path.read_dir()? {
@@ -278,10 +278,10 @@ impl MailBackend for MaildirType {
}
(*map).insert(hash, PathBuf::from(&file).into());
}
- if let Ok(mut env) = Envelope::from_bytes(
- unsafe { &Mmap::open_path(&file, Protection::Read)?.as_slice() },
- Some(file.flags()),
- ) {
+ let mut reader = io::BufReader::new(fs::File::open(&file)?);
+ buf.clear();
+ reader.read_to_end(&mut buf)?;
+ if let Ok(mut env) = Envelope::from_bytes(buf.as_slice(), Some(file.flags())) {
env.set_hash(hash);
mailbox_index
.lock()
@@ -371,6 +371,7 @@ impl MailBackend for MaildirType {
Ok(Box::pin(async move {
// Move `watcher` in the closure's scope so that it doesn't get dropped.
let _watcher = watcher;
+ let mut buf = Vec::with_capacity(4096);
loop {
match rx.recv() {
/*
@@ -410,6 +411,7 @@ impl MailBackend for MaildirType {
pathbuf.as_path(),
&cache_dir,
file_name,
+ &mut buf,
) {
mailbox_index
.lock()
@@ -464,6 +466,7 @@ impl MailBackend for MaildirType {
pathbuf.as_path(),
&cache_dir,
file_name,
+ &mut buf,
) {
mailbox_index
.lock()
@@ -482,14 +485,14 @@ impl MailBackend for MaildirType {
}
};
let new_hash: EnvelopeHash = get_file_hash(pathbuf.as_path());
+ let mut reader = io::BufReader::new(fs::File::open(&pathbuf)?);
+ buf.clear();
+ reader.read_to_end(&mut buf)?;
if index_lock.get_mut(&new_hash).is_none() {
debug!("write notice");
- if let Ok(mut env) = Envelope::from_bytes(
- unsafe {
- &Mmap::open_path(&pathbuf, Protection::Read)?.as_slice()
- },
- Some(pathbuf.flags()),
- ) {
+ if let Ok(mut env) =
+ Envelope::from_bytes(buf.as_slice(), Some(pathbuf.flags()))
+ {
env.set_hash(new_hash);
debug!("{}\t{:?}", new_hash, &pathbuf);
debug!(
@@ -611,6 +614,7 @@ impl MailBackend for MaildirType {
dest.as_path(),
&cache_dir,
file_name,
+ &mut buf,
) {
mailbox_index
.lock()
@@ -701,6 +705,7 @@ impl MailBackend for MaildirType {
dest.as_path(),
&cache_dir,
file_name,
+ &mut buf,
) {
mailbox_index
.lock()
@@ -747,6 +752,7 @@ impl MailBackend for MaildirType {
dest.as_path(),
&cache_dir,
file_name,
+ &mut buf,
) {
mailbox_index
.lock()
@@ -1330,6 +1336,7 @@ fn add_path_to_index(
path: &Path,
cache_dir: &xdg::BaseDirectories,
file_name: PathBuf,
+ buf: &mut Vec<u8>,
) -> Result<Envelope> {
debug!("add_path_to_index path {:?} filename{:?}", path, file_name);
let env_hash = get_file_hash(path);
@@ -1344,11 +1351,10 @@ fn add_path_to_index(
map.len()
);
}
- //Mmap::open_path(self.path(), Protection::Read)?
- let mut env = Envelope::from_bytes(
- unsafe { &Mmap::open_path(path, Protection::Read)?.as_slice() },
- Some(path.flags()),
- )?;
+ let mut reader = io::BufReader::new(fs::File::open(&path)?);
+ buf.clear();
+ reader.read_to_end(buf)?;
+ let mut env = Envelope::from_bytes(buf.as_slice(), Some(path.flags()))?;
env.set_hash(env_hash);
debug!(
"add_path_to_index gen {}\t{}",
diff --git a/melib/src/backends/maildir/stream.rs b/melib/src/backends/maildir/stream.rs
index 8fd59fc9..be750f72 100644
--- a/melib/src/backends/maildir/stream.rs
+++ b/melib/src/backends/maildir/stream.rs
@@ -25,8 +25,7 @@ use core::future::Future;
use core::pin::Pin;
use futures::stream::{FuturesUnordered, StreamExt};
use futures::task::{Context, Poll};
-use memmap::{Mmap, Protection};
-use std::io::{self};
+use std::io::{self, Read};
use std::os::unix::fs::PermissionsExt;
use std::path::PathBuf;
use std::result;
@@ -113,6 +112,7 @@ impl MaildirStream {
let len = chunk.len();
let size = if len <= 100 { 100 } else { (len / 100) * 100 };
let mut local_r: Vec<Envelope> = Vec::with_capacity(chunk.len());
+ let mut buf = Vec::with_capacity(4096);
for c in chunk.chunks(size) {
let map = map.clone();
for file in c {
@@ -146,10 +146,10 @@ impl MaildirStream {
let map = map.entry(mailbox_hash).or_default();
(*map).insert(env_hash, PathBuf::from(file).into());
}
- match Envelope::from_bytes(
- unsafe { &Mmap::open_path(&file, Protection::Read)?.as_slice() },
- Some(file.flags()),
- ) {
+ let mut reader = io::BufReader::new(fs::File::open(&file)?);
+ buf.clear();
+ reader.read_to_end(&mut buf)?;
+ match Envelope::from_bytes(buf.as_slice(), Some(file.flags())) {
Ok(mut env) => {
env.set_hash(env_hash);
mailbox_index.lock().unwrap().insert(env_hash, mailbox_hash);
diff --git a/melib/src/backends/mbox.rs b/melib/src/backends/mbox.rs
index a00af89a..07a5dda6 100644
--- a/melib/src/backends/mbox.rs
+++ b/melib/src/backends/mbox.rs
@@ -30,7 +30,6 @@ use crate::email::*;
use crate::error::{MeliError, Result};
use crate::get_path_hash;
use crate::shellexpand::ShellExpandTrait;
-use memmap::{Mmap, Protection};
use nom::bytes::complete::tag;
use nom::character::complete::digit1;
use nom::combinator::map_res;
@@ -41,8 +40,7 @@ use self::notify::{watcher, DebouncedEvent, RecursiveMode, Watcher};
use std::collections::hash_map::{DefaultHasher, HashMap};
use std::fs::File;
use std::hash::Hasher;
-use std::io::BufReader;
-use std::io::Read;
+use std::io::{BufReader, Read};
use std::os::unix::io::AsRawFd;
use std::path::{Path, PathBuf};
use std::str::FromStr;
@@ -164,7 +162,7 @@ pub struct MboxOp {
path: PathBuf,
offset: Offset,
length: Length,
- slice: Option<Mmap>,
+ slice: std::cell::RefCell<Option<Vec<u8>>>,
}
impl MboxOp {
@@ -172,7 +170,7 @@ impl MboxOp {
MboxOp {
hash,
path: path.to_path_buf(),
- slice: None,
+ slice: std::cell::RefCell::new(None),
offset,
length,
}
@@ -181,28 +179,38 @@ impl MboxOp {
impl BackendOp for MboxOp {
fn as_bytes(&mut self) -> ResultFuture<Vec<u8>> {
- if self.slice.is_none() {
- self.slice = Some(Mmap::open_path(&self.path, Protection::Read)?);
+ if self.slice.get_mut().is_none() {
+ let file = std::fs::OpenOptions::new()
+ .read(true)
+ .write(false)
+ .open(&self.path)?;
+ get_rw_lock_blocking(&file);
+ let mut buf_reader = BufReader::new(file);
+ let mut contents = Vec::new();
+ buf_reader.read_to_end(&mut contents)?;
+ *self.slice.get_mut() = Some(contents);
}
- /* Unwrap is safe since we use ? above. */
- let ret = Ok((unsafe {
- &self.slice.as_ref().unwrap().as_slice()[self.offset..self.offset + self.length]
- })
- .to_vec());
+ let ret = Ok(self.slice.get_mut().as_ref().unwrap().as_slice()
+ [self.offset..self.offset + self.length]
+ .to_vec());
Ok(Box::pin(async move { ret }))
}
fn fetch_flags(&self) -> ResultFuture<Flag> {
let mut flags = Flag::empty();
- let file = std::fs::OpenOptions::new()
- .read(true)
- .write(true)
- .open(&self.path)?;
- get_rw_lock_blocking(&file);
- let mut buf_reader = BufReader::new(file);
- let mut contents = Vec::new();
- buf_reader.read_to_end(&mut contents)?;
- let (_, headers) = parser::headers::headers_raw(contents.as_slice())?;
+ if self.slice.borrow().is_none() {
+ let file = std::fs::OpenOptions::new()
+ .read(true)
+ .write(false)
+ .open(&self.path)?;
+ get_rw_lock_blocking(&file);
+ let mut buf_reader = BufReader::new(file);
+ let mut contents = Vec::new();
+ buf_reader.read_to_end(&mut contents)?;
+ *self.slice.borrow_mut() = Some(contents);
+ }
+ let slice_ref = self.slice.borrow();
+ let (_, headers) = parser::headers::headers_raw(slice_ref.as_ref().unwrap().as_slice())?;
if let Some(start) = headers.find(b"Status:") {
if let Some(end) = headers[start..].find(b"\n") {
let start = start + b"Status:".len();
@@ -780,7 +788,7 @@ impl MailBackend for MboxType {
let mailbox_path = mailboxes.lock().unwrap()[&mailbox_hash].fs_path.clone();
let file = std::fs::OpenOptions::new()
.read(true)
- .write(true)
+ .write(false)
.open(&mailbox_path)?;
get_rw_lock_blocking(&file);
let mut buf_reader = BufReader::new(file);
@@ -852,7 +860,7 @@ impl MailBackend for MboxType {
let mailbox_hash = get_path_hash!(&pathbuf);
let file = match std::fs::OpenOptions::new()
.read(true)
- .write(true)
+ .write(false)
.open(&pathbuf)
{
Ok(f) => f,