Skip to content

Commit e6b595e

Browse files
committed
search.js: introduce optimized removeIdxListAsc routine
1 parent a5809b6 commit e6b595e

File tree

1 file changed

+30
-9
lines changed

1 file changed

+30
-9
lines changed

src/librustdoc/html/static/js/search.js

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1076,6 +1076,34 @@ function isPathSeparator(c) {
10761076
return c === ":" || c === " ";
10771077
}
10781078

1079+
/**
1080+
* Given an array and an ascending list of indices,
1081+
* efficiently removes each index in the array.
1082+
*
1083+
* @template T
1084+
* @param {Array<T>} a
1085+
* @param {Array<number>} idxList
1086+
*/
1087+
function removeIdxListAsc(a, idxList) {
1088+
if (idxList.length === 0) {
1089+
return;
1090+
}
1091+
let removed = 0;
1092+
let i = idxList[0];
1093+
let nextToRemove = idxList[0];
1094+
while (i < a.length - idxList.length) {
1095+
while (i === nextToRemove && removed < idxList.length) {
1096+
removed++;
1097+
i++;
1098+
nextToRemove = idxList[removed];
1099+
}
1100+
a[i] = a[i + removed];
1101+
i++;
1102+
}
1103+
// truncate array
1104+
a.length -= idxList.length;
1105+
}
1106+
10791107
/**
10801108
* @template T
10811109
*/
@@ -2610,7 +2638,7 @@ class DocSearch {
26102638
*/
26112639
const transformResults = (results, typeInfo, duplicates) => {
26122640
/** @type {rustdoc.ResultObject[]} */
2613-
let out = [];
2641+
const out = [];
26142642

26152643
// if we match a trait-associated item, we want to go back and
26162644
// remove all the items that are their equivalent but in an impl block.
@@ -2707,16 +2735,9 @@ class DocSearch {
27072735
list.push(out.length);
27082736
traitImplIdxMap.set(obj.traitPath, list);
27092737
} else {
2710-
// FIXME: this is `O(n*m)` because we're repeatedly
2711-
// shifting with Array.splice, but could be `O(n+m)` if
2712-
// we did the shifting manually in a more clever way.
27132738
const toRemove = traitImplIdxMap.get(obj.fullPath);
27142739
if (toRemove) {
2715-
// iterate in reverse order so we don't shift the indexes
2716-
for (let i = toRemove.length - 1; i >= 0; i--) {
2717-
const rmIdx = toRemove[i];
2718-
out = out.splice(rmIdx, 1);
2719-
}
2740+
removeIdxListAsc(out, toRemove);
27202741
}
27212742
traitImplIdxMap.delete(obj.fullPath);
27222743
}

0 commit comments

Comments
 (0)