Refactoring unwrap usage

This commit is contained in:
vandomej 2021-11-07 10:52:32 -08:00
parent bf1fd5a7d1
commit 95c65fa4b1
6 changed files with 88 additions and 70 deletions

2
.gitignore vendored
View file

@ -10,3 +10,5 @@ Cargo.lock
**/*.rs.bk **/*.rs.bk
settings.json settings.json
.DS_Store

View file

@ -29,10 +29,8 @@ where
T: Serialize, T: Serialize,
{ {
fn drop(&mut self) { fn drop(&mut self) {
if self.file_thread.is_some() { if let Some(file_thread) = self.file_thread.take() {
let file_thread = self.file_thread.take();
file_thread file_thread
.unwrap()
.join() .join()
.expect("Error cleaning up file thread for file_linked object"); .expect("Error cleaning up file thread for file_linked object");
} }
@ -145,9 +143,9 @@ where
let thread_temp_path = self.temp_file_path.clone(); let thread_temp_path = self.temp_file_path.clone();
let thread_val = bincode::serialize(&self.val) let thread_val = bincode::serialize(&self.val)
.with_context(|| "Unable to serialize object into bincode".to_string())?; .with_context(|| "Unable to serialize object into bincode".to_string())?;
if self.file_thread.is_some() {
let file_thread = self.file_thread.take(); if let Some(file_thread) = self.file_thread.take() {
file_thread.unwrap().join().expect("Unable to join thread"); file_thread.join().expect("Error cleaning up file thread for file_linked object");
} }
match File::open(&self.path) { match File::open(&self.path) {

View file

@ -6,6 +6,7 @@ extern crate log;
mod test_state; mod test_state;
use anyhow::anyhow;
use clap::App; use clap::App;
use gemla::core::{Gemla, GemlaConfig}; use gemla::core::{Gemla, GemlaConfig};
use gemla::error::log_error; use gemla::error::log_error;
@ -46,12 +47,12 @@ fn main() -> anyhow::Result<()> {
let yaml = load_yaml!("../../cli.yml"); let yaml = load_yaml!("../../cli.yml");
let matches = App::from_yaml(yaml).get_matches(); let matches = App::from_yaml(yaml).get_matches();
// Checking that the first argument <DIRECTORY> is a valid directory // Checking that the first argument <FILE> is a valid file
let file_path = matches.value_of(gemla::constants::args::FILE).unwrap(); if let Some(file_path) = matches.value_of(gemla::constants::args::FILE) {
let mut gemla = log_error(Gemla::<TestState>::new( let mut gemla = log_error(Gemla::<TestState>::new(
&PathBuf::from(file_path), &PathBuf::from(file_path),
GemlaConfig { GemlaConfig {
generations_per_node: 1, generations_per_node: 3,
overwrite: true, overwrite: true,
}, },
))?; ))?;
@ -59,6 +60,11 @@ fn main() -> anyhow::Result<()> {
log_error(gemla.simulate(3).await)?; log_error(gemla.simulate(3).await)?;
Ok(()) Ok(())
} else {
Err(gemla::error::Error::Other(anyhow!(
"Invalid argument for FILE"
)))
}
}) })
}); });

View file

@ -3,7 +3,6 @@ use gemla::error;
use rand::prelude::*; use rand::prelude::*;
use rand::thread_rng; use rand::thread_rng;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::convert::TryInto;
const POPULATION_SIZE: u64 = 5; const POPULATION_SIZE: u64 = 5;
const POPULATION_REDUCTION_SIZE: u64 = 3; const POPULATION_REDUCTION_SIZE: u64 = 3;
@ -47,7 +46,7 @@ impl GeneticNode for TestState {
self.population = v[0..(POPULATION_REDUCTION_SIZE as usize)].to_vec(); self.population = v[0..(POPULATION_REDUCTION_SIZE as usize)].to_vec();
loop { loop {
if self.population.len() >= POPULATION_SIZE.try_into().unwrap() { if self.population.len() as u64 >= POPULATION_SIZE {
break; break;
} }

View file

@ -105,16 +105,13 @@ where
} }
pub fn process_node(&mut self) -> Result<GeneticState, Error> { pub fn process_node(&mut self) -> Result<GeneticState, Error> {
match (&self.state, &self.node) { match (self.state, &mut self.node) {
(GeneticState::Initialize, _) => { (GeneticState::Initialize, _) => {
self.node = Some(*T::initialize()?); self.node = Some(*T::initialize()?);
self.state = GeneticState::Simulate; self.state = GeneticState::Simulate;
} }
(GeneticState::Simulate, Some(_)) => { (GeneticState::Simulate, Some(n)) => {
self.node n.simulate()
.as_mut()
.unwrap()
.simulate()
.with_context(|| format!("Error simulating node: {:?}", self))?; .with_context(|| format!("Error simulating node: {:?}", self))?;
self.state = if self.generation >= self.max_generations { self.state = if self.generation >= self.max_generations {
@ -123,11 +120,8 @@ where
GeneticState::Mutate GeneticState::Mutate
}; };
} }
(GeneticState::Mutate, Some(_)) => { (GeneticState::Mutate, Some(n)) => {
self.node n.mutate()
.as_mut()
.unwrap()
.mutate()
.with_context(|| format!("Error mutating node: {:?}", self))?; .with_context(|| format!("Error mutating node: {:?}", self))?;
self.generation += 1; self.generation += 1;

View file

@ -76,21 +76,36 @@ where
info!( info!(
"Height of simulation tree increased to {}", "Height of simulation tree increased to {}",
self.data.readonly().0.as_ref().unwrap().height() self.data
.readonly()
.0
.as_ref()
.map(|t| format!("{}", t.height()))
.unwrap_or_else(|| "Tree is not defined".to_string())
); );
loop { loop {
if Gemla::is_completed(self.data.readonly().0.as_ref().unwrap()) { if self
.data
.readonly()
.0
.as_ref()
.map(|t| Gemla::is_completed(t))
.unwrap_or(false)
{
self.join_threads().await?; self.join_threads().await?;
info!("Processed tree"); info!("Processed tree");
break; break;
} }
let node_to_process = if let Some(node) = self
self.get_unprocessed_node(self.data.readonly().0.as_ref().unwrap()); .data
.readonly()
if let Some(node) = node_to_process { .0
.as_ref()
.and_then(|t| self.get_unprocessed_node(t))
{
trace!("Adding node to process list {}", node.id()); trace!("Adding node to process list {}", node.id());
self.threads self.threads
@ -116,10 +131,9 @@ where
self.threads.clear(); self.threads.clear();
reduced_results.and_then(|r| { reduced_results.and_then(|r| {
let failed_nodes = self self.data.mutate(|(d, _)| {
.data if let Some(t) = d {
.mutate(|(d, _)| Gemla::replace_nodes(d.as_mut().unwrap(), r))?; let failed_nodes = Gemla::replace_nodes(t, r);
if !failed_nodes.is_empty() { if !failed_nodes.is_empty() {
warn!( warn!(
"Unable to find {:?} to replace in tree", "Unable to find {:?} to replace in tree",
@ -127,10 +141,12 @@ where
) )
} }
self.data Gemla::merge_completed_nodes(t)
.mutate(|(d, _)| Gemla::merge_completed_nodes(d.as_mut().unwrap()))??; } else {
warn!("Unable to replce nodes {:?} in empty tree", r);
Ok(()) Ok(())
}
})?
})?; })?;
} }
@ -145,9 +161,7 @@ where
&& r.val.state() == GeneticState::Finish => && r.val.state() == GeneticState::Finish =>
{ {
info!("Merging nodes {} and {}", l.val.id(), r.val.id()); info!("Merging nodes {} and {}", l.val.id(), r.val.id());
if let (Some(left_node), Some(right_node)) = (l.val.as_ref(), r.val.as_ref()) {
let left_node = l.val.as_ref().unwrap();
let right_node = r.val.as_ref().unwrap();
let merged_node = GeneticNode::merge(left_node, right_node)?; let merged_node = GeneticNode::merge(left_node, right_node)?;
tree.val = GeneticNodeWrapper::from( tree.val = GeneticNodeWrapper::from(
*merged_node, *merged_node,
@ -155,6 +169,7 @@ where
tree.val.id(), tree.val.id(),
); );
} }
}
(Some(l), Some(r)) => { (Some(l), Some(r)) => {
Gemla::merge_completed_nodes(l)?; Gemla::merge_completed_nodes(l)?;
Gemla::merge_completed_nodes(r)?; Gemla::merge_completed_nodes(r)?;
@ -162,22 +177,26 @@ where
(Some(l), None) if l.val.state() == GeneticState::Finish => { (Some(l), None) if l.val.state() == GeneticState::Finish => {
trace!("Copying node {}", l.val.id()); trace!("Copying node {}", l.val.id());
tree.val = GeneticNodeWrapper::from( if let Some(left_node) = l.val.as_ref() {
l.val.as_ref().unwrap().clone(), GeneticNodeWrapper::from(
left_node.clone(),
tree.val.max_generations(), tree.val.max_generations(),
tree.val.id(), tree.val.id(),
); );
} }
}
(Some(l), None) => Gemla::merge_completed_nodes(l)?, (Some(l), None) => Gemla::merge_completed_nodes(l)?,
(None, Some(r)) if r.val.state() == GeneticState::Finish => { (None, Some(r)) if r.val.state() == GeneticState::Finish => {
trace!("Copying node {}", r.val.id()); trace!("Copying node {}", r.val.id());
if let Some(right_node) = r.val.as_ref() {
tree.val = GeneticNodeWrapper::from( tree.val = GeneticNodeWrapper::from(
r.val.as_ref().unwrap().clone(), right_node.clone(),
tree.val.max_generations(), tree.val.max_generations(),
tree.val.id(), tree.val.id(),
); );
} }
}
(None, Some(r)) => Gemla::merge_completed_nodes(r)?, (None, Some(r)) => Gemla::merge_completed_nodes(r)?,
(_, _) => (), (_, _) => (),
} }
@ -289,7 +308,7 @@ mod tests {
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use std::str::FromStr; use std::str::FromStr;
#[derive(Default, Deserialize, Serialize, Clone, Debug, PartialEq)] #[derive(Deserialize, Serialize, Clone, Debug, PartialEq)]
struct TestState { struct TestState {
pub score: f64, pub score: f64,
} }