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:
@@ -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.
|
||||
|
||||
@@ -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(
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user