Skip to content

Commit 7329bd2

Browse files
authored
perf: let cached source work right (#89)
1 parent 3764d68 commit 7329bd2

File tree

2 files changed

+87
-65
lines changed

2 files changed

+87
-65
lines changed

src/cached_source.rs

Lines changed: 32 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,13 @@ use std::{
77
use dashmap::DashMap;
88
use rustc_hash::FxHasher;
99

10-
use crate::{helpers::StreamChunks, MapOptions, Source, SourceMap};
10+
use crate::{
11+
helpers::{
12+
stream_and_get_source_and_map, stream_chunks_of_raw_source,
13+
stream_chunks_of_source_map, StreamChunks,
14+
},
15+
MapOptions, Source, SourceMap,
16+
};
1117

1218
/// It tries to reused cached results from other methods to avoid calculations,
1319
/// usually used after modify is finished.
@@ -44,10 +50,10 @@ use crate::{helpers::StreamChunks, MapOptions, Source, SourceMap};
4450
/// ```
4551
pub struct CachedSource<T> {
4652
inner: Arc<T>,
47-
cached_buffer: OnceLock<Vec<u8>>,
53+
cached_buffer: OnceLock<Arc<Vec<u8>>>,
4854
cached_source: OnceLock<Arc<str>>,
4955
cached_maps:
50-
DashMap<MapOptions, Option<SourceMap>, BuildHasherDefault<FxHasher>>,
56+
Arc<DashMap<MapOptions, Option<SourceMap>, BuildHasherDefault<FxHasher>>>,
5157
}
5258

5359
impl<T> CachedSource<T> {
@@ -78,7 +84,7 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for CachedSource<T> {
7884
fn buffer(&self) -> Cow<[u8]> {
7985
let cached = self
8086
.cached_buffer
81-
.get_or_init(|| self.inner.buffer().to_vec());
87+
.get_or_init(|| self.inner.buffer().to_vec().into());
8288
Cow::Borrowed(cached)
8389
}
8490

@@ -91,7 +97,7 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> Source for CachedSource<T> {
9197
map.clone()
9298
} else {
9399
let map = self.inner.map(options);
94-
self.cached_maps.insert(options.to_owned(), map.clone());
100+
self.cached_maps.insert(options.clone(), map.clone());
95101
map
96102
}
97103
}
@@ -111,24 +117,27 @@ impl<T: Source + Hash + PartialEq + Eq + 'static> StreamChunks
111117
on_source: crate::helpers::OnSource,
112118
on_name: crate::helpers::OnName,
113119
) -> crate::helpers::GeneratedInfo {
114-
// if self.cached_maps.contains_key(options)
115-
// && (self.cached_buffer.get().is_some()
116-
// || self.cached_source.get().is_some())
117-
// {
118-
// let source = self.source();
119-
// if let Some(map) = &self.map(options) {
120-
// return stream_chunks_of_source_map(
121-
// &source, map, on_chunk, on_source, on_name, options,
122-
// );
123-
// } else {
124-
// return stream_chunks_of_raw_source(
125-
// &source, options, on_chunk, on_source, on_name,
126-
// );
127-
// }
128-
// }
129-
self
130-
.inner
131-
.stream_chunks(options, on_chunk, on_source, on_name)
120+
if self.cached_maps.contains_key(options) {
121+
let source = self.source();
122+
if let Some(map) = &self.map(options) {
123+
return stream_chunks_of_source_map(
124+
&source, map, on_chunk, on_source, on_name, options,
125+
);
126+
} else {
127+
return stream_chunks_of_raw_source(
128+
&source, options, on_chunk, on_source, on_name,
129+
);
130+
}
131+
}
132+
let (generated_info, map) = stream_and_get_source_and_map(
133+
self.original(),
134+
options,
135+
on_chunk,
136+
on_source,
137+
on_name,
138+
);
139+
self.cached_maps.insert(options.clone(), map);
140+
generated_info
132141
}
133142
}
134143

src/helpers.rs

Lines changed: 55 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -1464,45 +1464,58 @@ pub fn stream_chunks_of_combined_source_map(
14641464
)
14651465
}
14661466

1467-
// pub fn stream_and_get_source_and_map<S: StreamChunks>(
1468-
// input_source: &S,
1469-
// options: &MapOptions,
1470-
// on_chunk: OnChunk,
1471-
// on_source: OnSource,
1472-
// on_name: OnName,
1473-
// ) -> () {
1474-
// let mappings = vec![];
1475-
// let sources = vec![];
1476-
// let sources_content = vec![];
1477-
// let names = vec![];
1478-
// let info = input_source.stream_chunks(
1479-
// options,
1480-
// &mut |chunk, mapping| {
1481-
// mappings.push(mapping.clone());
1482-
// return on_chunk(chunk, mapping);
1483-
// },
1484-
// &mut |source_index, source, source_content| {
1485-
// let source_index2 = source_index as usize;
1486-
// while sources.len() <= source_index2 {
1487-
// sources.push("".to_string());
1488-
// }
1489-
// sources[source_index2] = source.to_owned();
1490-
// if let Some(source_content) = source_content {
1491-
// while sources_content.len() <= source_index2 {
1492-
// sources_content.push("".to_string());
1493-
// }
1494-
// sources_content[source_index2] = source_content.to_owned();
1495-
// }
1496-
// return on_source(source_index, source, source_content);
1497-
// },
1498-
// &mut |name_index, name| {
1499-
// let name_index2 = name_index as usize;
1500-
// while names.len() <= name_index2 {
1501-
// names.push("".to_string());
1502-
// }
1503-
// names[name_index2] = name.to_owned();
1504-
// return on_name(name_index, name);
1505-
// },
1506-
// );
1507-
// (info, map)
1508-
// }
1467+
pub fn stream_and_get_source_and_map<S: StreamChunks>(
1468+
input_source: &S,
1469+
options: &MapOptions,
1470+
on_chunk: OnChunk,
1471+
on_source: OnSource,
1472+
on_name: OnName,
1473+
) -> (GeneratedInfo, Option<SourceMap>) {
1474+
let mut mappings = vec![];
1475+
let mut sources: Vec<Cow<'static, str>> = Vec::new();
1476+
let mut sources_content: Vec<Cow<'static, str>> = Vec::new();
1477+
let mut names: Vec<Cow<'static, str>> = Vec::new();
1478+
let generated_info = input_source.stream_chunks(
1479+
options,
1480+
&mut |chunk, mapping| {
1481+
mappings.push(mapping.clone());
1482+
on_chunk(chunk, mapping);
1483+
},
1484+
&mut |source_index, source, source_content| {
1485+
let source_index2 = source_index as usize;
1486+
while sources.len() <= source_index2 {
1487+
sources.push("".into());
1488+
}
1489+
sources[source_index2] = source.to_string().into();
1490+
if let Some(source_content) = source_content {
1491+
while sources_content.len() <= source_index2 {
1492+
sources_content.push("".into());
1493+
}
1494+
sources_content[source_index2] = source_content.to_string().into();
1495+
}
1496+
on_source(source_index, source, source_content);
1497+
},
1498+
&mut |name_index, name| {
1499+
let name_index2 = name_index as usize;
1500+
while names.len() <= name_index2 {
1501+
names.push("".into());
1502+
}
1503+
names[name_index2] = name.to_string().into();
1504+
on_name(name_index, name);
1505+
},
1506+
);
1507+
1508+
let mappings = encode_mappings(&mappings, options);
1509+
let map = if mappings.is_empty() {
1510+
None
1511+
} else {
1512+
Some(SourceMap::new(
1513+
None,
1514+
mappings,
1515+
sources,
1516+
sources_content,
1517+
names,
1518+
))
1519+
};
1520+
(generated_info, map)
1521+
}

0 commit comments

Comments
 (0)