Bug 1942080, part 4 - Text Fragments: Use NodeIndexCache to further speed up nsContentUtils::ComparePoints(). r=farre,dom-core

`nsContentUtils::ComparePoints()` already has a cache which
keeps the last 100 indices in a stack-allocated array.

This patch makes use of this cache in the hot path.

Differential Revision: https://phabricator.services.mozilla.com/D235557
This commit is contained in:
Jan-Niklas Jaeschke
2025-02-22 19:46:44 +00:00
parent e8f2074681
commit 5a3143f2ec
4 changed files with 13 additions and 9 deletions

View File

@@ -873,6 +873,7 @@ Result<nsTArray<RefPtr<nsRange>>, ErrorResult>
TextDirectiveCreator::FindAllMatchingRanges(const nsString& aSearchQuery) {
MOZ_ASSERT(!aSearchQuery.IsEmpty());
ErrorResult rv;
nsContentUtils::NodeIndexCache nodeIndexCache;
RangeBoundary documentStart{&mDocument, 0u};
RefPtr<nsRange> searchRange =
nsRange::Create(documentStart, mInputRange->EndRef(), rv);
@@ -888,14 +889,14 @@ TextDirectiveCreator::FindAllMatchingRanges(const nsString& aSearchQuery) {
return matchingRanges;
}
RefPtr<nsRange> searchResult = TextDirectiveUtil::FindStringInRange(
searchStart, searchEnd, aSearchQuery, true, true);
searchStart, searchEnd, aSearchQuery, true, true, &nodeIndexCache);
if (!searchResult) {
// This would mean we reached a weird edge case in which the search query
// is not in the search range.
break;
}
if (TextDirectiveUtil::NormalizedRangeBoundariesAreEqual(
searchResult->EndRef(), searchEnd)) {
searchResult->EndRef(), searchEnd, &nodeIndexCache)) {
// It is safe to assume that this algorithm reached the end of all
// potential ranges if the search result is equal to the search query.
// Therefore, this range is not added to the results.

View File

@@ -97,6 +97,7 @@ RefPtr<nsRange> TextDirectiveFinder::FindRangeForTextDirective(
if (rv.Failed()) {
return nullptr;
}
nsContentUtils::NodeIndexCache nodeIndexCache;
// 2. While searchRange is not collapsed:
while (!searchRange->Collapsed()) {
// 2.1. Let potentialMatch be null.
@@ -108,7 +109,7 @@ RefPtr<nsRange> TextDirectiveFinder::FindRangeForTextDirective(
// searchRange, wordStartBounded true and wordEndBounded false.
RefPtr<nsRange> prefixMatch = TextDirectiveUtil::FindStringInRange(
searchRange->StartRef(), searchRange->EndRef(), aTextDirective.prefix,
true, false);
true, false, &nodeIndexCache);
// 2.2.2. If prefixMatch is null, return null.
if (!prefixMatch) {
TEXT_FRAGMENT_LOG(
@@ -213,7 +214,7 @@ RefPtr<nsRange> TextDirectiveFinder::FindRangeForTextDirective(
// wordStartBounded true, and wordEndBounded mustEndAtWordBoundary.
potentialMatch = TextDirectiveUtil::FindStringInRange(
searchRange->StartRef(), searchRange->EndRef(), aTextDirective.start,
true, mustEndAtWordBoundary);
true, mustEndAtWordBoundary, &nodeIndexCache);
// 2.3.3. If potentialMatch is null, return null.
if (!potentialMatch) {
TEXT_FRAGMENT_LOG(
@@ -258,7 +259,7 @@ RefPtr<nsRange> TextDirectiveFinder::FindRangeForTextDirective(
// mustEndAtWordBoundary.
RefPtr<nsRange> endMatch = TextDirectiveUtil::FindStringInRange(
rangeEndSearchRange->StartRef(), rangeEndSearchRange->EndRef(),
aTextDirective.end, true, mustEndAtWordBoundary);
aTextDirective.end, true, mustEndAtWordBoundary, &nodeIndexCache);
// 2.5.1.3. If endMatch is null then return null.
if (!endMatch) {
TEXT_FRAGMENT_LOG(

View File

@@ -425,8 +425,8 @@ TextDirectiveUtil::FindBlockBoundaryInRange(const nsRange& aRange,
}
/* static */ bool TextDirectiveUtil::NormalizedRangeBoundariesAreEqual(
const RangeBoundary& aRangeBoundary1,
const RangeBoundary& aRangeBoundary2) {
const RangeBoundary& aRangeBoundary1, const RangeBoundary& aRangeBoundary2,
nsContentUtils::NodeIndexCache* aCache /* = nullptr */) {
MOZ_ASSERT(aRangeBoundary1.IsSetAndValid() &&
aRangeBoundary2.IsSetAndValid());
if (aRangeBoundary1 == aRangeBoundary2) {
@@ -468,7 +468,8 @@ TextDirectiveUtil::FindBlockBoundaryInRange(const nsRange& aRange,
mozilla::UnsafePreContentIterator iter;
// ContentIterator classes require boundaries to be in correct order.
auto comp = nsContentUtils::ComparePoints(aRangeBoundary1, aRangeBoundary2);
auto comp =
nsContentUtils::ComparePoints(aRangeBoundary1, aRangeBoundary2, aCache);
if (!comp) {
return false;
}

View File

@@ -193,7 +193,8 @@ class TextDirectiveUtil final {
*/
static bool NormalizedRangeBoundariesAreEqual(
const RangeBoundary& aRangeBoundary1,
const RangeBoundary& aRangeBoundary2);
const RangeBoundary& aRangeBoundary2,
nsContentUtils::NodeIndexCache* aCache = nullptr);
/**
* @brief Extends the range boundaries to word boundaries across nodes.