Skip to content

Commit 920711b

Browse files
authored
perf: linear mapping (#111)
1 parent 7c4ca9f commit 920711b

File tree

5 files changed

+94
-51
lines changed

5 files changed

+94
-51
lines changed

src/concat_source.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_hash::FxHashMap as HashMap;
88

99
use crate::{
1010
helpers::{get_map, GeneratedInfo, OnChunk, OnName, OnSource, StreamChunks},
11+
linear_map::LinearMap,
1112
source::{Mapping, OriginalLocation},
1213
BoxSource, MapOptions, Source, SourceExt, SourceMap,
1314
};
@@ -163,10 +164,10 @@ impl<'a> StreamChunks<'a> for ConcatSource {
163164
let mut name_mapping: HashMap<Cow<str>, u32> = HashMap::default();
164165
let mut need_to_close_mapping = false;
165166

166-
let source_index_mapping: RefCell<HashMap<u32, u32>> =
167-
RefCell::new(HashMap::default());
168-
let name_index_mapping: RefCell<HashMap<u32, u32>> =
169-
RefCell::new(HashMap::default());
167+
let source_index_mapping: RefCell<LinearMap<u32>> =
168+
RefCell::new(LinearMap::default());
169+
let name_index_mapping: RefCell<LinearMap<u32>> =
170+
RefCell::new(LinearMap::default());
170171

171172
for item in self.children() {
172173
source_index_mapping.borrow_mut().clear();

src/helpers.rs

Lines changed: 44 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,15 @@
11
use arrayvec::ArrayVec;
2-
use rustc_hash::FxHashMap as HashMap;
32
use std::{
43
borrow::{BorrowMut, Cow},
54
cell::{OnceCell, RefCell},
65
rc::Rc,
76
};
87

8+
use rustc_hash::FxHashMap as HashMap;
9+
910
use crate::{
1011
encoder::create_encoder,
12+
linear_map::LinearMap,
1113
source::{Mapping, OriginalLocation},
1214
vlq::decode,
1315
with_indices::WithIndices,
@@ -16,7 +18,7 @@ use crate::{
1618

1719
// Adding this type because sourceContentLine not happy
1820
type InnerSourceContentLine<'a> =
19-
RefCell<HashMap<i64, Option<Rc<Vec<WithIndices<&'a str>>>>>>;
21+
RefCell<HashMap<u32, Option<Rc<Vec<WithIndices<&'a str>>>>>>;
2022

2123
pub fn get_map<'a, S: StreamChunks<'a>>(
2224
stream: &'a S,
@@ -776,7 +778,7 @@ impl<'a> SourceMapLineChunk<'a> {
776778
}
777779

778780
type InnerSourceIndexValueMapping<'a> =
779-
HashMap<i64, (Cow<'a, str>, Option<&'a str>)>;
781+
LinearMap<(Cow<'a, str>, Option<&'a str>)>;
780782

781783
#[allow(clippy::too_many_arguments)]
782784
pub fn stream_chunks_of_combined_source_map<'a>(
@@ -796,27 +798,28 @@ pub fn stream_chunks_of_combined_source_map<'a>(
796798
let source_mapping: RefCell<HashMap<Cow<str>, u32>> =
797799
RefCell::new(HashMap::default());
798800
let mut name_mapping: HashMap<Cow<str>, u32> = HashMap::default();
799-
let source_index_mapping: RefCell<HashMap<i64, i64>> =
800-
RefCell::new(HashMap::default());
801-
let name_index_mapping: RefCell<HashMap<i64, i64>> =
802-
RefCell::new(HashMap::default());
803-
let name_index_value_mapping: RefCell<HashMap<i64, Cow<str>>> =
804-
RefCell::new(HashMap::default());
801+
let source_index_mapping: RefCell<LinearMap<i64>> =
802+
RefCell::new(LinearMap::default());
803+
let name_index_mapping: RefCell<LinearMap<i64>> =
804+
RefCell::new(LinearMap::default());
805+
let name_index_value_mapping: RefCell<LinearMap<Cow<str>>> =
806+
RefCell::new(LinearMap::default());
805807
let inner_source_index: RefCell<i64> = RefCell::new(-2);
806-
let inner_source_index_mapping: RefCell<HashMap<i64, i64>> =
807-
RefCell::new(HashMap::default());
808+
let inner_source_index_mapping: RefCell<LinearMap<i64>> =
809+
RefCell::new(LinearMap::default());
808810
let inner_source_index_value_mapping: RefCell<InnerSourceIndexValueMapping> =
809-
RefCell::new(HashMap::default());
810-
let inner_source_contents: RefCell<HashMap<i64, Option<&str>>> =
811-
RefCell::new(HashMap::default());
811+
RefCell::new(LinearMap::default());
812+
let inner_source_contents: RefCell<LinearMap<Option<&str>>> =
813+
RefCell::new(LinearMap::default());
812814
let inner_source_content_lines: InnerSourceContentLine =
813815
RefCell::new(HashMap::default());
814-
let inner_name_index_mapping: RefCell<HashMap<i64, i64>> =
815-
RefCell::new(HashMap::default());
816-
let inner_name_index_value_mapping: RefCell<HashMap<i64, Cow<str>>> =
817-
RefCell::new(HashMap::default());
816+
let inner_name_index_mapping: RefCell<LinearMap<i64>> =
817+
RefCell::new(LinearMap::default());
818+
let inner_name_index_value_mapping: RefCell<LinearMap<Cow<str>>> =
819+
RefCell::new(LinearMap::default());
818820
let inner_source_map_line_data: RefCell<Vec<SourceMapLineData>> =
819821
RefCell::new(Vec::new());
822+
820823
let find_inner_mapping = |line: i64, column: i64| -> Option<u32> {
821824
let inner_source_map_line_data = inner_source_map_line_data.borrow();
822825
if line as usize > inner_source_map_line_data.len() {
@@ -864,6 +867,8 @@ pub fn stream_chunks_of_combined_source_map<'a>(
864867

865868
// Check if this is a mapping to the inner source
866869
if source_index == *inner_source_index.borrow() {
870+
let source_index = source_index as u32;
871+
867872
// Check if there is a mapping in the inner source
868873
if let Some(idx) = find_inner_mapping(original_line, original_column) {
869874
let idx = idx as usize;
@@ -877,6 +882,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
877882
let mut inner_original_column = mappings_data[mi + 3];
878883
let mut inner_name_index = mappings_data[mi + 4];
879884
if inner_source_index >= 0 {
885+
let inner_source_index = inner_source_index as u32;
880886
// Check for an identity mapping
881887
// where we are allowed to adjust the original column
882888
let inner_chunk = &chunks[idx];
@@ -953,6 +959,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
953959
// emit name when needed and compute global name index
954960
let mut final_name_index = -1;
955961
if inner_name_index >= 0 {
962+
let inner_name_index = inner_name_index as u32;
956963
// when we have a inner name
957964
let mut inner_name_index_mapping =
958965
inner_name_index_mapping.borrow_mut();
@@ -980,6 +987,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
980987
.insert(inner_name_index, final_name_index);
981988
}
982989
} else if name_index >= 0 {
990+
let name_index = name_index as u32;
983991
// when we don't have an inner name,
984992
// but we have an outer name
985993
// it can be used when inner original code equals to the name
@@ -1094,11 +1102,16 @@ pub fn stream_chunks_of_combined_source_map<'a>(
10941102
}
10951103
}
10961104

1097-
let final_source_index = source_index_mapping
1098-
.borrow()
1099-
.get(&source_index)
1100-
.copied()
1101-
.unwrap_or(-1);
1105+
let final_source_index = if source_index < 0 {
1106+
-1
1107+
} else {
1108+
let source_index = source_index as u32;
1109+
source_index_mapping
1110+
.borrow()
1111+
.get(&source_index)
1112+
.copied()
1113+
.unwrap_or(-1)
1114+
};
11021115
if final_source_index < 0 {
11031116
// no source, so we make it a generated chunk
11041117
on_chunk(
@@ -1112,9 +1125,14 @@ pub fn stream_chunks_of_combined_source_map<'a>(
11121125
} else {
11131126
// Pass through the chunk with mapping
11141127
let mut name_index_mapping = name_index_mapping.borrow_mut();
1115-
let mut final_name_index =
1116-
name_index_mapping.get(&name_index).copied().unwrap_or(-1);
1128+
let mut final_name_index = if name_index >= 0 {
1129+
let name_index = name_index as u32;
1130+
name_index_mapping.get(&name_index).copied().unwrap_or(-1)
1131+
} else {
1132+
-1
1133+
};
11171134
if final_name_index == -2 {
1135+
let name_index = name_index as u32;
11181136
let name_index_value_mapping = name_index_value_mapping.borrow();
11191137
let name = name_index_value_mapping.get(&name_index).unwrap();
11201138
let mut global_index = name_mapping.get(name).copied();
@@ -1144,9 +1162,8 @@ pub fn stream_chunks_of_combined_source_map<'a>(
11441162
}
11451163
},
11461164
&mut |i, source, mut source_content| {
1147-
let i = i as i64;
11481165
if source == inner_source_name {
1149-
*inner_source_index.borrow_mut() = i;
1166+
*inner_source_index.borrow_mut() = i as i64;
11501167
let mut inner_source = inner_source.borrow_mut();
11511168
if let Some(inner_source) = inner_source.as_ref() {
11521169
source_content = Some(inner_source);
@@ -1210,7 +1227,6 @@ pub fn stream_chunks_of_combined_source_map<'a>(
12101227
data.chunks.push(chunk);
12111228
},
12121229
&mut |i, source, source_content| {
1213-
let i = i as i64;
12141230
inner_source_contents
12151231
.borrow_mut()
12161232
.insert(i, source_content.map(Into::into));
@@ -1221,7 +1237,6 @@ pub fn stream_chunks_of_combined_source_map<'a>(
12211237
.insert(i, (source, source_content));
12221238
},
12231239
&mut |i, name| {
1224-
let i = i as i64;
12251240
inner_name_index_mapping.borrow_mut().insert(i, -2);
12261241
inner_name_index_value_mapping.borrow_mut().insert(i, name);
12271242
},
@@ -1245,7 +1260,6 @@ pub fn stream_chunks_of_combined_source_map<'a>(
12451260
}
12461261
},
12471262
&mut |i, name| {
1248-
let i = i as i64;
12491263
name_index_mapping.borrow_mut().insert(i, -2);
12501264
name_index_value_mapping.borrow_mut().insert(i, name);
12511265
},

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ mod concat_source;
55
mod encoder;
66
mod error;
77
mod helpers;
8+
mod linear_map;
89
mod original_source;
910
mod raw_source;
1011
mod replace_source;

src/linear_map.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
pub struct LinearMap<V: Default> {
2+
inner: Vec<V>,
3+
}
4+
5+
impl<V: Default> LinearMap<V> {
6+
pub fn new() -> Self {
7+
Self {
8+
inner: Default::default(),
9+
}
10+
}
11+
12+
pub fn get(&self, key: &u32) -> Option<&V> {
13+
self.inner.get(*key as usize)
14+
}
15+
16+
pub fn insert(&mut self, key: u32, value: V) {
17+
let key = key as usize;
18+
if key >= self.inner.len() {
19+
self.inner.resize_with(key + 1, Default::default);
20+
}
21+
self.inner[key] = value;
22+
}
23+
24+
pub fn clear(&mut self) {
25+
self.inner.clear()
26+
}
27+
}
28+
29+
impl<V: Default> Default for LinearMap<V> {
30+
fn default() -> Self {
31+
Self::new()
32+
}
33+
}

src/replace_source.rs

Lines changed: 11 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ use rustc_hash::FxHashMap as HashMap;
1212

1313
use crate::{
1414
helpers::{get_map, split_into_lines, GeneratedInfo, StreamChunks},
15+
linear_map::LinearMap,
1516
MapOptions, Mapping, OriginalLocation, Source, SourceMap,
1617
};
1718

@@ -273,11 +274,12 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
273274
let mut generated_line_offset: i64 = 0;
274275
let mut generated_column_offset: i64 = 0;
275276
let mut generated_column_offset_line = 0;
276-
let source_content_lines: RefCell<Vec<Option<Vec<&str>>>> =
277-
RefCell::new(Vec::new());
277+
let source_content_lines: RefCell<LinearMap<Option<Vec<&str>>>> =
278+
RefCell::new(LinearMap::default());
278279
let name_mapping: RefCell<HashMap<Cow<str>, u32>> =
279280
RefCell::new(HashMap::default());
280-
let name_index_mapping: RefCell<Vec<u32>> = RefCell::new(Vec::new());
281+
let name_index_mapping: RefCell<LinearMap<u32>> =
282+
RefCell::new(LinearMap::default());
281283

282284
// check if source_content[line][col] is equal to expect
283285
// Why this is needed?
@@ -308,7 +310,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
308310
let check_original_content =
309311
|source_index: u32, line: u32, column: u32, expected_chunk: &str| {
310312
if let Some(Some(content_lines)) =
311-
source_content_lines.borrow().get(source_index as usize)
313+
source_content_lines.borrow().get(&source_index)
312314
{
313315
if let Some(content_line) = content_lines.get(line as usize - 1) {
314316
match content_line
@@ -411,10 +413,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
411413
original_line: original.original_line,
412414
original_column: original.original_column,
413415
name_index: original.name_index.and_then(|name_index| {
414-
name_index_mapping
415-
.borrow()
416-
.get(name_index as usize)
417-
.copied()
416+
name_index_mapping.borrow().get(&name_index).copied()
418417
}),
419418
}
420419
}),
@@ -589,10 +588,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
589588
original_line: original.original_line,
590589
original_column: original.original_column,
591590
name_index: original.name_index.and_then(|name_index| {
592-
name_index_mapping
593-
.borrow()
594-
.get(name_index as usize)
595-
.copied()
591+
name_index_mapping.borrow().get(&name_index).copied()
596592
}),
597593
}
598594
}),
@@ -603,11 +599,9 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
603599
},
604600
&mut |source_index, source, source_content| {
605601
let mut source_content_lines = source_content_lines.borrow_mut();
606-
while source_content_lines.len() <= source_index as usize {
607-
source_content_lines.push(None);
608-
}
609-
source_content_lines[source_index as usize] = source_content
602+
let lines = source_content
610603
.map(|source_content| split_into_lines(source_content).collect());
604+
source_content_lines.insert(source_index, lines);
611605
on_source(source_index, source, source_content);
612606
},
613607
&mut |name_index, name| {
@@ -621,7 +615,7 @@ impl<'a, T: Source> StreamChunks<'a> for ReplaceSource<T> {
621615
}
622616
name_index_mapping
623617
.borrow_mut()
624-
.insert(name_index as usize, global_index.unwrap());
618+
.insert(name_index, global_index.unwrap());
625619
},
626620
);
627621

0 commit comments

Comments
 (0)