Skip to content

Commit 6e4df5f

Browse files
committed
perf: try remove Rc
1 parent da072e5 commit 6e4df5f

File tree

2 files changed

+56
-48
lines changed

2 files changed

+56
-48
lines changed

src/replace_source.rs

+33-22
Original file line numberDiff line numberDiff line change
@@ -302,7 +302,7 @@ fn check_content_at_position(
302302
lines: &[Rope],
303303
line: u32,
304304
column: u32,
305-
expected: Rope, // FIXME: memory
305+
expected: &Rope,
306306
) -> bool {
307307
if let Some(line) = lines.get(line as usize - 1) {
308308
match line
@@ -311,7 +311,7 @@ fn check_content_at_position(
311311
.map(|(byte_index, _)| byte_index)
312312
{
313313
Some(byte_index) => {
314-
line.get_byte_slice(byte_index..byte_index + expected.len())
314+
line.get_byte_slice(byte_index..byte_index + expected.len()).as_ref()
315315
== Some(expected)
316316
}
317317
None => false,
@@ -372,7 +372,7 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
372372
// In this case, we can't split this mapping.
373373
// webpack-sources also have this function, refer https://github.com/webpack/webpack-sources/blob/main/lib/ReplaceSource.js#L158
374374
let check_original_content =
375-
|source_index: u32, line: u32, column: u32, expected_chunk: Rope| {
375+
|source_index: u32, line: u32, column: u32, expected_chunk: &Rope| {
376376
if let Some(Some(source_content)) =
377377
source_content_lines.borrow_mut().get_mut(&source_index)
378378
{
@@ -432,7 +432,7 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
432432
original.source_index,
433433
original.original_line,
434434
original.original_column,
435-
chunk.byte_slice(0..chunk_pos as usize),
435+
&chunk.byte_slice(0..chunk_pos as usize),
436436
)
437437
}) {
438438
original.original_column += chunk_pos;
@@ -458,8 +458,24 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
458458
let offset = next_replacement_pos - pos;
459459
let chunk_slice = chunk
460460
.byte_slice(chunk_pos as usize..(chunk_pos + offset) as usize);
461+
462+
let new_original_column = if let Some(original) =
463+
mapping.original.as_mut().filter(|original| {
464+
check_original_content(
465+
original.source_index,
466+
original.original_line,
467+
original.original_column,
468+
&chunk_slice,
469+
)
470+
})
471+
{
472+
Some(original.original_column + chunk_slice.len() as u32)
473+
} else {
474+
None
475+
};
476+
461477
on_chunk(
462-
Some(chunk_slice.clone()),
478+
Some(chunk_slice),
463479
Mapping {
464480
generated_line: line as u32,
465481
generated_column: ((mapping.generated_column as i64)
@@ -483,17 +499,9 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
483499
mapping.generated_column += offset;
484500
chunk_pos += offset;
485501
pos = next_replacement_pos;
486-
if let Some(original) =
487-
mapping.original.as_mut().filter(|original| {
488-
check_original_content(
489-
original.source_index,
490-
original.original_line,
491-
original.original_column,
492-
chunk_slice.clone(),
493-
)
494-
})
495-
{
496-
original.original_column += chunk_slice.len() as u32;
502+
503+
if let Some(new_original_column) = new_original_column {
504+
mapping.original.as_mut().unwrap().original_column = new_original_column;
497505
}
498506
}
499507
// Insert replacement content split into chunks by lines
@@ -611,7 +619,7 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
611619
original.source_index,
612620
original.original_line,
613621
original.original_column,
614-
chunk.byte_slice(
622+
&chunk.byte_slice(
615623
chunk_pos as usize..(chunk_pos + offset as u32) as usize,
616624
),
617625
)
@@ -695,9 +703,12 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
695703
// Insert remaining replacements content split into chunks by lines
696704
let mut line = result.generated_line as i64 + generated_line_offset;
697705
let matches: Vec<Rope> = split_into_lines(&remainder).collect();
698-
for (m, content_line) in matches.iter().enumerate() {
706+
let matches_len = matches.len();
707+
for (m, content_line) in matches.into_iter().enumerate() {
708+
let ends_with_newline = content_line.ends_with("\n");
709+
let content_line_len = content_line.len();
699710
on_chunk(
700-
Some(content_line.clone()),
711+
Some(content_line),
701712
Mapping {
702713
generated_line: line as u32,
703714
generated_column: ((result.generated_column as i64)
@@ -710,11 +721,11 @@ impl<T: Source> StreamChunks for ReplaceSource<T> {
710721
},
711722
);
712723

713-
if m == matches.len() - 1 && !content_line.ends_with("\n") {
724+
if m == matches_len - 1 && !ends_with_newline {
714725
if generated_column_offset_line == line {
715-
generated_column_offset += content_line.len() as i64;
726+
generated_column_offset += content_line_len as i64;
716727
} else {
717-
generated_column_offset = content_line.len() as i64;
728+
generated_column_offset = content_line_len as i64;
718729
generated_column_offset_line = line;
719730
}
720731
} else {

src/rope.rs

+23-26
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,14 @@ use std::{
66
collections::VecDeque,
77
hash::Hash,
88
ops::{Bound, RangeBounds},
9-
rc::Rc,
109
};
1110

1211
use crate::Error;
1312

1413
#[derive(Clone, Debug)]
1514
pub(crate) enum Repr<'a> {
1615
Light(&'a str),
17-
Full(Rc<Vec<(&'a str, usize)>>),
16+
Full(Vec<(&'a str, usize)>),
1817
}
1918

2019
/// A rope data structure.
@@ -43,13 +42,13 @@ impl<'a> Rope<'a> {
4342
match &mut self.repr {
4443
Repr::Light(s) => {
4544
let vec = Vec::from_iter([(*s, 0), (value, s.len())]);
46-
self.repr = Repr::Full(Rc::new(vec));
45+
self.repr = Repr::Full(vec);
4746
}
4847
Repr::Full(data) => {
4948
let len = data
5049
.last()
5150
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
52-
Rc::make_mut(data).push((value, len));
51+
data.push((value, len));
5352
}
5453
}
5554
}
@@ -61,15 +60,15 @@ impl<'a> Rope<'a> {
6160
match (&mut self.repr, value.repr) {
6261
(Repr::Light(s), Repr::Light(other)) => {
6362
let raw = Vec::from_iter([(*s, 0), (other, s.len())]);
64-
self.repr = Repr::Full(Rc::new(raw));
63+
self.repr = Repr::Full(raw);
6564
}
6665
(Repr::Full(s), Repr::Full(other)) => {
6766
if !other.is_empty() {
6867
let mut len = s
6968
.last()
7069
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
7170

72-
let cur = Rc::make_mut(s);
71+
let cur = s;
7372
cur.reserve_exact(other.len());
7473

7574
for &(chunk, _) in other.iter() {
@@ -83,7 +82,7 @@ impl<'a> Rope<'a> {
8382
let len = s
8483
.last()
8584
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
86-
Rc::make_mut(s).push((other, len));
85+
s.push((other, len));
8786
}
8887
}
8988
(Repr::Light(s), Repr::Full(other)) => {
@@ -94,7 +93,7 @@ impl<'a> Rope<'a> {
9493
raw.push((chunk, len));
9594
len += chunk.len();
9695
}
97-
self.repr = Repr::Full(Rc::new(raw));
96+
self.repr = Repr::Full(raw);
9897
}
9998
}
10099
}
@@ -325,7 +324,7 @@ impl<'a> Rope<'a> {
325324
})?;
326325

327326
Ok(Rope {
328-
repr: Repr::Full(Rc::new(raw)),
327+
repr: Repr::Full(raw),
329328
})
330329
}
331330
}
@@ -413,7 +412,7 @@ impl<'a> Rope<'a> {
413412
});
414413

415414
Rope {
416-
repr: Repr::Full(Rc::new(raw)),
415+
repr: Repr::Full(raw),
417416
}
418417
}
419418
}
@@ -614,7 +613,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
614613
// Advance the byte index to the end of the line.
615614
*byte_idx += len;
616615
Some(Rope {
617-
repr: Repr::Full(Rc::new(raw)),
616+
repr: Repr::Full(raw),
618617
})
619618
} else {
620619
// If we did not find a newline in the next few chunks,
@@ -646,7 +645,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
646645
// Advance the byte index to the end of the rope.
647646
*byte_idx += len;
648647
Some(Rope {
649-
repr: Repr::Full(Rc::new(raw)),
648+
repr: Repr::Full(raw),
650649
})
651650
}
652651
}
@@ -864,7 +863,7 @@ impl<'a> FromIterator<&'a str> for Rope<'a> {
864863
.collect::<Vec<_>>();
865864

866865
Self {
867-
repr: Repr::Full(Rc::new(raw)),
866+
repr: Repr::Full(raw),
868867
}
869868
}
870869
}
@@ -889,8 +888,6 @@ fn end_bound_to_range_end(end: Bound<&usize>) -> Option<usize> {
889888

890889
#[cfg(test)]
891890
mod tests {
892-
use std::rc::Rc;
893-
894891
use crate::rope::{Repr, Rope};
895892

896893
impl<'a> PartialEq for Repr<'a> {
@@ -915,19 +912,19 @@ mod tests {
915912
assert_eq!(simple, "abcdef");
916913
assert_eq!(
917914
simple.repr,
918-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3)])))
915+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3)]))
919916
);
920917
assert_eq!(simple.len(), 6);
921918

922919
simple.add("ghi");
923920
assert_eq!(simple, "abcdefghi");
924921
assert_eq!(
925922
simple.repr,
926-
Repr::Full(Rc::new(Vec::from_iter([
923+
Repr::Full(Vec::from_iter([
927924
("abc", 0),
928925
("def", 3),
929926
("ghi", 6),
930-
])))
927+
]))
931928
);
932929
assert_eq!(simple.len(), 9);
933930
}
@@ -946,7 +943,7 @@ mod tests {
946943
assert_eq!(append1, "abcdef");
947944
assert_eq!(
948945
append1.repr,
949-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3),])))
946+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3),]))
950947
);
951948

952949
// simple - complex
@@ -955,12 +952,12 @@ mod tests {
955952
assert_eq!(append2, "abc123");
956953
assert_eq!(
957954
append2.repr,
958-
Repr::Full(Rc::new(Vec::from_iter([
955+
Repr::Full(Vec::from_iter([
959956
("abc", 0),
960957
("1", 3),
961958
("2", 4),
962959
("3", 5),
963-
])))
960+
]))
964961
);
965962

966963
// complex - simple
@@ -969,12 +966,12 @@ mod tests {
969966
assert_eq!(append3, "123abc");
970967
assert_eq!(
971968
append3.repr,
972-
Repr::Full(Rc::new(Vec::from_iter([
969+
Repr::Full(Vec::from_iter([
973970
("1", 0),
974971
("2", 1),
975972
("3", 2),
976973
("abc", 3),
977-
])))
974+
]))
978975
);
979976

980977
// complex - complex
@@ -983,14 +980,14 @@ mod tests {
983980
assert_eq!(append4, "123456");
984981
assert_eq!(
985982
append4.repr,
986-
Repr::Full(Rc::new(Vec::from_iter([
983+
Repr::Full(Vec::from_iter([
987984
("1", 0),
988985
("2", 1),
989986
("3", 2),
990987
("4", 3),
991988
("5", 4),
992989
("6", 5),
993-
])))
990+
]))
994991
);
995992
}
996993

@@ -1071,7 +1068,7 @@ mod tests {
10711068
assert_eq!(rope, "abcdef");
10721069
assert_eq!(
10731070
rope.repr,
1074-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3)])))
1071+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3)]))
10751072
);
10761073
}
10771074

0 commit comments

Comments
 (0)