feat(parse): run in parallel

This commit is contained in:
rvcas 2024-03-06 17:05:07 -05:00 committed by Lucas
parent 9c5556aa1e
commit f8377af0c8
2 changed files with 85 additions and 44 deletions

View File

@ -564,16 +564,21 @@ where
} }
fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Vec<Error>> { fn parse_sources(&mut self, package_name: PackageName) -> Result<ParsedModules, Vec<Error>> {
let mut errors = Vec::new(); use rayon::prelude::*;
let mut parsed_modules = HashMap::with_capacity(self.sources.len());
for Source { let (parsed_modules, errors) = self
.sources
.par_drain(0..)
.fold(
|| (ParsedModules::new(), Vec::new()),
|(mut parsed_modules, mut errors), elem| {
let Source {
path, path,
name, name,
code, code,
kind, kind,
} in self.sources.drain(0..) } = elem;
{
match aiken_lang::parser::module(&code, kind) { match aiken_lang::parser::module(&code, kind) {
Ok((mut ast, extra)) => { Ok((mut ast, extra)) => {
// Store the name // Store the name
@ -589,35 +594,61 @@ where
package: package_name.to_string(), package: package_name.to_string(),
}; };
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,
}
.into());
}
parsed_modules.insert(module.name.clone(), module); parsed_modules.insert(module.name.clone(), module);
(parsed_modules, errors)
} }
Err(errs) => { Err(errs) => {
for error in errs { for error in errs {
errors.push(Error::Parse { errors.push((
path: path.clone(), path.clone(),
src: code.clone(), code.clone(),
named: NamedSource::new(path.display().to_string(), code.clone()), NamedSource::new(path.display().to_string(), code.clone()),
error: Box::new(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<Error> = 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() { if errors.is_empty() {
Ok(parsed_modules.into()) Ok(parsed_modules)
} else { } else {
Err(errors) Err(errors)
} }

View File

@ -42,6 +42,10 @@ impl ParsedModule {
pub struct ParsedModules(HashMap<String, ParsedModule>); pub struct ParsedModules(HashMap<String, ParsedModule>);
impl ParsedModules { impl ParsedModules {
pub fn new() -> Self {
Self(HashMap::new())
}
pub fn sequence(&self) -> Result<Vec<String>, Error> { pub fn sequence(&self) -> Result<Vec<String>, Error> {
let inputs = self let inputs = self
.0 .0
@ -103,6 +107,12 @@ impl ParsedModules {
} }
} }
impl Default for ParsedModules {
fn default() -> Self {
Self::new()
}
}
impl From<HashMap<String, ParsedModule>> for ParsedModules { impl From<HashMap<String, ParsedModule>> for ParsedModules {
fn from(parsed_modules: HashMap<String, ParsedModule>) -> Self { fn from(parsed_modules: HashMap<String, ParsedModule>) -> Self {
ParsedModules(parsed_modules) ParsedModules(parsed_modules)