From f8377af0c84b075136cf2ccda1bf59c22f9d4aca Mon Sep 17 00:00:00 2001 From: rvcas Date: Wed, 6 Mar 2024 17:05:07 -0500 Subject: [PATCH] feat(parse): run in parallel --- crates/aiken-project/src/lib.rs | 119 ++++++++++++++++++----------- crates/aiken-project/src/module.rs | 10 +++ 2 files changed, 85 insertions(+), 44 deletions(-) diff --git a/crates/aiken-project/src/lib.rs b/crates/aiken-project/src/lib.rs index f3961519..3ac3e70e 100644 --- a/crates/aiken-project/src/lib.rs +++ b/crates/aiken-project/src/lib.rs @@ -564,60 +564,91 @@ where } fn parse_sources(&mut self, package_name: PackageName) -> Result> { - let mut errors = Vec::new(); - let mut parsed_modules = HashMap::with_capacity(self.sources.len()); + use rayon::prelude::*; - for Source { - path, - name, - code, - kind, - } in self.sources.drain(0..) - { - match aiken_lang::parser::module(&code, kind) { - Ok((mut ast, extra)) => { - // Store the name - ast.name = name.clone(); - - let module = ParsedModule { - kind, - ast, - code, - name, + let (parsed_modules, errors) = self + .sources + .par_drain(0..) + .fold( + || (ParsedModules::new(), Vec::new()), + |(mut parsed_modules, mut errors), elem| { + let Source { path, - extra, - package: package_name.to_string(), - }; + name, + code, + kind, + } = elem; - if let Some(first) = self - .defined_modules - .insert(module.name.clone(), module.path.clone()) - { - return Err(Error::DuplicateModule { - module: module.name.clone(), - first, - second: module.path, + match aiken_lang::parser::module(&code, kind) { + Ok((mut ast, extra)) => { + // Store the name + ast.name = name.clone(); + + let module = ParsedModule { + kind, + ast, + code, + name, + path, + extra, + package: package_name.to_string(), + }; + + parsed_modules.insert(module.name.clone(), module); + + (parsed_modules, errors) } - .into()); - } + Err(errs) => { + for error in errs { + errors.push(( + path.clone(), + code.clone(), + NamedSource::new(path.display().to_string(), code.clone()), + Box::new(error), + )) + } - parsed_modules.insert(module.name.clone(), module); - } - Err(errs) => { - for error in errs { - errors.push(Error::Parse { - path: path.clone(), - src: code.clone(), - named: NamedSource::new(path.display().to_string(), code.clone()), - error: Box::new(error), - }) + (parsed_modules, errors) + } } - } + }, + ) + .reduce( + || (ParsedModules::new(), Vec::new()), + |(mut parsed_modules, mut errors), (mut parsed, errs)| { + parsed_modules.extend(parsed.drain()); + + errors.extend(errs); + + (parsed_modules, errors) + }, + ); + + let mut errors: Vec = errors + .into_iter() + .map(|(path, src, named, error)| Error::Parse { + path, + src, + named, + error, + }) + .collect(); + + for parsed_module in parsed_modules.values() { + if let Some(first) = self + .defined_modules + .insert(parsed_module.name.clone(), parsed_module.path.clone()) + { + errors.push(Error::DuplicateModule { + module: parsed_module.name.clone(), + first, + second: parsed_module.path.clone(), + }); } } if errors.is_empty() { - Ok(parsed_modules.into()) + Ok(parsed_modules) } else { Err(errors) } diff --git a/crates/aiken-project/src/module.rs b/crates/aiken-project/src/module.rs index 647b4f2c..d7a579b8 100644 --- a/crates/aiken-project/src/module.rs +++ b/crates/aiken-project/src/module.rs @@ -42,6 +42,10 @@ impl ParsedModule { pub struct ParsedModules(HashMap); impl ParsedModules { + pub fn new() -> Self { + Self(HashMap::new()) + } + pub fn sequence(&self) -> Result, Error> { let inputs = self .0 @@ -103,6 +107,12 @@ impl ParsedModules { } } +impl Default for ParsedModules { + fn default() -> Self { + Self::new() + } +} + impl From> for ParsedModules { fn from(parsed_modules: HashMap) -> Self { ParsedModules(parsed_modules)