Repository navigation
perf(parser): replace input.substring with matchAsPrefix in GridFilterEngine lexer #1512
Copy link
Copy link
Open
Labels
P3Low priority / Polish & EnhancementsLow priority / Polish & Enhancementsdata-gridInteractive data grid, cell editor, filtering, groupingsInteractive data grid, cell editor, filtering, groupingsparserTheme parser epic label: parserTheme parser epic label: parserperformanceTheme parser epic label: performanceTheme parser epic label: performance
Milestone
Description
Summary
In lib/features/workspace/grid_filter_engine.dart (lines 389, 400, 408, 458):
Inside _FilterLexer.tokenize() and _tryMatchPredicate(), logical operators and predicates are checked against a fresh substring copy on every single token iteration:
final rem = input.substring(i);
final andMatch = RegExp(r'^(AND\b|&&)', caseSensitive: false).firstMatch(rem);
...
final rem = input.substring(p);
final isNullMatch = RegExp(r'^IS\s+(NOT\s+)?NULL\b', caseSensitive: false).firstMatch(rem);Whenever the user types into the data grid filter bar, thousands of transient string slices are allocated, triggering garbage collection and UI stutter.
Architectural Solution: Dedicated Zero-Allocation Micro-Parsers
Decompose _tryMatchPredicate and token matching into dedicated, testable micro-functions operating strictly on (String input, int offset) with zero substring copying:
static int? _matchLogicalOperator(String input, int offset)- Matches
AND,OR,NOT,&&,||,!via precompiled static patterns usingmatchAsPrefix(input, offset).
- Matches
static ({int consumed, _PredicateNode node})? _matchNullPredicate(String input, int start, int colIdx)- Micro-parser for
IS NULLandIS NOT NULL.
- Micro-parser for
static ({int consumed, _PredicateNode node})? _matchInPredicate(String input, int start, int colIdx)- Micro-parser for
IN (...)andNOT IN (...).
- Micro-parser for
static ({int consumed, _PredicateNode node})? _matchBetweenPredicate(String input, int start, int colIdx)- Micro-parser for
BETWEEN min AND max.
- Micro-parser for
static ({int consumed, _PredicateNode node})? _matchComparisonPredicate(String input, int start, int colIdx)- Micro-parser for relational operators (
=,!=,<,<=,>,>=,:,LIKE,ILIKE).
- Micro-parser for relational operators (
static ({String value, int consumed})? _scanQuotedStringLiteral(String input, int start)- Single-pass quote escaper for single (
'...) and double ("...) quotes.
- Single-pass quote escaper for single (
Acceptance Criteria
- Each predicate type and operator has an isolated, self-contained micro-function.
- No intermediate
input.substring(i)calls in the lexer loop. - Micro-functions return Dart 3 records with primitive offsets and nodes.
- 100% test pass rate in
test/features/workspace/data_grid_filter_engine_test.dart.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
P3Low priority / Polish & EnhancementsLow priority / Polish & Enhancementsdata-gridInteractive data grid, cell editor, filtering, groupingsInteractive data grid, cell editor, filtering, groupingsparserTheme parser epic label: parserTheme parser epic label: parserperformanceTheme parser epic label: performanceTheme parser epic label: performance
Activity
Merge pull request #1607 from QueryaHub/issue/1527-grid-filter-engine