Skip to content

Commit 5d7b5f5

Browse files
committed
perf: memory pool
1 parent 42b4f9f commit 5d7b5f5

File tree

8 files changed

+148
-44
lines changed

8 files changed

+148
-44
lines changed

src/cached_source.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -301,10 +301,7 @@ mod tests {
301301

302302
#[test]
303303
fn should_produce_correct_output_for_cached_raw_source() {
304-
let map_options = MapOptions {
305-
columns: true,
306-
final_source: true,
307-
};
304+
let map_options = MapOptions::new(true);
308305

309306
let source = RawStringSource::from("Test\nTest\nTest\n");
310307
let mut on_chunk_count = 0;

src/helpers.rs

Lines changed: 14 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,13 @@ use std::{
22
borrow::{BorrowMut, Cow},
33
cell::{OnceCell, RefCell},
44
marker::PhantomData,
5-
ops::Range,
5+
ops::Range, rc::Rc,
66
};
77

88
use rustc_hash::FxHashMap as HashMap;
99

1010
use crate::{
11-
decoder::MappingsDecoder,
12-
encoder::create_encoder,
13-
linear_map::LinearMap,
14-
source::{Mapping, OriginalLocation},
15-
with_indices::WithIndices,
16-
MapOptions, Rope, SourceMap,
11+
decoder::MappingsDecoder, encoder::create_encoder, linear_map::LinearMap, source::{Mapping, OriginalLocation}, with_indices::WithIndices, work_context::{self, WorkContext}, MapOptions, Rope, SourceMap
1712
};
1813

1914
// Adding this type because sourceContentLine not happy
@@ -33,6 +28,7 @@ pub fn get_map<'a, S: StreamChunks>(
3328
&MapOptions {
3429
columns: options.columns,
3530
final_source: true,
31+
work_context: options.work_context.clone(),
3632
},
3733
// on_chunk
3834
&mut |_, mapping| {
@@ -317,24 +313,28 @@ where
317313
MapOptions {
318314
columns: true,
319315
final_source: true,
316+
..
320317
} => stream_chunks_of_source_map_final(
321318
source, source_map, on_chunk, on_source, on_name,
322319
),
323320
MapOptions {
324321
columns: true,
325322
final_source: false,
323+
work_context
326324
} => stream_chunks_of_source_map_full(
327-
source, source_map, on_chunk, on_source, on_name,
325+
work_context.clone(), source, source_map, on_chunk, on_source, on_name,
328326
),
329327
MapOptions {
330328
columns: false,
331329
final_source: true,
330+
..
332331
} => stream_chunks_of_source_map_lines_final(
333332
source, source_map, on_chunk, on_source, on_name,
334333
),
335334
MapOptions {
336335
columns: false,
337336
final_source: false,
337+
..
338338
} => stream_chunks_of_source_map_lines_full(
339339
source, source_map, on_chunk, on_source, on_name,
340340
),
@@ -413,6 +413,7 @@ where
413413
}
414414

415415
fn stream_chunks_of_source_map_full<'a, S>(
416+
work_context: Rc<WorkContext>,
416417
source: S,
417418
source_map: &'a SourceMap,
418419
on_chunk: OnChunk<'_, 'a>,
@@ -423,7 +424,7 @@ where
423424
S: SourceText<'a> + 'a,
424425
{
425426
let lines = split_into_lines(&source);
426-
let line_with_indices_list = lines.map(WithIndices::new).collect::<Vec<_>>();
427+
let line_with_indices_list = lines.map(|line| WithIndices::new(work_context.clone(), line)).collect::<Vec<_>>();
427428

428429
if line_with_indices_list.is_empty() {
429430
return GeneratedInfo {
@@ -710,6 +711,7 @@ type InnerSourceIndexValueMapping<'a> =
710711

711712
#[allow(clippy::too_many_arguments)]
712713
pub fn stream_chunks_of_combined_source_map<'a, S>(
714+
work_context: Rc<WorkContext>,
713715
source: S,
714716
source_map: &'a SourceMap,
715717
inner_source_name: &'a str,
@@ -830,7 +832,7 @@ where
830832
match inner_source_contents.get(&inner_source_index) {
831833
Some(Some(source_content)) => Some(
832834
split_into_lines(source_content)
833-
.map(WithIndices::new)
835+
.map(|line| WithIndices::new(work_context.clone(), line))
834836
.collect(),
835837
),
836838
_ => None,
@@ -930,7 +932,7 @@ where
930932
match inner_source_contents.get(&inner_source_index) {
931933
Some(Some(source_content)) => Some(
932934
split_into_lines(source_content)
933-
.map(WithIndices::new)
935+
.map(|line| WithIndices::new(work_context.clone(), line))
934936
.collect(),
935937
),
936938
_ => None,
@@ -1167,6 +1169,7 @@ where
11671169
&MapOptions {
11681170
columns: options.columns,
11691171
final_source: false,
1172+
work_context: options.work_context.clone(),
11701173
},
11711174
);
11721175
} else {

src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ mod rope;
1414
mod source;
1515
mod source_map_source;
1616
mod with_indices;
17+
mod work_context;
1718

1819
pub use cached_source::CachedSource;
1920
pub use concat_source::ConcatSource;

src/replace_source.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -391,7 +391,7 @@ impl StreamChunks for ReplaceSource {
391391
match source_content {
392392
SourceContent::Raw(source) => {
393393
let lines = split_into_lines(source)
394-
.map(WithIndices::new)
394+
.map(|line| WithIndices::new(options.work_context.clone(), line))
395395
.collect::<Vec<_>>();
396396
let matched =
397397
check_content_at_position(&lines, line, column, expected_chunk);
@@ -411,6 +411,7 @@ impl StreamChunks for ReplaceSource {
411411
&MapOptions {
412412
columns: options.columns,
413413
final_source: false,
414+
work_context: options.work_context.clone()
414415
},
415416
&mut |chunk, mut mapping| {
416417
// SAFETY: final_source is false in ReplaceSource

src/source.rs

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,12 @@
11
use std::{
2-
any::{Any, TypeId},
3-
borrow::Cow,
4-
convert::{TryFrom, TryInto},
5-
fmt,
6-
hash::{Hash, Hasher},
7-
sync::Arc,
2+
any::{Any, TypeId}, borrow::Cow, collections::BinaryHeap, convert::{TryFrom, TryInto}, fmt, hash::{Hash, Hasher}, rc::Rc, sync::Arc
83
};
94

105
use dyn_clone::DynClone;
116
use serde::{Deserialize, Serialize};
127

138
use crate::{
14-
helpers::{decode_mappings, StreamChunks},
15-
rope::Rope,
16-
Result,
9+
helpers::{decode_mappings, StreamChunks}, rope::Rope, work_context::WorkContext, Result
1710
};
1811

1912
/// An alias for `Box<dyn Source>`.
@@ -250,19 +243,36 @@ impl<T: Source + 'static> SourceExt for T {
250243
}
251244

252245
/// Options for [Source::map].
253-
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
246+
#[derive(Debug, Clone)]
254247
pub struct MapOptions {
255248
/// Whether have columns info in generated [SourceMap] mappings.
256249
pub columns: bool,
257250
/// Whether the source will have changes, internal used for `ReplaceSource`, etc.
258251
pub(crate) final_source: bool,
252+
pub(crate) work_context: Rc<WorkContext>,
253+
}
254+
255+
impl PartialEq for MapOptions {
256+
fn eq(&self, other: &Self) -> bool {
257+
self.columns == other.columns && self.final_source == other.final_source
258+
}
259+
}
260+
261+
impl Eq for MapOptions {}
262+
263+
impl Hash for MapOptions {
264+
fn hash<H: Hasher>(&self, state: &mut H) {
265+
self.columns.hash(state);
266+
self.final_source.hash(state);
267+
}
259268
}
260269

261270
impl Default for MapOptions {
262271
fn default() -> Self {
263272
Self {
264273
columns: true,
265274
final_source: false,
275+
work_context: Default::default()
266276
}
267277
}
268278
}

src/source_map_source.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ impl StreamChunks for SourceMapSource {
191191
) -> crate::helpers::GeneratedInfo {
192192
if let Some(inner_source_map) = &self.inner_source_map {
193193
stream_chunks_of_combined_source_map(
194+
options.work_context.clone(),
194195
&*self.value,
195196
&self.source_map,
196197
&self.name,
@@ -469,10 +470,7 @@ mod tests {
469470
.into_string_lossy()
470471
.into_owned());
471472
test_cached!(source, |s: &dyn Source| s.map(&MapOptions::default()));
472-
test_cached!(source, |s: &dyn Source| s.map(&MapOptions {
473-
columns: false,
474-
final_source: true
475-
}));
473+
test_cached!(source, |s: &dyn Source| s.map(&MapOptions::new(false)));
476474
}
477475

478476
#[test]

src/with_indices.rs

Lines changed: 22 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
1-
use std::{cell::OnceCell, marker::PhantomData};
1+
use std::{cell::OnceCell, marker::PhantomData, rc::Rc};
22

3-
use crate::helpers::SourceText;
3+
use crate::{helpers::SourceText, work_context::{PooledVec, WorkContext}};
44

5-
#[derive(Debug, Clone)]
5+
#[derive(Debug)]
66
pub struct WithIndices<'a, S>
77
where
88
S: SourceText<'a>,
99
{
1010
/// line is a string reference
1111
pub line: S,
1212
/// the byte position of each `char` in `line` string slice .
13-
pub indices_indexes: OnceCell<Vec<usize>>,
13+
pub indices_indexes: OnceCell<PooledVec>,
14+
work_context: Rc<WorkContext>,
1415
data: PhantomData<&'a S>,
1516
}
1617

1718
impl<'a, S> WithIndices<'a, S>
1819
where
1920
S: SourceText<'a>,
2021
{
21-
pub fn new(line: S) -> Self {
22+
pub fn new(work_context: Rc<WorkContext>, line: S) -> Self {
2223
Self {
2324
indices_indexes: OnceCell::new(),
2425
line,
26+
work_context,
2527
data: PhantomData,
2628
}
2729
}
@@ -32,8 +34,12 @@ where
3234
return S::default();
3335
}
3436

35-
let indices_indexes = self.indices_indexes.get_or_init(|| {
36-
self.line.char_indices().map(|(i, _)| i).collect::<Vec<_>>()
37+
let indices_indexes = &*self.indices_indexes.get_or_init(|| {
38+
let mut vec = PooledVec::new(self.work_context.clone(), self.line.len());
39+
for (i, _) in self.line.char_indices() {
40+
vec.push(i);
41+
}
42+
vec
3743
});
3844

3945
let str_len = self.line.len();
@@ -53,40 +59,42 @@ where
5359
/// tests are just copy from `substring` crate
5460
#[cfg(test)]
5561
mod tests {
56-
use crate::Rope;
62+
use std::rc::Rc;
63+
64+
use crate::{work_context::WorkContext, Rope};
5765

5866
use super::WithIndices;
5967
#[test]
6068
fn test_substring() {
6169
assert_eq!(
62-
WithIndices::new(Rope::from("foobar")).substring(0, 3),
70+
WithIndices::new(Rc::new(WorkContext::default()), Rope::from("foobar")).substring(0, 3),
6371
"foo"
6472
);
6573
}
6674

6775
#[test]
6876
fn test_out_of_bounds() {
6977
assert_eq!(
70-
WithIndices::new(Rope::from("foobar")).substring(0, 10),
78+
WithIndices::new(Rc::new(WorkContext::default()), Rope::from("foobar")).substring(0, 10),
7179
"foobar"
7280
);
73-
assert_eq!(WithIndices::new(Rope::from("foobar")).substring(6, 10), "");
81+
assert_eq!(WithIndices::new(Rc::new(WorkContext::default()), Rope::from("foobar")).substring(6, 10), "");
7482
}
7583

7684
#[test]
7785
fn test_start_less_than_end() {
78-
assert_eq!(WithIndices::new(Rope::from("foobar")).substring(3, 2), "");
86+
assert_eq!(WithIndices::new(Rc::new(WorkContext::default()), Rope::from("foobar")).substring(3, 2), "");
7987
}
8088

8189
#[test]
8290
fn test_start_and_end_equal() {
83-
assert_eq!(WithIndices::new(Rope::from("foobar")).substring(3, 3), "");
91+
assert_eq!(WithIndices::new(Rc::new(WorkContext::default()), Rope::from("foobar")).substring(3, 3), "");
8492
}
8593

8694
#[test]
8795
fn test_multiple_byte_characters() {
8896
assert_eq!(
89-
WithIndices::new(Rope::from("fõøbα®")).substring(2, 5),
97+
WithIndices::new(Rc::new(WorkContext::default()), Rope::from("fõøbα®")).substring(2, 5),
9098
"øbα"
9199
);
92100
}

0 commit comments

Comments
 (0)