Skip to content

Commit 44298da

Browse files
committed
use Rope to perf-n
1 parent edddae1 commit 44298da

File tree

6 files changed

+131
-94
lines changed

6 files changed

+131
-94
lines changed

src/helpers.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ use crate::{
1313
linear_map::LinearMap,
1414
source::{Mapping, OriginalLocation},
1515
with_indices::WithIndices,
16-
MapOptions, Rope, SourceMap,
16+
MapOptions, Rope, SourceMap, StringCell,
1717
};
1818

1919
// Adding this type because sourceContentLine not happy
@@ -26,7 +26,7 @@ pub fn get_map<'a, S: StreamChunks>(
2626
) -> Option<SourceMap<'a>> {
2727
let mut mappings_encoder = create_encoder(options.columns);
2828
let mut sources: Vec<Cow<str>> = Vec::new();
29-
let mut sources_content: Vec<Cow<str>> = Vec::new();
29+
let mut sources_content: Vec<StringCell<'a>> = Vec::new();
3030
let mut names: Vec<Cow<str>> = Vec::new();
3131

3232
stream.stream_chunks(
@@ -49,8 +49,7 @@ pub fn get_map<'a, S: StreamChunks>(
4949
if sources_content.len() <= source_index {
5050
sources_content.resize(source_index + 1, "".into());
5151
}
52-
// TODO: avoid to_string allocation
53-
sources_content[source_index] = Cow::Owned(source_content.to_string());
52+
sources_content[source_index] = source_content.into();
5453
}
5554
},
5655
// on_name
@@ -1201,7 +1200,7 @@ pub fn stream_and_get_source_and_map<'a, S: StreamChunks>(
12011200
) -> (GeneratedInfo, Option<SourceMap<'a>>) {
12021201
let mut mappings_encoder = create_encoder(options.columns);
12031202
let mut sources: Vec<Cow<'a, str>> = Vec::new();
1204-
let mut sources_content: Vec<Cow<'static, str>> = Vec::new();
1203+
let mut sources_content: Vec<StringCell<'a>> = Vec::new();
12051204
let mut names: Vec<Cow<'a, str>> = Vec::new();
12061205

12071206
let generated_info = input_source.stream_chunks(
@@ -1216,12 +1215,11 @@ pub fn stream_and_get_source_and_map<'a, S: StreamChunks>(
12161215
sources.push("".into());
12171216
}
12181217
sources[source_index2] = source.clone();
1219-
if let Some(ref source_content) = source_content {
1218+
if let Some(source_content) = &source_content {
12201219
while sources_content.len() <= source_index2 {
12211220
sources_content.push("".into());
12221221
}
1223-
// TODO: avoid allocation here
1224-
sources_content[source_index2] = Cow::Owned(source_content.to_string());
1222+
sources_content[source_index2] = source_content.clone().into();
12251223
}
12261224
on_source(source_index, source, source_content);
12271225
},

src/lib.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub use rope::Rope;
2626
pub use source::{
2727
BoxSource, MapOptions, Mapping, OriginalLocation, Source, SourceExt,
2828
};
29-
pub use source_map::SourceMap;
29+
pub use source_map::{SourceMap, StringCell};
3030
pub use source_map_source::{
3131
SourceMapSource, SourceMapSourceOptions, WithoutOriginalOptions,
3232
};

src/original_source.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,11 +252,11 @@ mod tests {
252252
assert_eq!(result_list_map.sources(), ["file.js".to_string()]);
253253
assert_eq!(
254254
result_map.sources_content(),
255-
["Line1\n\nLine3\n".to_string()],
255+
["Line1\n\nLine3\n".into()],
256256
);
257257
assert_eq!(
258258
result_list_map.sources_content(),
259-
["Line1\n\nLine3\n".to_string()],
259+
["Line1\n\nLine3\n".into()],
260260
);
261261
assert_eq!(result_map.mappings(), "AAAA;;AAEA");
262262
assert_eq!(result_list_map.mappings(), "AAAA;AACA;AACA");

src/replace_source.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1109,7 +1109,7 @@ function StaticPage(_ref) {
11091109
assert_eq!(source_map.get_name(1).unwrap(), "data");
11101110
assert_eq!(source_map.get_name(2).unwrap(), "foo");
11111111
assert_eq!(
1112-
source_map.get_source_content(0).unwrap(),
1112+
source_map.get_source_content(0).unwrap().to_string(),
11131113
r#"export default function StaticPage({ data }) {
11141114
return <div>{data.foo}</div>
11151115
}

src/rope.rs

Lines changed: 56 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ use std::{
88
rc::Rc,
99
};
1010

11-
use crate::Error;
11+
use serde::Serialize;
12+
13+
use crate::{Error, StringCell};
1214

1315
#[derive(Clone, Debug)]
1416
pub(crate) enum Repr<'a> {
1517
Light(&'a str),
16-
Full(Rc<Vec<(&'a str, usize)>>),
18+
Full(Vec<(&'a str, usize)>),
1719
}
1820

1921
/// A rope data structure.
@@ -22,6 +24,24 @@ pub struct Rope<'a> {
2224
repr: Repr<'a>,
2325
}
2426

27+
impl Serialize for Rope<'_> {
28+
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
29+
where
30+
S: serde::Serializer,
31+
{
32+
match &self.repr {
33+
Repr::Light(s) => serializer.serialize_str(s),
34+
Repr::Full(items) => {
35+
let mut out = String::with_capacity(self.len());
36+
for (s, _) in items.iter() {
37+
out.push_str(s);
38+
}
39+
serializer.serialize_str(&out)
40+
}
41+
}
42+
}
43+
}
44+
2545
impl<'a> Rope<'a> {
2646
/// Creates a new empty rope.
2747
pub const fn new() -> Self {
@@ -42,13 +62,13 @@ impl<'a> Rope<'a> {
4262
match &mut self.repr {
4363
Repr::Light(s) => {
4464
let vec = Vec::from_iter([(*s, 0), (value, s.len())]);
45-
self.repr = Repr::Full(Rc::new(vec));
65+
self.repr = Repr::Full(vec);
4666
}
4767
Repr::Full(data) => {
4868
let len = data
4969
.last()
5070
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
51-
Rc::make_mut(data).push((value, len));
71+
data.push((value, len));
5272
}
5373
}
5474
}
@@ -63,7 +83,7 @@ impl<'a> Rope<'a> {
6383
return;
6484
}
6585
let raw = Vec::from_iter([(*s, 0), (other, s.len())]);
66-
self.repr = Repr::Full(Rc::new(raw));
86+
self.repr = Repr::Full(raw);
6787
}
6888
(Repr::Full(s), Repr::Full(other)) => {
6989
if other.is_empty() {
@@ -73,11 +93,10 @@ impl<'a> Rope<'a> {
7393
.last()
7494
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
7595

76-
let cur = Rc::make_mut(s);
77-
cur.reserve_exact(other.len());
96+
s.reserve_exact(other.len());
7897

7998
for &(chunk, _) in other.iter() {
80-
cur.push((chunk, len));
99+
s.push((chunk, len));
81100
len += chunk.len();
82101
}
83102
}
@@ -88,7 +107,7 @@ impl<'a> Rope<'a> {
88107
let len = s
89108
.last()
90109
.map_or(0, |(chunk, start_pos)| *start_pos + chunk.len());
91-
Rc::make_mut(s).push((other, len));
110+
s.push((other, len));
92111
}
93112
(Repr::Light(s), Repr::Full(other)) => {
94113
if s.is_empty() {
@@ -102,7 +121,7 @@ impl<'a> Rope<'a> {
102121
raw.push((chunk, len));
103122
len += chunk.len();
104123
}
105-
self.repr = Repr::Full(Rc::new(raw));
124+
self.repr = Repr::Full(raw);
106125
}
107126
}
108127
}
@@ -400,7 +419,7 @@ impl<'a> Rope<'a> {
400419
})?;
401420

402421
Ok(Rope {
403-
repr: Repr::Full(Rc::new(raw)),
422+
repr: Repr::Full(raw),
404423
})
405424
}
406425
}
@@ -488,7 +507,7 @@ impl<'a> Rope<'a> {
488507
});
489508

490509
Rope {
491-
repr: Repr::Full(Rc::new(raw)),
510+
repr: Repr::Full(raw),
492511
}
493512
}
494513
}
@@ -689,7 +708,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
689708
// Advance the byte index to the end of the line.
690709
*byte_idx += len;
691710
Some(Rope {
692-
repr: Repr::Full(Rc::new(raw)),
711+
repr: Repr::Full(raw),
693712
})
694713
} else {
695714
// If we did not find a newline in the next few chunks,
@@ -721,7 +740,7 @@ impl<'a> Iterator for Lines<'_, 'a> {
721740
// Advance the byte index to the end of the rope.
722741
*byte_idx += len;
723742
Some(Rope {
724-
repr: Repr::Full(Rc::new(raw)),
743+
repr: Repr::Full(raw),
725744
})
726745
}
727746
}
@@ -955,6 +974,8 @@ impl PartialEq<&str> for Rope<'_> {
955974
}
956975
}
957976

977+
impl Eq for Rope<'_> { }
978+
958979
impl<'a> From<&'a str> for Rope<'a> {
959980
fn from(value: &'a str) -> Self {
960981
Rope {
@@ -979,6 +1000,15 @@ impl<'a> From<&'a Cow<'a, str>> for Rope<'a> {
9791000
}
9801001
}
9811002

1003+
impl<'a> From<&'a StringCell<'a>> for Rope<'a> {
1004+
fn from(value: &'a StringCell<'a>) -> Self {
1005+
match value {
1006+
StringCell::Rope(rope) => rope.clone(),
1007+
StringCell::Owned(s) => Rope::from(s),
1008+
}
1009+
}
1010+
}
1011+
9821012
impl<'a> FromIterator<&'a str> for Rope<'a> {
9831013
fn from_iter<T: IntoIterator<Item = &'a str>>(iter: T) -> Self {
9841014
let mut len = 0;
@@ -995,7 +1025,7 @@ impl<'a> FromIterator<&'a str> for Rope<'a> {
9951025
.collect::<Vec<_>>();
9961026

9971027
Self {
998-
repr: Repr::Full(Rc::new(raw)),
1028+
repr: Repr::Full(raw),
9991029
}
10001030
}
10011031
}
@@ -1046,19 +1076,19 @@ mod tests {
10461076
assert_eq!(simple, "abcdef");
10471077
assert_eq!(
10481078
simple.repr,
1049-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3)])))
1079+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3)]))
10501080
);
10511081
assert_eq!(simple.len(), 6);
10521082

10531083
simple.add("ghi");
10541084
assert_eq!(simple, "abcdefghi");
10551085
assert_eq!(
10561086
simple.repr,
1057-
Repr::Full(Rc::new(Vec::from_iter([
1087+
Repr::Full(Vec::from_iter([
10581088
("abc", 0),
10591089
("def", 3),
10601090
("ghi", 6),
1061-
])))
1091+
]))
10621092
);
10631093
assert_eq!(simple.len(), 9);
10641094
}
@@ -1077,7 +1107,7 @@ mod tests {
10771107
assert_eq!(append1, "abcdef");
10781108
assert_eq!(
10791109
append1.repr,
1080-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3),])))
1110+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3),]))
10811111
);
10821112

10831113
// simple - complex
@@ -1086,12 +1116,12 @@ mod tests {
10861116
assert_eq!(append2, "abc123");
10871117
assert_eq!(
10881118
append2.repr,
1089-
Repr::Full(Rc::new(Vec::from_iter([
1119+
Repr::Full(Vec::from_iter([
10901120
("abc", 0),
10911121
("1", 3),
10921122
("2", 4),
10931123
("3", 5),
1094-
])))
1124+
]))
10951125
);
10961126

10971127
// complex - simple
@@ -1100,12 +1130,12 @@ mod tests {
11001130
assert_eq!(append3, "123abc");
11011131
assert_eq!(
11021132
append3.repr,
1103-
Repr::Full(Rc::new(Vec::from_iter([
1133+
Repr::Full(Vec::from_iter([
11041134
("1", 0),
11051135
("2", 1),
11061136
("3", 2),
11071137
("abc", 3),
1108-
])))
1138+
]))
11091139
);
11101140

11111141
// complex - complex
@@ -1114,14 +1144,14 @@ mod tests {
11141144
assert_eq!(append4, "123456");
11151145
assert_eq!(
11161146
append4.repr,
1117-
Repr::Full(Rc::new(Vec::from_iter([
1147+
Repr::Full(Vec::from_iter([
11181148
("1", 0),
11191149
("2", 1),
11201150
("3", 2),
11211151
("4", 3),
11221152
("5", 4),
11231153
("6", 5),
1124-
])))
1154+
]))
11251155
);
11261156
}
11271157

@@ -1212,7 +1242,7 @@ mod tests {
12121242
assert_eq!(rope, "abcdef");
12131243
assert_eq!(
12141244
rope.repr,
1215-
Repr::Full(Rc::new(Vec::from_iter([("abc", 0), ("def", 3)])))
1245+
Repr::Full(Vec::from_iter([("abc", 0), ("def", 3)]))
12161246
);
12171247
}
12181248

0 commit comments

Comments
 (0)