Skip to content

Commit

Permalink
scanner: speed up token position -> location using a cache
Browse files Browse the repository at this point in the history
Signed-off-by: Ran Benita <[email protected]>
  • Loading branch information
bluetech committed Jan 30, 2025
1 parent fd8de2b commit 9a00d32
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 4 deletions.
24 changes: 20 additions & 4 deletions src/scanner-utils.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,32 @@ scanner_token_location(struct scanner *s)
* https://lemire.me/blog/2017/02/14/how-fast-can-you-count-lines/
* https://github.com/lemire/Code-used-on-Daniel-Lemire-s-blog/blob/master/2017/02/14/newlines.c
* This is the fastest portable one for me, and it's simple.
*
* To avoid rescanning on each call, cache the previously found position
* and start from that on the next call. This is effective as long as the
* tokens go forward.
*/
size_t line = 1, column;
size_t line, column;
size_t line_pos = 0;
const char *ptr = s->s;
if (s->cached_pos > s->token_pos) {
s->cached_pos = 0;
s->cached_loc.line = s->cached_loc.column = 1;
}
line = s->cached_loc.line;
const char *ptr = s->s + s->cached_pos;
const char *last = s->s + s->token_pos;
while ((ptr = memchr(ptr, '\n', last - ptr))) {
line++;
ptr++;
line_pos = ptr - s->s;
}
column = s->token_pos - line_pos + 1;
return (struct scanner_loc){.line = line, .column = column};
if (line == s->cached_loc.line) {
column = s->cached_loc.column + (s->token_pos - s->cached_pos);
} else {
column = s->token_pos - line_pos + 1;
}
struct scanner_loc loc = {.line = line, .column = column};
s->cached_pos = s->token_pos;
s->cached_loc = loc;
return loc;
}
5 changes: 5 additions & 0 deletions src/scanner-utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,9 @@ struct scanner {
size_t buf_pos;
/* The position of the start of the current token. */
size_t token_pos;
/* Cached values used by scanner_token_location. */
size_t cached_pos;
struct scanner_loc cached_loc;
const char *file_name;
struct xkb_context *ctx;
void *priv;
Expand Down Expand Up @@ -106,6 +109,8 @@ scanner_init(struct scanner *s, struct xkb_context *ctx,
s->len = len;
s->pos = 0;
s->token_pos = 0;
s->cached_pos = 0;
s->cached_loc.line = s->cached_loc.column = 1;
s->file_name = file_name;
s->ctx = ctx;
s->priv = priv;
Expand Down

0 comments on commit 9a00d32

Please sign in to comment.