Skip to content

Commit

Permalink
⚡️ Simplify and speed up SEARCH response parsing
Browse files Browse the repository at this point in the history
The `mailbox-data` `SEARCH` response parser was refactored, as part of
the work on `CONDSTORE` support.  This commit contains only the
refactoring, which (coincidentally) brings a significant speed
improvement:

```
invalid_search_response_multiple_result_with_trailing_space
                v0.4.6-2-g3ac9912:     70865.1 i/s
                            0.4.6:     49505.1 i/s - 1.43x  slower

invalid_search_response_single_result_with_trailing_space
                v0.4.6-2-g3ac9912:     74398.0 i/s
                            0.4.6:     67791.1 i/s - 1.10x  slower

rfc3501_7.2.5_SEARCH_response_example
                v0.4.6-2-g3ac9912:     65968.9 i/s
                            0.4.6:     53490.9 i/s - 1.23x  slower

search_response_multiple_seq_nums_returned
                v0.4.6-2-g3ac9912:     62777.4 i/s
                            0.4.6:     47852.3 i/s - 1.31x  slower

search_response_single_seq_nums_returned
                v0.4.6-2-g3ac9912:     79656.5 i/s
                            0.4.6:     69234.9 i/s - 1.15x  slower

search_response_with_condstore_modseq
                v0.4.6-2-g3ac9912:     55376.4 i/s
                            0.4.6:     39129.0 i/s - 1.42x  slower
```
  • Loading branch information
nevans committed Nov 25, 2023
1 parent b4a1915 commit 38d7530
Showing 1 changed file with 8 additions and 27 deletions.
35 changes: 8 additions & 27 deletions lib/net/imap/response_parser.rb
Original file line number Diff line number Diff line change
Expand Up @@ -1452,34 +1452,15 @@ def acl_data
# mailbox-data = obsolete-search-response / ...
# obsolete-search-response = "SEARCH" *(SP nz-number)
def mailbox_data__search
token = match(T_ATOM)
name = token.value.upcase
token = lookahead
if token.symbol == T_SPACE
shift_token
data = []
while true
token = lookahead
case token.symbol
when T_CRLF
break
when T_SPACE
shift_token
when T_NUMBER
data.push(number)
when T_LPAR
# TODO: include the MODSEQ value in a response
shift_token
match(T_ATOM)
match(T_SPACE)
match(T_NUMBER)
match(T_RPAR)
end
end
else
data = []
name = label_in("SEARCH", "SORT")
data = []
while _ = SP? && nz_number? do data << _ end
if lpar?
label("MODSEQ"); SP!
mod_sequence_value
rpar
end
return UntaggedResponse.new(name, data, @str)
UntaggedResponse.new(name, data, @str)
end
alias sort_data mailbox_data__search

Expand Down

0 comments on commit 38d7530

Please sign in to comment.