source: frontend/node_modules/@jridgewell/trace-mapping/src/binary-search.ts

Last change on this file was 9af201e, checked in by MBK <marija.karapandzova@…>, 2 weeks ago

Fix frontend appearance

  • Property mode set to 100644
File size: 2.7 KB
Line 
1import type { SourceMapSegment, ReverseSegment } from './sourcemap-segment';
2import { COLUMN } from './sourcemap-segment';
3
4export type MemoState = {
5 lastKey: number;
6 lastNeedle: number;
7 lastIndex: number;
8};
9
10export let found = false;
11
12/**
13 * A binary search implementation that returns the index if a match is found.
14 * If no match is found, then the left-index (the index associated with the item that comes just
15 * before the desired index) is returned. To maintain proper sort order, a splice would happen at
16 * the next index:
17 *
18 * ```js
19 * const array = [1, 3];
20 * const needle = 2;
21 * const index = binarySearch(array, needle, (item, needle) => item - needle);
22 *
23 * assert.equal(index, 0);
24 * array.splice(index + 1, 0, needle);
25 * assert.deepEqual(array, [1, 2, 3]);
26 * ```
27 */
28export function binarySearch(
29 haystack: SourceMapSegment[] | ReverseSegment[],
30 needle: number,
31 low: number,
32 high: number,
33): number {
34 while (low <= high) {
35 const mid = low + ((high - low) >> 1);
36 const cmp = haystack[mid][COLUMN] - needle;
37
38 if (cmp === 0) {
39 found = true;
40 return mid;
41 }
42
43 if (cmp < 0) {
44 low = mid + 1;
45 } else {
46 high = mid - 1;
47 }
48 }
49
50 found = false;
51 return low - 1;
52}
53
54export function upperBound(
55 haystack: SourceMapSegment[] | ReverseSegment[],
56 needle: number,
57 index: number,
58): number {
59 for (let i = index + 1; i < haystack.length; index = i++) {
60 if (haystack[i][COLUMN] !== needle) break;
61 }
62 return index;
63}
64
65export function lowerBound(
66 haystack: SourceMapSegment[] | ReverseSegment[],
67 needle: number,
68 index: number,
69): number {
70 for (let i = index - 1; i >= 0; index = i--) {
71 if (haystack[i][COLUMN] !== needle) break;
72 }
73 return index;
74}
75
76export function memoizedState(): MemoState {
77 return {
78 lastKey: -1,
79 lastNeedle: -1,
80 lastIndex: -1,
81 };
82}
83
84/**
85 * This overly complicated beast is just to record the last tested line/column and the resulting
86 * index, allowing us to skip a few tests if mappings are monotonically increasing.
87 */
88export function memoizedBinarySearch(
89 haystack: SourceMapSegment[] | ReverseSegment[],
90 needle: number,
91 state: MemoState,
92 key: number,
93): number {
94 const { lastKey, lastNeedle, lastIndex } = state;
95
96 let low = 0;
97 let high = haystack.length - 1;
98 if (key === lastKey) {
99 if (needle === lastNeedle) {
100 found = lastIndex !== -1 && haystack[lastIndex][COLUMN] === needle;
101 return lastIndex;
102 }
103
104 if (needle >= lastNeedle) {
105 // lastIndex may be -1 if the previous needle was not found.
106 low = lastIndex === -1 ? 0 : lastIndex;
107 } else {
108 high = lastIndex;
109 }
110 }
111 state.lastKey = key;
112 state.lastNeedle = needle;
113
114 return (state.lastIndex = binarySearch(haystack, needle, low, high));
115}
Note: See TracBrowser for help on using the repository browser.