diff --git a/file_linked/src/lib.rs b/file_linked/src/lib.rs index d7741fb..31a70ef 100644 --- a/file_linked/src/lib.rs +++ b/file_linked/src/lib.rs @@ -5,12 +5,14 @@ pub mod error; use anyhow::{anyhow, Context}; use error::Error; use log::info; -use serde::de::DeserializeOwned; -use serde::Serialize; -use std::fs::{copy, remove_file, File}; -use std::io::ErrorKind; -use std::io::Write; -use std::path::{Path, PathBuf}; +use serde::{de::DeserializeOwned, Serialize}; +use std::{ + fs::{copy, remove_file, File}, + io::{ErrorKind, Write}, + path::{Path, PathBuf}, + thread, + thread::JoinHandle, +}; /// A wrapper around an object `T` that ties the object to a physical file #[derive(Debug)] @@ -21,7 +23,7 @@ where val: T, path: PathBuf, temp_file_path: PathBuf, - file_thread: Option>, + file_thread: Option>, } impl Drop for FileLinked @@ -145,12 +147,14 @@ where .with_context(|| "Unable to serialize object into bincode".to_string())?; if let Some(file_thread) = self.file_thread.take() { - file_thread.join().expect("Error cleaning up file thread for file_linked object"); + file_thread + .join() + .expect("Error cleaning up file thread for file_linked object"); } match File::open(&self.path) { Ok(_) => { - let handle = std::thread::spawn(move || { + let handle = thread::spawn(move || { copy(&thread_path, &thread_temp_path).expect("Unable to copy temp file"); let mut file = File::create(&thread_path).expect("Error creating file handle"); @@ -164,7 +168,7 @@ where self.file_thread = Some(handle); } Err(error) if error.kind() == ErrorKind::NotFound => { - let handle = std::thread::spawn(move || { + let handle = thread::spawn(move || { let mut file = File::create(&thread_path).expect("Error creating file handle"); file.write_all(thread_val.as_slice()) @@ -348,7 +352,7 @@ where )); match File::open(path).map_err(Error::from).and_then(|file| { - bincode::deserialize_from::(file) + bincode::deserialize_from::(file) .with_context(|| format!("Unable to deserialize file {}", path.display())) .map_err(Error::from) }) { diff --git a/gemla/src/bin/bin.rs b/gemla/src/bin/bin.rs index e1c948b..69bfdac 100644 --- a/gemla/src/bin/bin.rs +++ b/gemla/src/bin/bin.rs @@ -8,12 +8,15 @@ mod test_state; use anyhow::anyhow; use clap::App; -use gemla::core::{Gemla, GemlaConfig}; -use gemla::error::log_error; -use std::path::PathBuf; -use std::time::Instant; +use easy_parallel::Parallel; +use gemla::{ + constants::args::FILE, + core::{Gemla, GemlaConfig}, + error::{log_error, Error}, +}; +use smol::{channel, channel::RecvError, future, Executor}; +use std::{path::PathBuf, time::Instant}; use test_state::TestState; -// use std::io::Write; /// Runs a simluation of a genetic algorithm against a dataset. /// @@ -27,16 +30,13 @@ fn main() -> anyhow::Result<()> { // Obtainning number of threads to use let num_threads = num_cpus::get().max(1); - let ex = smol::Executor::new(); - let (signal, shutdown) = smol::channel::unbounded::<()>(); + let ex = Executor::new(); + let (signal, shutdown) = channel::unbounded::<()>(); // Create an executor thread pool. - let (_, result): ( - Vec>, - Result<(), gemla::error::Error>, - ) = easy_parallel::Parallel::new() + let (_, result): (Vec>, Result<(), Error>) = Parallel::new() .each(0..num_threads, |_| { - smol::future::block_on(ex.run(shutdown.recv())) + future::block_on(ex.run(shutdown.recv())) }) .finish(|| { smol::block_on(async { @@ -48,7 +48,7 @@ fn main() -> anyhow::Result<()> { let matches = App::from_yaml(yaml).get_matches(); // Checking that the first argument is a valid file - if let Some(file_path) = matches.value_of(gemla::constants::args::FILE) { + if let Some(file_path) = matches.value_of(FILE) { let mut gemla = log_error(Gemla::::new( &PathBuf::from(file_path), GemlaConfig { @@ -61,9 +61,7 @@ fn main() -> anyhow::Result<()> { Ok(()) } else { - Err(gemla::error::Error::Other(anyhow!( - "Invalid argument for FILE" - ))) + Err(Error::Other(anyhow!("Invalid argument for FILE"))) } }) }); diff --git a/gemla/src/bin/test_state/mod.rs b/gemla/src/bin/test_state/mod.rs index 72a09e3..fac0305 100644 --- a/gemla/src/bin/test_state/mod.rs +++ b/gemla/src/bin/test_state/mod.rs @@ -1,7 +1,5 @@ -use gemla::core::genetic_node::GeneticNode; -use gemla::error; +use gemla::{core::genetic_node::GeneticNode, error::Error}; use rand::prelude::*; -use rand::thread_rng; use serde::{Deserialize, Serialize}; const POPULATION_SIZE: u64 = 5; @@ -13,7 +11,7 @@ pub struct TestState { } impl GeneticNode for TestState { - fn initialize() -> Result, error::Error> { + fn initialize() -> Result, Error> { let mut population: Vec = vec![]; for _ in 0..POPULATION_SIZE { @@ -23,7 +21,7 @@ impl GeneticNode for TestState { Ok(Box::new(TestState { population })) } - fn simulate(&mut self) -> Result<(), error::Error> { + fn simulate(&mut self) -> Result<(), Error> { let mut rng = thread_rng(); self.population = self @@ -35,7 +33,7 @@ impl GeneticNode for TestState { Ok(()) } - fn mutate(&mut self) -> Result<(), error::Error> { + fn mutate(&mut self) -> Result<(), Error> { let mut rng = thread_rng(); let mut v = self.population.clone(); @@ -73,7 +71,7 @@ impl GeneticNode for TestState { Ok(()) } - fn merge(left: &TestState, right: &TestState) -> Result, error::Error> { + fn merge(left: &TestState, right: &TestState) -> Result, Error> { let mut v = left.population.clone(); v.append(&mut right.population.clone()); diff --git a/gemla/src/core/genetic_node.rs b/gemla/src/core/genetic_node.rs index b59bf0c..5ce6f7b 100644 --- a/gemla/src/core/genetic_node.rs +++ b/gemla/src/core/genetic_node.rs @@ -7,6 +7,7 @@ use crate::error::Error; use anyhow::Context; use serde::{Deserialize, Serialize}; use std::fmt::Debug; +use uuid::Uuid; /// An enum used to control the state of a [`GeneticNode`] /// @@ -52,7 +53,7 @@ pub struct GeneticNodeWrapper { state: GeneticState, generation: u64, max_generations: u64, - id: uuid::Uuid, + id: Uuid, } impl Default for GeneticNodeWrapper { @@ -62,7 +63,7 @@ impl Default for GeneticNodeWrapper { state: GeneticState::Initialize, generation: 0, max_generations: 1, - id: uuid::Uuid::new_v4(), + id: Uuid::new_v4(), } } } @@ -78,7 +79,7 @@ where } } - pub fn from(data: T, max_generations: u64, id: uuid::Uuid) -> Self { + pub fn from(data: T, max_generations: u64, id: Uuid) -> Self { GeneticNodeWrapper { node: Some(data), state: GeneticState::Simulate, @@ -92,7 +93,7 @@ where self.node.as_ref() } - pub fn id(&self) -> uuid::Uuid { + pub fn id(&self) -> Uuid { self.id } diff --git a/gemla/src/core/mod.rs b/gemla/src/core/mod.rs index b3803f1..37a72fd 100644 --- a/gemla/src/core/mod.rs +++ b/gemla/src/core/mod.rs @@ -3,19 +3,17 @@ pub mod genetic_node; -use crate::error::Error; -use crate::tree::Tree; +use crate::{error::Error, tree::Tree}; use file_linked::FileLinked; +use futures::{future, future::BoxFuture}; use genetic_node::{GeneticNode, GeneticNodeWrapper, GeneticState}; use log::{info, trace, warn}; -use serde::de::DeserializeOwned; -use serde::{Deserialize, Serialize}; -use std::fmt::Debug; -use std::fs::File; -use std::io::ErrorKind; -use std::mem::swap; -use std::path::Path; -use std::time::Instant; +use serde::{de::DeserializeOwned, Deserialize, Serialize}; +use std::{ + collections::HashMap, fmt::Debug, fs::File, io::ErrorKind, marker::Send, mem, path::Path, + time::Instant, +}; +use uuid::Uuid; type SimulationTree = Box>>; @@ -36,15 +34,12 @@ where T: Serialize + Clone, { pub data: FileLinked<(Option>, GemlaConfig)>, - threads: std::collections::HashMap< - uuid::Uuid, - futures::prelude::future::BoxFuture<'a, Result, Error>>, - >, + threads: HashMap, Error>>>, } impl<'a, T: 'a> Gemla<'a, T> where - T: GeneticNode + Serialize + DeserializeOwned + Debug + Clone + std::marker::Send, + T: GeneticNode + Serialize + DeserializeOwned + Debug + Clone + Send, { pub fn new(path: &Path, config: GemlaConfig) -> Result { match File::open(path) { @@ -54,11 +49,11 @@ where } else { FileLinked::from_file(path)? }, - threads: std::collections::HashMap::new(), + threads: HashMap::new(), }), Err(error) if error.kind() == ErrorKind::NotFound => Ok(Gemla { data: FileLinked::new((None, config), path)?, - threads: std::collections::HashMap::new(), + threads: HashMap::new(), }), Err(error) => Err(Error::IO(error)), } @@ -69,11 +64,9 @@ where // in the tree and which nodes have not. self.data.mutate(|(d, c)| { let mut tree: Option> = Gemla::increase_height(d.take(), c, steps); - swap(d, &mut tree); + mem::swap(d, &mut tree); })?; - // println!("{}", serde_json::to_string(&self.data.readonly().0).expect("")); - info!( "Height of simulation tree increased to {}", self.data @@ -124,7 +117,7 @@ where if !self.threads.is_empty() { trace!("Joining threads for nodes {:?}", self.threads.keys()); - let results = futures::future::join_all(self.threads.values_mut()).await; + let results = future::join_all(self.threads.values_mut()).await; let reduced_results: Result>, Error> = results.into_iter().collect();