Skip to content

Instantly share code, notes, and snippets.

@SethDusek
Created July 17, 2017 18:05
Show Gist options
  • Save SethDusek/4e18ab91c9999e8f4ab3dc38d44eb856 to your computer and use it in GitHub Desktop.
Save SethDusek/4e18ab91c9999e8f4ab3dc38d44eb856 to your computer and use it in GitHub Desktop.
use std::os::unix::io::AsRawFd;
use std::ptr::null_mut;
use std::io::prelude::*;
use std::io::Error;
mod raw {
pub use libc::{c_int, splice};
const __NR_COPY_FILE_RANGE: ::libc::c_long = 326;
#[inline]
pub unsafe fn copy_file_range(fd_in: c_int, off_in: *mut ::libc::loff_t, fd_out: c_int, off_out: *mut ::libc::loff_t, len: usize, flags: u32) -> i64 {
::libc::syscall(__NR_COPY_FILE_RANGE, fd_in, off_in, fd_out, off_out, len, flags)
}
}
pub fn splice<T: AsRawFd + Read, Y: AsRawFd + Write>(src: &mut T, dest: &mut Y, bytes: usize) -> ::std::io::Result<usize> {
let res = unsafe { raw::splice(src.as_raw_fd(), null_mut(), dest.as_raw_fd(), null_mut(), bytes, 0) };
if res < 0 {
Err(::std::io::Error::last_os_error())
}
else { Ok(res as usize) }
}
pub fn copy(src: &mut ::std::fs::File, dest: &mut ::std::fs::File) -> ::std::io::Result<u64> {
let len = src.metadata()?.len() as usize;
/*loop {
let res = unsafe { raw::copy_file_range(src.as_raw_fd(), null_mut(), dest.as_raw_fd(), null_mut(), 1024, 0) };
if res < 0 {
return Err(Error::last_os_error());
}
else if res == 0 {
break;
}
else {
written+=res as u64;
}
}*/
let res = unsafe { raw::copy_file_range(src.as_raw_fd(), null_mut(), dest.as_raw_fd(), null_mut(), len, 0) };
if res < 0 { Err(Error::last_os_error()) } else { Ok(res as u64) }
}
#![feature(test)]
extern crate test;
extern crate zerocopy;
use zerocopy::zc::ZeroCopy;
use test::Bencher;
use std::io::prelude::*;
use std::fs::File;
#[bench]
fn zerocopy(b: &mut Bencher) {
let mut src = File::open("foo").unwrap();
let mut dest = File::create("foo.txt").unwrap();
let len = src.metadata().unwrap().len() as usize;
b.iter(|| {
::zerocopy::copy(&mut src, &mut dest).unwrap();
src.seek(::std::io::SeekFrom::Start(0));
dest.seek(::std::io::SeekFrom::Start(0));
});
std::fs::remove_file("/tmp/foo.txt");
}
#[bench]
fn default(b: &mut Bencher) {
let mut src = File::open("foo").unwrap();
let mut dest = File::create("foo.txt").unwrap();
b.iter(|| {
::std::io::copy(&mut src, &mut dest).unwrap();
src.seek(::std::io::SeekFrom::Start(0));
dest.seek(::std::io::SeekFrom::Start(0));
});
std::fs::remove_file("/tmp/foo.txt");
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment