From ec4d29c4494f32acf0ff7c5632a1d951d957f084 Mon Sep 17 00:00:00 2001 From: Yuan Fu Date: Wed, 30 Aug 2023 20:53:03 -0700 Subject: [PATCH] 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. --- src/treesit.c | 22 +++++++++------------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/src/treesit.c b/src/treesit.c index e359f903f28..19aacc2da7f 100644 --- a/src/treesit.c +++ b/src/treesit.c @@ -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; -- 2.39.2