Improve performance of treesit_cursor_helper_1

* src/treesit.c: (treesit_cursor_helper_1): Use
ts_tree_cursor_goto_first_child_for_byte to speed up traversing among
siblings.  The "while (ts_node_end_byte (cursor_node) < end_pos)" can
be removed with the check added in the loop below.
This commit is contained in:
Yuan Fu 2023-08-30 20:53:03 -07:00
parent f26622b2a4
commit ec4d29c449
No known key found for this signature in database
GPG key ID: 56E19BC57664A442

View file

@ -2876,7 +2876,8 @@ treesit_assume_true (bool val)
limit. */
static bool
treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target,
uint32_t end_pos, ptrdiff_t limit)
uint32_t start_pos, uint32_t end_pos,
ptrdiff_t limit)
{
if (limit <= 0)
return false;
@ -2885,23 +2886,17 @@ treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target,
if (ts_node_eq (cursor_node, *target))
return true;
if (!ts_tree_cursor_goto_first_child (cursor))
if (ts_tree_cursor_goto_first_child_for_byte (cursor, start_pos) == -1)
return false;
/* Skip nodes that definitely don't contain TARGET. */
while (ts_node_end_byte (cursor_node) < end_pos)
{
if (!ts_tree_cursor_goto_next_sibling (cursor))
break;
cursor_node = ts_tree_cursor_current_node (cursor);
}
/* Go through each sibling that could contain TARGET. Because of
missing nodes (their width is 0), there could be multiple
siblings that could contain TARGET. */
while (ts_node_start_byte (cursor_node) <= end_pos)
{
if (treesit_cursor_helper_1 (cursor, target, end_pos, limit - 1))
if (ts_node_end_byte (cursor_node) >= end_pos
&& treesit_cursor_helper_1 (cursor, target, start_pos, end_pos,
limit - 1))
return true;
if (!ts_tree_cursor_goto_next_sibling (cursor))
@ -2933,11 +2928,12 @@ treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target,
static bool
treesit_cursor_helper (TSTreeCursor *cursor, TSNode node, Lisp_Object parser)
{
uint32_t start_pos = ts_node_start_byte (node);
uint32_t end_pos = ts_node_end_byte (node);
TSNode root = ts_tree_root_node (XTS_PARSER (parser)->tree);
*cursor = ts_tree_cursor_new (root);
bool success = treesit_cursor_helper_1 (cursor, &node, end_pos,
treesit_recursion_limit);
bool success = treesit_cursor_helper_1 (cursor, &node, start_pos,
end_pos, treesit_recursion_limit);
if (!success)
ts_tree_cursor_delete (cursor);
return success;