Improve buffer handling in scan_plain_scalar
.
This commit is contained in:
parent
7275141203
commit
4a5241e0bb
2 changed files with 43 additions and 24 deletions
|
@ -17,11 +17,13 @@ ethi_bench:
|
||||||
cd ../libfyaml/build && ninja
|
cd ../libfyaml/build && ninja
|
||||||
cargo bench_compare run_bench
|
cargo bench_compare run_bench
|
||||||
|
|
||||||
ethi_build_dump:
|
ethi_build_cg_dump:
|
||||||
(cargo test 2>&1 >/dev/null || (cargo test && false))
|
(cargo test 2>&1 >/dev/null || (cargo test && false))
|
||||||
CARGO_PROFILE_RELEASE_DEBUG=true cargo build --release --bin time_parse
|
CARGO_PROFILE_RELEASE_DEBUG=true cargo build --release --bin time_parse
|
||||||
valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes ./target/release/time_parse ~/Projects/yaml-rust2/bench_yaml/strings_array.yaml
|
valgrind --tool=callgrind --dump-instr=yes --collect-jumps=yes ./target/release/time_parse ~/Projects/yaml-rust2/bench_yaml/small_objects.yaml
|
||||||
|
|
||||||
|
ethi_build_dump: ethi_build_cg_dump
|
||||||
|
cg_file=`\ls -1t callgrind.out.* | head -n1` && callgrind_annotate $cg_file --auto=no --threshold=99.99 > cg/WORK && rm $cg_file
|
||||||
|
|
||||||
ethi_compare: ethi_build_dump
|
ethi_compare: ethi_build_dump
|
||||||
cg_file=`\ls -1t callgrind.out.* | head -n1` && callgrind_annotate $cg_file --auto=no --threshold=99.99 > cg/WORK && rm $cg_file
|
|
||||||
callgrind_differ `\ls cg/0*` cg/WORK --show percentagediff,ircount --sort-by=-first-ir -a
|
callgrind_differ `\ls cg/0*` cg/WORK --show percentagediff,ircount --sort-by=-first-ir -a
|
||||||
|
|
|
@ -422,6 +422,9 @@ pub struct Scanner<T> {
|
||||||
/// [`Possible`]: ImplicitMappingState::Possible
|
/// [`Possible`]: ImplicitMappingState::Possible
|
||||||
/// [`Inside`]: ImplicitMappingState::Inside
|
/// [`Inside`]: ImplicitMappingState::Inside
|
||||||
implicit_flow_mapping_states: Vec<ImplicitMappingState>,
|
implicit_flow_mapping_states: Vec<ImplicitMappingState>,
|
||||||
|
buf_leading_break: String,
|
||||||
|
buf_trailing_breaks: String,
|
||||||
|
buf_whitespaces: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: Input> Iterator for Scanner<T> {
|
impl<T: Input> Iterator for Scanner<T> {
|
||||||
|
@ -473,6 +476,10 @@ impl<T: Input> Scanner<T> {
|
||||||
leading_whitespace: true,
|
leading_whitespace: true,
|
||||||
flow_mapping_started: false,
|
flow_mapping_started: false,
|
||||||
implicit_flow_mapping_states: vec![],
|
implicit_flow_mapping_states: vec![],
|
||||||
|
|
||||||
|
buf_leading_break: String::new(),
|
||||||
|
buf_trailing_breaks: String::new(),
|
||||||
|
buf_whitespaces: String::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -564,6 +571,16 @@ impl<T: Input> Scanner<T> {
|
||||||
// If the next characters do not correspond to a line break.
|
// If the next characters do not correspond to a line break.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read_break(&mut self, s: &mut String) {
|
fn read_break(&mut self, s: &mut String) {
|
||||||
|
self.skip_break();
|
||||||
|
s.push('\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read and consume a line break (either `\r`, `\n` or `\r\n`).
|
||||||
|
//
|
||||||
|
// # Panics (in debug)
|
||||||
|
// If the next characters do not correspond to a line break.
|
||||||
|
#[inline]
|
||||||
|
fn skip_break(&mut self) {
|
||||||
let c = self.input.peek();
|
let c = self.input.peek();
|
||||||
let nc = self.input.peek_nth(1);
|
let nc = self.input.peek_nth(1);
|
||||||
debug_assert!(is_break(c));
|
debug_assert!(is_break(c));
|
||||||
|
@ -571,8 +588,6 @@ impl<T: Input> Scanner<T> {
|
||||||
self.skip_blank();
|
self.skip_blank();
|
||||||
}
|
}
|
||||||
self.skip_nl();
|
self.skip_nl();
|
||||||
|
|
||||||
s.push('\n');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Insert a token at the given position.
|
/// Insert a token at the given position.
|
||||||
|
@ -2102,9 +2117,9 @@ impl<T: Input> Scanner<T> {
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut string = String::with_capacity(32);
|
let mut string = String::with_capacity(32);
|
||||||
let mut leading_break = String::with_capacity(32);
|
self.buf_whitespaces.clear();
|
||||||
let mut trailing_breaks = String::with_capacity(32);
|
self.buf_leading_break.clear();
|
||||||
let mut whitespaces = String::with_capacity(32);
|
self.buf_trailing_breaks.clear();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
self.input.lookahead(4);
|
self.input.lookahead(4);
|
||||||
|
@ -2123,24 +2138,24 @@ impl<T: Input> Scanner<T> {
|
||||||
&& self.input.next_can_be_plain_scalar(self.flow_level > 0)
|
&& self.input.next_can_be_plain_scalar(self.flow_level > 0)
|
||||||
{
|
{
|
||||||
if self.leading_whitespace {
|
if self.leading_whitespace {
|
||||||
if leading_break.is_empty() {
|
if self.buf_leading_break.is_empty() {
|
||||||
string.push_str(&leading_break);
|
string.push_str(&self.buf_leading_break);
|
||||||
string.push_str(&trailing_breaks);
|
string.push_str(&self.buf_trailing_breaks);
|
||||||
trailing_breaks.clear();
|
self.buf_trailing_breaks.clear();
|
||||||
leading_break.clear();
|
self.buf_leading_break.clear();
|
||||||
} else {
|
} else {
|
||||||
if trailing_breaks.is_empty() {
|
if self.buf_trailing_breaks.is_empty() {
|
||||||
string.push(' ');
|
string.push(' ');
|
||||||
} else {
|
} else {
|
||||||
string.push_str(&trailing_breaks);
|
string.push_str(&self.buf_trailing_breaks);
|
||||||
trailing_breaks.clear();
|
self.buf_trailing_breaks.clear();
|
||||||
}
|
}
|
||||||
leading_break.clear();
|
self.buf_leading_break.clear();
|
||||||
}
|
}
|
||||||
self.leading_whitespace = false;
|
self.leading_whitespace = false;
|
||||||
} else if !whitespaces.is_empty() {
|
} else if !self.buf_whitespaces.is_empty() {
|
||||||
string.push_str(&whitespaces);
|
string.push_str(&self.buf_whitespaces);
|
||||||
whitespaces.clear();
|
self.buf_whitespaces.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
// We can unroll the first iteration of the loop.
|
// We can unroll the first iteration of the loop.
|
||||||
|
@ -2182,7 +2197,7 @@ impl<T: Input> Scanner<T> {
|
||||||
while self.input.next_is_blank_or_break() {
|
while self.input.next_is_blank_or_break() {
|
||||||
if self.input.next_is_blank() {
|
if self.input.next_is_blank() {
|
||||||
if !self.leading_whitespace {
|
if !self.leading_whitespace {
|
||||||
whitespaces.push(self.input.peek());
|
self.buf_whitespaces.push(self.input.peek());
|
||||||
self.skip_blank();
|
self.skip_blank();
|
||||||
} else if (self.mark.col as isize) < indent && self.input.peek() == '\t' {
|
} else if (self.mark.col as isize) < indent && self.input.peek() == '\t' {
|
||||||
// Tabs in an indentation columns are allowed if and only if the line is
|
// Tabs in an indentation columns are allowed if and only if the line is
|
||||||
|
@ -2200,10 +2215,12 @@ impl<T: Input> Scanner<T> {
|
||||||
} else {
|
} else {
|
||||||
// Check if it is a first line break
|
// Check if it is a first line break
|
||||||
if self.leading_whitespace {
|
if self.leading_whitespace {
|
||||||
self.read_break(&mut trailing_breaks);
|
self.skip_break();
|
||||||
|
self.buf_trailing_breaks.push('\n');
|
||||||
} else {
|
} else {
|
||||||
whitespaces.clear();
|
self.buf_whitespaces.clear();
|
||||||
self.read_break(&mut leading_break);
|
self.skip_break();
|
||||||
|
self.buf_leading_break.push('\n');
|
||||||
self.leading_whitespace = true;
|
self.leading_whitespace = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue