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. */ limit. */
static bool static bool
treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target, 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) if (limit <= 0)
return false; return false;
@ -2885,23 +2886,17 @@ treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target,
if (ts_node_eq (cursor_node, *target)) if (ts_node_eq (cursor_node, *target))
return true; 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; 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 /* Go through each sibling that could contain TARGET. Because of
missing nodes (their width is 0), there could be multiple missing nodes (their width is 0), there could be multiple
siblings that could contain TARGET. */ siblings that could contain TARGET. */
while (ts_node_start_byte (cursor_node) <= end_pos) 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; return true;
if (!ts_tree_cursor_goto_next_sibling (cursor)) if (!ts_tree_cursor_goto_next_sibling (cursor))
@ -2933,11 +2928,12 @@ treesit_cursor_helper_1 (TSTreeCursor *cursor, TSNode *target,
static bool static bool
treesit_cursor_helper (TSTreeCursor *cursor, TSNode node, Lisp_Object parser) 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); uint32_t end_pos = ts_node_end_byte (node);
TSNode root = ts_tree_root_node (XTS_PARSER (parser)->tree); TSNode root = ts_tree_root_node (XTS_PARSER (parser)->tree);
*cursor = ts_tree_cursor_new (root); *cursor = ts_tree_cursor_new (root);
bool success = treesit_cursor_helper_1 (cursor, &node, end_pos, bool success = treesit_cursor_helper_1 (cursor, &node, start_pos,
treesit_recursion_limit); end_pos, treesit_recursion_limit);
if (!success) if (!success)
ts_tree_cursor_delete (cursor); ts_tree_cursor_delete (cursor);
return success; return success;