Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

perf: remove SourceMapLineChunk #110

Draft
wants to merge 17 commits into
base: main
Choose a base branch
from
Draft
229 changes: 96 additions & 133 deletions src/helpers.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
use arrayvec::ArrayVec;
use std::{
borrow::{BorrowMut, Cow},
cell::{OnceCell, RefCell},
cell::RefCell,
rc::Rc,
};

use memchr::Memchr2;
use rustc_hash::FxHashMap as HashMap;

use crate::{
Expand All @@ -13,7 +13,7 @@ use crate::{
source::{Mapping, OriginalLocation},
vlq::decode,
with_indices::WithIndices,
MapOptions, SourceMap,
Error, MapOptions, SourceMap,
};

// Adding this type because sourceContentLine not happy
Expand Down Expand Up @@ -115,87 +115,86 @@ pub struct GeneratedInfo {
pub generated_column: u32,
}

pub fn decode_mappings<'b, 'a: 'b>(
source_map: &'a SourceMap,
) -> impl Iterator<Item = Mapping> + 'b {
pub fn decode_mappings(
source_map: &SourceMap,
) -> impl Iterator<Item = Mapping> + '_ {
SegmentIter::new(source_map.mappings())
}

pub struct SegmentIter<'a> {
mapping_str: &'a str,
mapping_str: &'a [u8],
mapping_iter: Memchr2<'a>,
generated_line: usize,
generated_column: u32,
source_index: u32,
original_line: u32,
original_column: u32,
name_index: u32,
line: &'a str,
nums: ArrayVec<i64, 5>,
segment_cursor: usize,
tracing_index: usize,
tracing_newline: bool,
}

impl<'a> SegmentIter<'a> {
pub fn new(mapping_str: &'a str) -> Self {
let mapping_str = mapping_str.as_bytes();
let mapping_iter = memchr::memchr2_iter(b',', b';', mapping_str);
SegmentIter {
line: "",
mapping_str,
mapping_iter,
source_index: 0,
original_line: 1,
original_column: 0,
name_index: 0,
generated_line: 0,
segment_cursor: 0,
generated_line: 1,
generated_column: 0,
nums: ArrayVec::new(),
tracing_index: 0,
tracing_newline: false,
}
}

fn next_segment(&mut self) -> Option<&'a str> {
if self.line.is_empty() {
loop {
match self.next_line() {
Some(line) => {
self.generated_line += 1;
if line.is_empty() {
continue;
fn next_segment(&mut self) -> Option<&'a [u8]> {
let mapping_str_len = self.mapping_str.len();

loop {
if self.tracing_newline {
self.generated_line += 1;
self.generated_column = 0;
self.tracing_newline = false;
}

match self.mapping_iter.next() {
Some(index) => match self.mapping_str[index] {
b',' => {
if self.tracing_index != index {
let segment = &self.mapping_str[self.tracing_index..index];
self.tracing_index = index + 1;
return Some(segment);
}
self.line = line;
self.generated_column = 0;
self.segment_cursor = 0;
break;
self.tracing_index = index + 1;
}
b';' => {
self.tracing_newline = true;
if self.tracing_index != index {
let segment = &self.mapping_str[self.tracing_index..index];
self.tracing_index = index + 1;
return Some(segment);
}
self.tracing_index = index + 1;
}
_ => unreachable!(),
},
None => {
if self.tracing_index != mapping_str_len {
let segment =
&self.mapping_str[self.tracing_index..mapping_str_len];
self.tracing_index = mapping_str_len;
return Some(segment);
}
None => return None,
}
}
}

if let Some(i) =
memchr::memchr(b',', self.line[self.segment_cursor..].as_bytes())
{
let cursor = self.segment_cursor;
self.segment_cursor = self.segment_cursor + i + 1;
Some(&self.line[cursor..cursor + i])
} else {
let line = self.line;
self.line = "";
Some(&line[self.segment_cursor..])
}
}

fn next_line(&mut self) -> Option<&'a str> {
if self.mapping_str.is_empty() {
return None;
}
match memchr::memchr(b';', self.mapping_str.as_bytes()) {
Some(i) => {
let temp_str = self.mapping_str;
self.mapping_str = &self.mapping_str[i + 1..];
Some(&temp_str[..i])
}
None => {
let tem_str = self.mapping_str;
self.mapping_str = "";
Some(tem_str)
if self.tracing_index == mapping_str_len {
return None;
}
}
}
Expand All @@ -207,30 +206,38 @@ impl<'a> Iterator for SegmentIter<'a> {
fn next(&mut self) -> Option<Self::Item> {
match self.next_segment() {
Some(segment) => {
self.nums.clear();
decode(segment, &mut self.nums).unwrap();
self.generated_column =
(i64::from(self.generated_column) + self.nums[0]) as u32;
let mut vlq = decode(segment);
self.generated_column = (i64::from(self.generated_column)
+ vlq
.next()
.unwrap_or_else(|| Err(Error::VlqNoValues))
.unwrap()) as u32;

let mut src = None;
let mut name = None;

if self.nums.len() > 1 {
if self.nums.len() != 4 && self.nums.len() != 5 {
panic!("got {} segments, expected 4 or 5", self.nums.len());
}
if let Some(source_index) = vlq.next() {
// if self.nums.len() != 4 && self.nums.len() != 5 {
// panic!("got {} segments, expected 4 or 5", self.nums.len());
// }
self.source_index =
(i64::from(self.source_index) + self.nums[1]) as u32;
(i64::from(self.source_index) + source_index.unwrap()) as u32;
src = Some(self.source_index);
self.original_line =
(i64::from(self.original_line) + self.nums[2]) as u32;
self.original_column =
(i64::from(self.original_column) + self.nums[3]) as u32;

if self.nums.len() > 4 {
self.original_line = (i64::from(self.original_line)
+ vlq
.next()
.unwrap_or_else(|| Err(Error::VlqNoValues))
.unwrap()) as u32;
self.original_column = (i64::from(self.original_column)
+ vlq
.next()
.unwrap_or_else(|| Err(Error::VlqNoValues))
.unwrap()) as u32;

if let Some(name_index) = vlq.next() {
self.name_index =
(i64::from(self.name_index) + self.nums[4]) as u32;
name = Some(self.name_index);
(i64::from(self.name_index) + name_index.unwrap()) as u32;
name = Some(self.name_index)
}
}

Expand Down Expand Up @@ -466,20 +473,20 @@ fn stream_chunks_of_source_map_final<'a>(
on_name(i as u32, Cow::Borrowed(name));
}
let mut mapping_active_line = 0;
let mut on_mapping = |mapping: &Mapping| {
let mut on_mapping = |mapping: Mapping| {
if mapping.generated_line >= result.generated_line
&& (mapping.generated_column >= result.generated_column
|| mapping.generated_line > result.generated_line)
{
return;
}
if let Some(original) = &mapping.original {
if let Some(original) = mapping.original {
on_chunk(
None,
Mapping {
generated_line: mapping.generated_line,
generated_column: mapping.generated_column,
original: Some(*original),
original: Some(original),
},
);
mapping_active_line = mapping.generated_line;
Expand Down Expand Up @@ -527,11 +534,11 @@ fn stream_chunks_of_source_map_full<'a>(
let mut tracking_generated_column: u32 = 0;
let mut tracking_mapping_original: Option<OriginalLocation> = None;

let mut mappings_iter = source_map.decoded_mappings().iter();
let mut mappings_iter = source_map.decoded_mappings();
let mut current_mapping = mappings_iter.next();

for (current_generated_index, c) in source.char_indices() {
if let Some(mapping) = current_mapping.take() {
if let Some(mapping) = &current_mapping {
if mapping.generated_line == current_generated_line
&& mapping.generated_column == current_generated_column
{
Expand All @@ -553,8 +560,6 @@ fn stream_chunks_of_source_map_full<'a>(
tracking_mapping_original = mapping.original;

current_mapping = mappings_iter.next();
} else {
current_mapping = Some(mapping);
}
}

Expand Down Expand Up @@ -629,25 +634,15 @@ fn stream_chunks_of_source_map_lines_final<'a>(
};
let mut current_generated_line = 1;

let mut on_mapping = |mapping: &Mapping| {
if let Some(original) = &mapping.original.filter(|_| {
let mut on_mapping = |mut mapping: Mapping| {
if let Some(mut original) = mapping.original.filter(|_| {
current_generated_line <= mapping.generated_line
&& mapping.generated_line <= final_line
}) {
on_chunk(
None,
Mapping {
generated_line: mapping.generated_line,
generated_column: 0,
original: Some(OriginalLocation {
source_index: original.source_index,
original_line: original.original_line,
original_column: original.original_column,
name_index: None,
}),
},
);
mapping.generated_column = 0;
original.name_index = None;
current_generated_line = mapping.generated_line + 1;
on_chunk(None, mapping);
}
};
for mapping in source_map.decoded_mappings() {
Expand Down Expand Up @@ -678,7 +673,7 @@ fn stream_chunks_of_source_map_lines_full<'a>(
)
}
let mut current_generated_line = 1;
let mut on_mapping = |mapping: &Mapping| {
let mut on_mapping = |mut mapping: Mapping| {
if mapping.original.is_none()
|| mapping.generated_line < current_generated_line
|| mapping.generated_line as usize > lines.len()
Expand All @@ -699,24 +694,14 @@ fn stream_chunks_of_source_map_lines_full<'a>(
}
current_generated_line += 1;
}
if let Some(original) = &mapping
if let Some(mut original) = mapping
.original
.filter(|_| mapping.generated_line as usize <= lines.len())
{
let chunk = lines[current_generated_line as usize - 1];
on_chunk(
Some(Cow::Borrowed(chunk)),
Mapping {
generated_line: mapping.generated_line,
generated_column: 0,
original: Some(OriginalLocation {
source_index: original.source_index,
original_line: original.original_line,
original_column: original.original_column,
name_index: None,
}),
},
);
mapping.generated_column = 0;
original.name_index = None;
on_chunk(Some(Cow::Borrowed(chunk)), mapping);
current_generated_line += 1;
}
};
Expand Down Expand Up @@ -752,29 +737,7 @@ fn stream_chunks_of_source_map_lines_full<'a>(
#[derive(Debug)]
struct SourceMapLineData<'a> {
pub mappings_data: Vec<i64>,
pub chunks: Vec<SourceMapLineChunk<'a>>,
}

#[derive(Debug)]
struct SourceMapLineChunk<'a> {
content: Cow<'a, str>,
cached: OnceCell<WithIndices<Cow<'a, str>>>,
}

impl<'a> SourceMapLineChunk<'a> {
pub fn new(content: Cow<'a, str>) -> Self {
Self {
content,
cached: OnceCell::new(),
}
}

pub fn substring(&self, start_index: usize, end_index: usize) -> &str {
let cached = self
.cached
.get_or_init(|| WithIndices::new(self.content.clone()));
cached.substring(start_index, end_index)
}
pub chunks: Vec<WithIndices<Cow<'a, str>>>,
}

type InnerSourceIndexValueMapping<'a> =
Expand Down Expand Up @@ -1223,7 +1186,7 @@ pub fn stream_chunks_of_combined_source_map<'a>(
.unwrap_or(-1),
);
// SAFETY: final_source is false
let chunk = SourceMapLineChunk::new(chunk.unwrap());
let chunk = WithIndices::new(chunk.unwrap());
data.chunks.push(chunk);
},
&mut |i, source, source_content| {
Expand Down
Loading
Loading