diff options
| -rw-r--r-- | src/librustdoc/html/static/js/search.js | 39 |
1 files changed, 30 insertions, 9 deletions
diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 71bad967026..9a6d4c710ff 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -1077,6 +1077,34 @@ function isPathSeparator(c) { } /** + * Given an array and an ascending list of indices, + * efficiently removes each index in the array. + * + * @template T + * @param {Array<T>} a + * @param {Array<number>} idxList + */ +function removeIdxListAsc(a, idxList) { + if (idxList.length === 0) { + return; + } + let removed = 0; + let i = idxList[0]; + let nextToRemove = idxList[0]; + while (i < a.length - idxList.length) { + while (i === nextToRemove && removed < idxList.length) { + removed++; + i++; + nextToRemove = idxList[removed]; + } + a[i] = a[i + removed]; + i++; + } + // truncate array + a.length -= idxList.length; +} + +/** * @template T */ class VlqHexDecoder { @@ -2615,7 +2643,7 @@ class DocSearch { */ const transformResults = (results, typeInfo, duplicates) => { /** @type {rustdoc.ResultObject[]} */ - let out = []; + const out = []; // if we match a trait-associated item, we want to go back and // remove all the items that are their equivalent but in an impl block. @@ -2712,16 +2740,9 @@ class DocSearch { list.push(out.length); traitImplIdxMap.set(obj.traitPath, list); } else { - // FIXME: this is `O(n*m)` because we're repeatedly - // shifting with Array.splice, but could be `O(n+m)` if - // we did the shifting manually in a more clever way. const toRemoveList = traitImplIdxMap.get(obj.fullPath); if (toRemoveList) { - // iterate in reverse order so we don't shift the indexes - for (let i = toRemoveList.length - 1; i >= 0; i--) { - const rmIdx = toRemoveList[i]; - out = out.splice(rmIdx, 1); - } + removeIdxListAsc(out, toRemoveList); } traitImplIdxMap.delete(obj.fullPath); } |
