faster SortedList._search
This commit is contained in:
+24
-21
@@ -28,7 +28,7 @@ export class SortedList<T> {
|
|||||||
this._array.push(value);
|
this._array.push(value);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i = this._search(this._getKey(value), 0, this._array.length - 1);
|
i = this._search(this._getKey(value));
|
||||||
this._array.splice(i, 0, value);
|
this._array.splice(i, 0, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ export class SortedList<T> {
|
|||||||
if (key === undefined) {
|
if (key === undefined) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
i = this._search(key, 0, this._array.length - 1);
|
i = this._search(key);
|
||||||
if (i === -1) {
|
if (i === -1) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
@@ -60,7 +60,7 @@ export class SortedList<T> {
|
|||||||
if (this._array.length === 0) {
|
if (this._array.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i = this._search(key, 0, this._array.length - 1);
|
i = this._search(key);
|
||||||
if (i < 0 || i >= this._array.length) {
|
if (i < 0 || i >= this._array.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -76,7 +76,7 @@ export class SortedList<T> {
|
|||||||
if (this._array.length === 0) {
|
if (this._array.length === 0) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
i = this._search(key, 0, this._array.length - 1);
|
i = this._search(key);
|
||||||
if (i < 0 || i >= this._array.length) {
|
if (i < 0 || i >= this._array.length) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -92,23 +92,26 @@ export class SortedList<T> {
|
|||||||
return this._array.values();
|
return this._array.values();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _search(key: number, min: number, max: number): number {
|
private _search(key: number): number {
|
||||||
if (max < min) {
|
let min = 0;
|
||||||
return min;
|
let max = this._array.length - 1;
|
||||||
|
while (max >= min) {
|
||||||
|
let mid = (min + max) >> 1;
|
||||||
|
const midKey = this._getKey(this._array[mid]);
|
||||||
|
if (midKey > key) {
|
||||||
|
max = mid - 1;
|
||||||
|
} else if (midKey < key) {
|
||||||
|
min = mid + 1;
|
||||||
|
} else {
|
||||||
|
// key in list, walk to lowest duplicate
|
||||||
|
while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {
|
||||||
|
mid--;
|
||||||
|
}
|
||||||
|
return mid;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
let mid = Math.floor((min + max) / 2);
|
// key not in list
|
||||||
const midKey = this._getKey(this._array[mid]);
|
// still return closest min (also used as insert position)
|
||||||
if (midKey > key) {
|
return min;
|
||||||
return this._search(key, min, mid - 1);
|
|
||||||
}
|
|
||||||
if (midKey < key) {
|
|
||||||
return this._search(key, mid + 1, max);
|
|
||||||
}
|
|
||||||
// Value found! Since keys can be duplicates, move the result index back to the lowest index
|
|
||||||
// that matches the key.
|
|
||||||
while (mid > 0 && this._getKey(this._array[mid - 1]) === key) {
|
|
||||||
mid--;
|
|
||||||
}
|
|
||||||
return mid;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user