Skip to content

Commit

Permalink
perf: flatten concat_source when constructing it (#78)
Browse files Browse the repository at this point in the history
  • Loading branch information
Boshen and SyMind authored Feb 20, 2024
1 parent 8bae04e commit eca4132
Showing 1 changed file with 36 additions and 15 deletions.
51 changes: 36 additions & 15 deletions src/concat_source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ use crate::{
/// .unwrap()
/// );
/// ```
#[derive(Debug, Default, Clone, Eq)]
#[derive(Debug, Default, Clone)]
pub struct ConcatSource {
children: Vec<BoxSource>,
}
Expand All @@ -66,26 +66,46 @@ impl ConcatSource {
T: Source + 'static,
S: IntoIterator<Item = T>,
{
Self {
children: sources.into_iter().map(|s| SourceExt::boxed(s)).collect(),
}
// Flatten the children
let children = sources
.into_iter()
.flat_map(
|source| match source.as_any().downcast_ref::<ConcatSource>() {
// This clone is cheap because `BoxSource` is `Arc`ed for each child.
Some(concat_source) => concat_source.children.clone(),
None => {
vec![SourceExt::boxed(source)]
}
},
)
.collect();
Self { children }
}

fn children(&self) -> &Vec<BoxSource> {
&self.children
}

/// Add a [Source] to concat.
pub fn add<S: Source + 'static>(&mut self, item: S) {
self.children.push(SourceExt::boxed(item));
pub fn add<S: Source + 'static>(&mut self, source: S) {
if let Some(concat_source) = source.as_any().downcast_ref::<ConcatSource>()
{
self.children.extend(concat_source.children.clone());
} else {
self.children.push(SourceExt::boxed(source));
}
}
}

impl Source for ConcatSource {
fn source(&self) -> Cow<str> {
let all = self.children.iter().map(|child| child.source()).collect();
let all = self.children().iter().map(|child| child.source()).collect();
Cow::Owned(all)
}

fn buffer(&self) -> Cow<[u8]> {
let all = self
.children
.children()
.iter()
.map(|child| child.buffer())
.collect::<Vec<_>>()
Expand All @@ -94,15 +114,15 @@ impl Source for ConcatSource {
}

fn size(&self) -> usize {
self.children.iter().map(|child| child.size()).sum()
self.children().iter().map(|child| child.size()).sum()
}

fn map(&self, options: &MapOptions) -> Option<SourceMap> {
get_map(self, options)
}

fn to_writer(&self, writer: &mut dyn std::io::Write) -> std::io::Result<()> {
for child in &self.children {
for child in self.children() {
child.to_writer(writer)?;
}
Ok(())
Expand All @@ -112,17 +132,18 @@ impl Source for ConcatSource {
impl Hash for ConcatSource {
fn hash<H: Hasher>(&self, state: &mut H) {
"ConcatSource".hash(state);
for child in self.children.iter() {
for child in self.children().iter() {
child.hash(state);
}
}
}

impl PartialEq for ConcatSource {
fn eq(&self, other: &Self) -> bool {
self.children == other.children
self.children() == other.children()
}
}
impl Eq for ConcatSource {}

impl StreamChunks for ConcatSource {
fn stream_chunks(
Expand All @@ -132,16 +153,16 @@ impl StreamChunks for ConcatSource {
on_source: OnSource,
on_name: OnName,
) -> crate::helpers::GeneratedInfo {
if self.children.len() == 1 {
return self.children[0]
if self.children().len() == 1 {
return self.children()[0]
.stream_chunks(options, on_chunk, on_source, on_name);
}
let mut current_line_offset = 0;
let mut current_column_offset = 0;
let mut source_mapping: HashMap<String, u32> = HashMap::default();
let mut name_mapping: HashMap<String, u32> = HashMap::default();
let mut need_to_cloas_mapping = false;
for item in &self.children {
for item in self.children() {
let source_index_mapping: RefCell<HashMap<u32, u32>> =
RefCell::new(HashMap::default());
let name_index_mapping: RefCell<HashMap<u32, u32>> =
Expand Down

0 comments on commit eca4132

Please sign in to comment.