Skip to content

Instantly share code, notes, and snippets.

@Ironlenny
Created September 14, 2020 01:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Ironlenny/3b7c3d027718aa739fd3b84d10ddd7cb to your computer and use it in GitHub Desktop.
Save Ironlenny/3b7c3d027718aa739fd3b84d10ddd7cb to your computer and use it in GitHub Desktop.
Weird compiler error
[package]
name = "rupart"
version = "0.1.0"
edition = "2018"
[dependencies]
structopt = "0.2"
failure = ">=0.1.5"
md-5 = ">=0.8"
rayon = ">=1.0.3"
itertools = ">=0.8.0"
crc32fast = ">=1.2.0"
typename = { git = "https://github.com/Ironlenny/typename", branch = "master" }
lazy_static = ">=1.3.0"
[dependencies.async-std]
version = "1.6.3"
features = ["unstable"]
[dev-dependencies]
tempfile = "3.1.0"
hex-literal = ">=0.2.0"
use async_std::fs::File;
use async_std::io::Read;
use async_std::io::Result;
use async_std::prelude::*;
use async_std::stream;
use async_std::sync::{Arc, Mutex};
use async_std::task;
use async_std::task::Poll;
use async_std::task::{Context, JoinHandle};
type FutureBlock = JoinHandle<Result<Vec<u8>>>;
async fn read_blocks(
file: File,
num_blocks: usize,
block_size: usize,
pool: Arc<RwLock<usize>>,
queue: &mut VecDeque<FutureBlock>,
) {
let mut file = Arc::new(Mutex::new(file));
if *(pool.read().unwrap()) > 0 {
let mut pool = pool.write().unwrap();
let mut credits = if *pool >= num_blocks {
*pool -= num_blocks;
num_blocks
} else {
let temp = *pool;
*pool -= *pool;
temp
};
drop(pool);
while credits > 0 {
let mut lock= file.clone().lock().await;
// let mut block_reader = async_std::io::Read::take(*lock, block_size as u64);
let mut block_reader = <async_std::fs::File as async_std::io::Read>::take(*lock, block_size as u64);
queue.push_back(task::spawn(async move {
let mut block = vec![0u8; block_size];
block_reader.read(&mut block).await?;
Ok(block)
}));
credits -= 1
}
}
}
#[cfg(test)]
mod test {
use super::*;
use async_std::task::block_on;
use hex_literal::hex;
use tempfile::tempdir;
const FILE_LENGTH: usize = 1024000;
const BLOCK_SIZE: usize = 10240;
const NUM_BLOCKS: usize = FILE_LENGTH / BLOCK_SIZE;
fn write_test_file() -> (File, PathBuf, Arc<RwLock<usize>>) {
let bytes: Vec<u8> = vec![17; FILE_LENGTH];
let dir = tempdir().unwrap();
let path = dir.path().join("test_data");
let mut file = block_on(File::create(&path)).unwrap();
block_on(file.write_all(&bytes));
// File system lies. Must flush writes to disk.
block_on(file.sync_all());
let file = block_on(File::open(&path)).unwrap();
let pool = Arc::new(RwLock::new(100usize));
(file, path, pool)
}
#[test]
fn test_read_blocks() {
let test_block: Vec<u8> = vec![17; BLOCK_SIZE];
let (file, _, pool) = write_test_file();
let mut blocks = VecDeque::new();
read_blocks(file, NUM_BLOCKS, BLOCK_SIZE, pool, &mut blocks);
for (i, block) in blocks.iter_mut().enumerate() {
let block = task::block_on(block).unwrap();
assert_eq!(block, test_block, "Block {} did not match", i);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment