-
Notifications
You must be signed in to change notification settings - Fork 0
⚡ Bolt: Avoid UTF-8 decoding overhead in parser ASCII search #13
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
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -70,16 +70,16 @@ fn split_segments(source: &str) -> Vec<Segment<'_>> { | |
| for (line_index, line) in source.lines().enumerate() { | ||
| let mut start = 0; | ||
|
|
||
| for (byte_index, character) in line.char_indices() { | ||
| if character == '|' { | ||
| push_segment( | ||
| &mut segments, | ||
| &line[start..byte_index], | ||
| line_index + 1, | ||
| start, | ||
| ); | ||
| start = byte_index + character.len_utf8(); | ||
| } | ||
| // ⚡ Bolt Optimization: Use `match_indices` instead of `char_indices` for ASCII search | ||
| // This avoids UTF-8 decoding overhead when searching for the pipe character. | ||
| for (byte_index, _) in line.match_indices('|') { | ||
| push_segment( | ||
| &mut segments, | ||
| &line[start..byte_index], | ||
| line_index + 1, | ||
| start, | ||
| ); | ||
| start = byte_index + 1; // '|' is 1 byte | ||
| } | ||
|
|
||
| push_segment(&mut segments, &line[start..], line_index + 1, start); | ||
|
|
@@ -102,9 +102,12 @@ fn push_segment<'a>(segments: &mut Vec<Segment<'a>>, raw: &'a str, line: usize, | |
| } | ||
|
|
||
| fn parse_transform(text: &str, span: Span) -> Result<Transform, Diagnostic> { | ||
| // ⚡ Bolt Optimization: Use `.as_bytes().iter().position` to avoid UTF-8 decoding | ||
| // overhead when looking for ASCII whitespace to determine the keyword end. | ||
| let keyword_end = text | ||
| .char_indices() | ||
| .find_map(|(index, character)| character.is_whitespace().then_some(index)) | ||
| .as_bytes() | ||
| .iter() | ||
| .position(|&b| b.is_ascii_whitespace()) | ||
|
Comment on lines
+105
to
+110
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
git diff -- compiler/rockql-parser/src/lib.rs
rg -n -C 6 \
'parse_transform|char_indices|is_whitespace|is_ascii_whitespace' \
compiler/rockql-parser/src/lib.rs
rg -n -C 3 \
'\\u\{00A0\}|\\u\{2003\}|unicode.*whitespace|non.?ASCII.*whitespace' \
compiler/rockql-parser/src compiler/rockql-sql/src/lib.rsRepository: Sayanthrock-Developer/ROCKQL Length of output: 1879 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- parser source ---'
cat -n compiler/rockql-parser/src/lib.rs | sed -n '1,180p'
printf '%s\n' '--- parser files and tests ---'
git ls-files compiler/rockql-parser | sed -n '1,160p'
rg -n -C 4 \
'parse_transform|unknown transformation|Transform|filter|whitespace|is_ascii_whitespace|is_whitespace' \
compiler/rockql-parser compiler/rockql-sql README.md docs 2>/dev/null || true
printf '%s\n' '--- repository-wide RockQL syntax references ---'
rg -n -C 3 \
'RockQL|transformation|transform|filter|pipe|ASCII|Unicode|whitespace|non.?ASCII' \
--glob '!target/**' --glob '!node_modules/**' . 2>/dev/null | sed -n '1,260p'
printf '%s\n' '--- relevant diff summary ---'
git diff --stat -- compiler/rockql-parser/src/lib.rs
git diff --unified=30 -- compiler/rockql-parser/src/lib.rsRepository: Sayanthrock-Developer/ROCKQL Length of output: 40697 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- repository state ---'
git status --short
git rev-parse --short HEAD
git log --oneline -5 -- compiler/rockql-parser/src/lib.rs
printf '%s\n' '--- prior parser implementation, if available ---'
parent="$(git rev-parse HEAD^ 2>/dev/null || true)"
if [ -n "$parent" ]; then
git show "$parent:compiler/rockql-parser/src/lib.rs" 2>/dev/null \
| nl -ba | sed -n '90,135p' || true
fi
printf '%s\n' '--- exact whitespace behavior for the reported inputs ---'
python3 - <<'PY'
cases = [
"filter active == true",
"filter\u00a0active == true",
"filter\u2003active == true",
"filter\tactive == true",
"filter\nactive == true",
]
for text in cases:
ascii_end = next(
(i for i, byte in enumerate(text.encode("utf-8"))
if chr(byte).isspace() and byte < 128),
len(text.encode("utf-8")),
)
unicode_end = next(
(i for i, char in enumerate(text)
if char.isspace()),
len(text),
)
ascii_keyword = text.encode("utf-8")[:ascii_end].decode("utf-8", errors="replace")
unicode_keyword = text[:unicode_end]
print(repr(text), "ascii_keyword=", repr(ascii_keyword),
"unicode_keyword=", repr(unicode_keyword))
PYRepository: Sayanthrock-Developer/ROCKQL Length of output: 1052 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '--- optimization commit diff ---'
git show --format=fuller --unified=24 35be6b8 -- compiler/rockql-parser/src/lib.rs
printf '%s\n' '--- parent implementation ---'
git show 35be6b8^:compiler/rockql-parser/src/lib.rs \
| sed -n '90,135p'Repository: Sayanthrock-Developer/ROCKQL Length of output: 5826 Preserve Unicode whitespace handling.
🤖 Prompt for AI Agents |
||
| .unwrap_or(text.len()); | ||
|
Comment on lines
+108
to
111
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Suggestion: The byte-level scan only recognizes ASCII whitespace, whereas the previous character-based scan recognized all Unicode whitespace. Inputs such as Severity Level: Major
|
||
|
|
||
| let keyword = &text[..keyword_end]; | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When a query contains non-ASCII whitespace between the transform keyword and its argument, such as a pasted non-breaking space in
from users, this byte scan no longer finds the separator, sokeywordbecomes the entire segment and the parser reports an unknown transformation. The previouscharacter.is_whitespace()path accepted these inputs, and the rest of this parser still uses Unicode-awaretrim(), so this change is a user-visible parsing regression rather than just an optimization.Useful? React with 👍 / 👎.