use par_io;
use std::fs::File;
use std::io::Cursor;
use std::io::Read;
use std::io::Seek;
use std::io::SeekFrom;
use std::io::Write;
fn to_u8_slice<T: Sized>(v: &Vec<T>) -> &[u8] {
unsafe {
std::slice::from_raw_parts(v.as_ptr() as *const u8, v.len() * std::mem::size_of::<T>())
}
}
#[derive(Clone)]
struct Dummy {}
struct DeleteFile(String);
impl std::ops::Drop for DeleteFile {
fn drop(&mut self) {
std::fs::remove_file(&self.0).unwrap();
}
}
#[test]
fn read() -> Result<(), String> {
let buf: Vec<u32> = (0_u32..1111).collect();
let bytes = to_u8_slice(&buf);
let filename = "tmp-read_test";
let mut file = File::options()
.create(true)
.write(true)
.open(filename)
.map_err(|err| err.to_string())?;
file.write(bytes).map_err(|err| err.to_string())?;
drop(file);
let _delete_file_at_exit = DeleteFile(filename.to_string());
let consume = |buffer: &[u8],
_data: &Dummy,
_chunk_id: u64,
_num_chunks: u64,
offset: u64|
-> (u64, Vec<u8>) { (offset, buffer.to_vec()) };
let num_producers = 4;
let num_consumers = 2;
let chunks_per_producer = 3;
let num_buffers_per_producer = 2;
let mut b: Vec<u8> = Vec::new();
match par_io::read::read_file(
filename,
num_producers,
num_consumers,
chunks_per_producer,
std::sync::Arc::new(consume),
Dummy {},
num_buffers_per_producer,
) {
Ok(v) => {
let mut out = Cursor::new(&mut b);
for (_, (offset, x)) in &v {
out.seek(SeekFrom::Start(*offset))
.map_err(|err| err.to_string())?;
out.write(x).map_err(|err| err.to_string())?;
}
}
Err(err) => {
return Err(format!("{:?}", err));
}
}
assert_eq!(bytes, b);
Ok(())
}
#[test]
fn write() -> Result<(), String> {
let buf: Vec<u32> = (0_u32..1111).collect();
let bytes = to_u8_slice(&buf).to_vec();
let data = Arc::new(bytes);
let len = data.len();
let filename = "tmp-write_test";
let _delete_file_at_exit = DeleteFile(filename.to_string());
use std::sync::Arc;
let producer = |buffer: &mut Vec<u8>, src: &Arc<Vec<u8>>, offset: u64| -> Result<(), String> {
let len = buffer.len();
let start = offset as usize;
let end = start + len;
buffer.copy_from_slice(&src[start..end]);
Ok(())
};
let num_producers = 4;
let num_consumers = 2;
let chunks_per_producer = 3;
let num_buffers_per_producer = 2;
let bytes_consumed = par_io::write::write_to_file(
&filename,
num_producers,
num_consumers,
chunks_per_producer,
Arc::new(producer),
data.clone(),
num_buffers_per_producer,
len,
)
.map_err(|err| format!("{:?}", err))?;
let len = std::fs::metadata(&filename)
.map_err(|err| err.to_string())?
.len();
assert_eq!(bytes_consumed, len as usize);
let mut file = File::open(&filename).map_err(|err| err.to_string())?;
let mut buffer: Vec<u8> = vec![0_u8; len as usize];
file.read_exact(&mut buffer)
.map_err(|err| err.to_string())?;
assert_eq!(buffer, *data);
Ok(())
}