From 326de1020dfec075811c41e20093a95bf0d082d9 Mon Sep 17 00:00:00 2001 From: amansaryal Date: Thu, 30 Nov 2023 01:47:33 +0530 Subject: [PATCH] Optimize search start and search end index computation while finding token. Earlier, the code would run through all MentionSpans in the text to determine the span index closest to the cursor on either side. This is rather wasteful and, in the case of getSearchEndIndex(), even unnecessary. The idea is to use text.nextSpanTransition to iterate sequentially over batches of spans and break out of the loop as soon as the closest index is reached. --- .../tokenization/impl/WordTokenizer.java | 34 +++++++++++-------- 1 file changed, 19 insertions(+), 15 deletions(-) diff --git a/spyglass/src/main/java/com/linkedin/android/spyglass/tokenization/impl/WordTokenizer.java b/spyglass/src/main/java/com/linkedin/android/spyglass/tokenization/impl/WordTokenizer.java index 9111e8c..ef2f2b6 100644 --- a/spyglass/src/main/java/com/linkedin/android/spyglass/tokenization/impl/WordTokenizer.java +++ b/spyglass/src/main/java/com/linkedin/android/spyglass/tokenization/impl/WordTokenizer.java @@ -376,12 +376,23 @@ protected int getSearchStartIndex(final @NonNull Spanned text, int cursor) { } // Get index of the end of the last span before the cursor (or 0 if does not exist) - MentionSpan[] spans = text.getSpans(0, text.length(), MentionSpan.class); - int closestToCursor = 0; - for (MentionSpan span : spans) { - int end = text.getSpanEnd(span); - if (end > closestToCursor && end <= cursor) { - closestToCursor = end; + int closestLastSpanEnd = 0; + // iterate over all spans before the cursor + // we do this by finding the next span transition and looking back to find the closest span to the cursor + int nextSpanStart; + for (int searchStartIndex = 0; searchStartIndex < cursor; searchStartIndex = nextSpanStart) { + + // find the next span transition + nextSpanStart = text.nextSpanTransition(searchStartIndex, text.length(), MentionSpan.class); + + // get the spans from searchStartIndex to nextSpanStart + // of these, we find the closest span to the cursor + MentionSpan[] closestLastSpans = text.getSpans(searchStartIndex, nextSpanStart, MentionSpan.class); + for (MentionSpan span : closestLastSpans) { + int end = text.getSpanEnd(span); + if (end > closestLastSpanEnd && end <= cursor) { + closestLastSpanEnd = end; + } } } @@ -393,7 +404,7 @@ protected int getSearchStartIndex(final @NonNull Spanned text, int cursor) { } // Return whichever is closer before to the cursor - return Math.max(closestToCursor, lineStartIndex); + return Math.max(closestLastSpanEnd, lineStartIndex); } /** @@ -411,14 +422,7 @@ protected int getSearchEndIndex(final @NonNull Spanned text, int cursor) { } // Get index of the start of the first span after the cursor (or text.length() if does not exist) - MentionSpan[] spans = text.getSpans(0, text.length(), MentionSpan.class); - int closestAfterCursor = text.length(); - for (MentionSpan span : spans) { - int start = text.getSpanStart(span); - if (start < closestAfterCursor && start >= cursor) { - closestAfterCursor = start; - } - } + int closestAfterCursor = text.nextSpanTransition(cursor, text.length(), MentionSpan.class); // Get the index of the end of the line String textString = text.toString().substring(cursor, text.length());