Added memmap version.
This commit is contained in:
@@ -7,5 +7,6 @@ edition = "2018"
|
|||||||
[dependencies]
|
[dependencies]
|
||||||
bzip2 = "0.4"
|
bzip2 = "0.4"
|
||||||
flate2 = "1.0"
|
flate2 = "1.0"
|
||||||
|
memmap = "0.7"
|
||||||
mime = "0.3"
|
mime = "0.3"
|
||||||
mime_guess = "2.0"
|
mime_guess = "2.0"
|
||||||
|
|||||||
73
src/lib.rs
73
src/lib.rs
@@ -150,3 +150,76 @@ pub mod bufread {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub mod memmap {
|
||||||
|
use std::fs::File;
|
||||||
|
use std::io::{Cursor, Read, Seek, SeekFrom};
|
||||||
|
use std::path::Path;
|
||||||
|
|
||||||
|
use bzip2::read::BzDecoder;
|
||||||
|
use flate2::read::GzDecoder;
|
||||||
|
use memmap::{Mmap, MmapOptions};
|
||||||
|
|
||||||
|
pub enum MmapDecoder {
|
||||||
|
Raw(Cursor<Mmap>),
|
||||||
|
Gz(GzDecoder<Cursor<Mmap>>),
|
||||||
|
Bz(BzDecoder<Cursor<Mmap>>),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl MmapDecoder {
|
||||||
|
pub fn open<P>(path: P) -> Result<MmapDecoder, std::io::Error>
|
||||||
|
where
|
||||||
|
P: AsRef<Path>,
|
||||||
|
{
|
||||||
|
let file = File::open(&path)?;
|
||||||
|
let mmap = unsafe { MmapOptions::new().map(&file)? };
|
||||||
|
let cursor = Cursor::new(mmap);
|
||||||
|
|
||||||
|
Ok(match mime_guess::from_path(path).first_raw() {
|
||||||
|
Some("application/x-gzip") => MmapDecoder::Gz(GzDecoder::new(cursor)),
|
||||||
|
Some("application/x-bzip2") => MmapDecoder::Bz(BzDecoder::new(cursor)),
|
||||||
|
_ => MmapDecoder::Raw(cursor),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn stream_len(&mut self) -> std::io::Result<u64> {
|
||||||
|
let file = match self {
|
||||||
|
MmapDecoder::Raw(file) => file,
|
||||||
|
MmapDecoder::Gz(file) => file.get_mut(),
|
||||||
|
MmapDecoder::Bz(file) => file.get_mut(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let old_pos = file.seek(SeekFrom::Current(0))?;
|
||||||
|
let len = file.seek(SeekFrom::End(0))?;
|
||||||
|
|
||||||
|
if old_pos != len {
|
||||||
|
file.seek(SeekFrom::Start(old_pos))?;
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(len)
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn stream_position(&mut self) -> std::io::Result<u64> {
|
||||||
|
let file = match self {
|
||||||
|
MmapDecoder::Raw(file) => file,
|
||||||
|
MmapDecoder::Gz(file) => file.get_mut(),
|
||||||
|
MmapDecoder::Bz(file) => file.get_mut(),
|
||||||
|
};
|
||||||
|
|
||||||
|
file.seek(SeekFrom::Current(0))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Read for MmapDecoder {
|
||||||
|
#[inline]
|
||||||
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
|
match self {
|
||||||
|
MmapDecoder::Raw(file) => file.read(buf),
|
||||||
|
MmapDecoder::Gz(file) => file.read(buf),
|
||||||
|
MmapDecoder::Bz(file) => file.read(buf),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user