Refactoring unwrap usage
This commit is contained in:
parent
bf1fd5a7d1
commit
95c65fa4b1
6 changed files with 88 additions and 70 deletions
2
.gitignore
vendored
2
.gitignore
vendored
|
@ -10,3 +10,5 @@ Cargo.lock
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|
||||||
settings.json
|
settings.json
|
||||||
|
|
||||||
|
.DS_Store
|
|
@ -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) {
|
||||||
|
|
|
@ -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,19 +47,24 @@ 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,
|
||||||
},
|
},
|
||||||
))?;
|
))?;
|
||||||
|
|
||||||
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"
|
||||||
|
)))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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,21 +131,22 @@ 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() {
|
||||||
|
warn!(
|
||||||
|
"Unable to find {:?} to replace in tree",
|
||||||
|
failed_nodes.iter().map(|n| n.id())
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
if !failed_nodes.is_empty() {
|
Gemla::merge_completed_nodes(t)
|
||||||
warn!(
|
} else {
|
||||||
"Unable to find {:?} to replace in tree",
|
warn!("Unable to replce nodes {:?} in empty tree", r);
|
||||||
failed_nodes.iter().map(|n| n.id())
|
Ok(())
|
||||||
)
|
}
|
||||||
}
|
})?
|
||||||
|
|
||||||
self.data
|
|
||||||
.mutate(|(d, _)| Gemla::merge_completed_nodes(d.as_mut().unwrap()))??;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,15 +161,14 @@ 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 merged_node = GeneticNode::merge(left_node, right_node)?;
|
||||||
let right_node = r.val.as_ref().unwrap();
|
tree.val = GeneticNodeWrapper::from(
|
||||||
let merged_node = GeneticNode::merge(left_node, right_node)?;
|
*merged_node,
|
||||||
tree.val = GeneticNodeWrapper::from(
|
tree.val.max_generations(),
|
||||||
*merged_node,
|
tree.val.id(),
|
||||||
tree.val.max_generations(),
|
);
|
||||||
tree.val.id(),
|
}
|
||||||
);
|
|
||||||
}
|
}
|
||||||
(Some(l), Some(r)) => {
|
(Some(l), Some(r)) => {
|
||||||
Gemla::merge_completed_nodes(l)?;
|
Gemla::merge_completed_nodes(l)?;
|
||||||
|
@ -162,21 +177,25 @@ 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(
|
||||||
tree.val.max_generations(),
|
left_node.clone(),
|
||||||
tree.val.id(),
|
tree.val.max_generations(),
|
||||||
);
|
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());
|
||||||
|
|
||||||
tree.val = GeneticNodeWrapper::from(
|
if let Some(right_node) = r.val.as_ref() {
|
||||||
r.val.as_ref().unwrap().clone(),
|
tree.val = GeneticNodeWrapper::from(
|
||||||
tree.val.max_generations(),
|
right_node.clone(),
|
||||||
tree.val.id(),
|
tree.val.max_generations(),
|
||||||
);
|
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,
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue