1
0

Implement parallel find loop

This commit is contained in:
Jeff 2023-11-14 21:24:47 -05:00
parent 98ea049229
commit d4aac2c729
2 changed files with 30 additions and 12 deletions

View File

@ -1,7 +1,8 @@
use rayon::prelude::*;
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use tree_sitter::Node; use tree_sitter::Node;
use crate::{AbstractTree, Block, Expression, Identifier, Map, Result, Value}; use crate::{AbstractTree, Block, Error, Expression, Identifier, Map, Result, Value};
#[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)] #[derive(Debug, Clone, Serialize, Deserialize, Eq, PartialEq, PartialOrd, Ord)]
pub struct Find { pub struct Find {
@ -32,20 +33,37 @@ impl AbstractTree for Find {
let value = self.expression.run(source, context)?; let value = self.expression.run(source, context)?;
let values = value.as_list()?.items(); let values = value.as_list()?.items();
let key = self.identifier.inner(); let key = self.identifier.inner();
let loop_context = Map::clone_from(context)?;
let mut loop_context = Map::clone_from(context)?; let find_result = values.par_iter().find_map_first(|value| {
let mut variables = context.variables_mut()?; loop_context
.variables_mut()
.unwrap()
.insert(key.clone(), (*value).clone());
for value in values.iter() { let run_result = self.item.run(source, &mut loop_context.clone());
variables.insert(key.clone(), value.clone());
let should_return = self.item.run(source, &mut loop_context)?.as_boolean()?;
if let Ok(run_result_value) = run_result {
if let Ok(should_return) = run_result_value.as_boolean() {
if should_return { if should_return {
return Ok(value.clone()); Some(Ok(value.clone()))
} else {
None
} }
} else {
Some(Err(Error::ExpectedBoolean {
actual: value.clone(),
}))
} }
} else {
Some(run_result)
}
});
if let Some(result) = find_result {
result
} else {
Ok(Value::Empty) Ok(Value::Empty)
} }
}
} }

View File

@ -22,7 +22,7 @@ impl Identifier {
impl AbstractTree for Identifier { impl AbstractTree for Identifier {
fn from_syntax_node(source: &str, node: Node) -> Result<Self> { fn from_syntax_node(source: &str, node: Node) -> Result<Self> {
debug_assert_eq!("identifier", node.kind()); Error::expect_syntax_node(source, "identifier", node)?;
let identifier = &source[node.byte_range()]; let identifier = &source[node.byte_range()];