Skip to content

Commit 00cb1f4

Browse files
committed
perf: refactor SegmentIter
1 parent 8626651 commit 00cb1f4

File tree

2 files changed

+47
-52
lines changed

2 files changed

+47
-52
lines changed

src/helpers.rs

Lines changed: 44 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -118,80 +118,75 @@ pub fn decode_mappings<'b, 'a: 'b>(
118118
}
119119

120120
pub struct SegmentIter<'a> {
121-
mapping_str: &'a str,
121+
mapping_str: &'a [u8],
122122
generated_line: usize,
123123
generated_column: u32,
124124
source_index: u32,
125125
original_line: u32,
126126
original_column: u32,
127127
name_index: u32,
128-
line: &'a str,
129128
nums: ArrayVec<i64, 5>,
130-
segment_cursor: usize,
129+
tracing_index: usize,
130+
current_index: usize,
131131
}
132132

133133
impl<'a> SegmentIter<'a> {
134134
pub fn new(mapping_str: &'a str) -> Self {
135135
SegmentIter {
136-
line: "",
137-
mapping_str,
136+
mapping_str: mapping_str.as_bytes(),
138137
source_index: 0,
139138
original_line: 1,
140139
original_column: 0,
141140
name_index: 0,
142-
generated_line: 0,
143-
segment_cursor: 0,
141+
generated_line: 1,
144142
generated_column: 0,
145143
nums: ArrayVec::new(),
144+
tracing_index: 0,
145+
current_index: 0,
146146
}
147147
}
148148

149-
fn next_segment(&mut self) -> Option<&'a str> {
150-
if self.line.is_empty() {
151-
loop {
152-
match self.next_line() {
153-
Some(line) => {
154-
self.generated_line += 1;
155-
if line.is_empty() {
156-
continue;
157-
}
158-
self.line = line;
159-
self.generated_column = 0;
160-
self.segment_cursor = 0;
161-
break;
149+
fn next_segment(&mut self) -> Option<&'a [u8]> {
150+
let mapping_str_len = self.mapping_str.len();
151+
if self.current_index == mapping_str_len {
152+
return None;
153+
}
154+
155+
loop {
156+
match self.mapping_str[self.current_index] {
157+
b',' => {
158+
if self.tracing_index != self.current_index {
159+
let segment =
160+
&self.mapping_str[self.tracing_index..self.current_index];
161+
self.tracing_index = self.current_index;
162+
return Some(segment);
162163
}
163-
None => return None,
164+
self.current_index += 1;
165+
self.tracing_index = self.current_index;
164166
}
167+
b';' => {
168+
if self.tracing_index != self.current_index {
169+
let segment =
170+
&self.mapping_str[self.tracing_index..self.current_index];
171+
self.tracing_index = self.current_index;
172+
return Some(segment);
173+
}
174+
self.generated_line += 1;
175+
self.generated_column = 0;
176+
self.current_index += 1;
177+
self.tracing_index = self.current_index;
178+
}
179+
_ => self.current_index += 1,
165180
}
166-
}
167-
168-
if let Some(i) =
169-
memchr::memchr(b',', self.line[self.segment_cursor..].as_bytes())
170-
{
171-
let cursor = self.segment_cursor;
172-
self.segment_cursor = self.segment_cursor + i + 1;
173-
Some(&self.line[cursor..cursor + i])
174-
} else {
175-
let line = self.line;
176-
self.line = "";
177-
Some(&line[self.segment_cursor..])
178-
}
179-
}
180181

181-
fn next_line(&mut self) -> Option<&'a str> {
182-
if self.mapping_str.is_empty() {
183-
return None;
184-
}
185-
match memchr::memchr(b';', self.mapping_str.as_bytes()) {
186-
Some(i) => {
187-
let temp_str = self.mapping_str;
188-
self.mapping_str = &self.mapping_str[i + 1..];
189-
Some(&temp_str[..i])
190-
}
191-
None => {
192-
let tem_str = self.mapping_str;
193-
self.mapping_str = "";
194-
Some(tem_str)
182+
if self.current_index == mapping_str_len {
183+
if self.tracing_index != self.current_index {
184+
let segment =
185+
&self.mapping_str[self.tracing_index..self.current_index];
186+
return Some(segment);
187+
} else {
188+
return None;
189+
}
195190
}
196191
}
197192
}

src/vlq.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -267,12 +267,12 @@ const B64: [i8; 256] = [
267267
];
268268

269269
/// Parses a VLQ segment into a pre-allocated `Vec` instead of returning a new allocation.
270-
pub fn decode(segment: &str, rv: &mut ArrayVec<i64, 5>) -> Result<()> {
270+
pub fn decode(segment: &[u8], rv: &mut ArrayVec<i64, 5>) -> Result<()> {
271271
let mut cur = 0;
272272
let mut shift = 0;
273273

274-
for c in segment.bytes() {
275-
let enc = i64::from(B64[c as usize]);
274+
for c in segment {
275+
let enc = i64::from(B64[*c as usize]);
276276
let val = enc & 0b11111;
277277
let cont = enc >> 5;
278278
cur += val.checked_shl(shift).ok_or(Error::VlqOverflow)?;

0 commit comments

Comments
 (0)