UNPKG

rxdb

Version:

A local-first realtime NoSQL Database for JavaScript applications - https://rxdb.info/

172 lines (160 loc) 4.65 kB
/** * Optimized binary search functions for the memory storage. * Based on https://github.com/mikolalysenko/binary-search-bounds * but with performance improvements: * - Removed unnecessary undefined checks for comparator * - Inlined the norm() wrapper to avoid extra function calls * - Added string-specialized variants to avoid temporary array allocations */ type Compare<T> = ((a: T, b: T) => number | null | undefined); export function boundGE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number { let l: number = lo === undefined ? 0 : lo | 0; let h: number = hi === undefined ? a.length - 1 : hi | 0; let i: number = h + 1; while (l <= h) { const m = (l + h) >>> 1; if ((c(a[m], y) as number) >= 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } export function boundGT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number { let l: number = lo === undefined ? 0 : lo | 0; let h: number = hi === undefined ? a.length - 1 : hi | 0; let i = h + 1; while (l <= h) { const m = (l + h) >>> 1; if ((c(a[m], y) as number) > 0) { i = m; h = m - 1; } else { l = m + 1; } } return i; } export function boundLT<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number { let l: number = lo === undefined ? 0 : lo | 0; let h: number = hi === undefined ? a.length - 1 : hi | 0; let i = l - 1; while (l <= h) { const m = (l + h) >>> 1; if ((c(a[m], y) as number) < 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } export function boundLE<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number { let l: number = lo === undefined ? 0 : lo | 0; let h: number = hi === undefined ? a.length - 1 : hi | 0; let i = l - 1; while (l <= h) { const m = (l + h) >>> 1; if ((c(a[m], y) as number) <= 0) { i = m; l = m + 1; } else { h = m - 1; } } return i; } export function boundEQ<T>(a: T[], y: T, c: Compare<T>, lo?: any, hi?: any): number { let l: number = lo === undefined ? 0 : lo | 0; let h: number = hi === undefined ? a.length - 1 : hi | 0; while (l <= h) { const m = (l + h) >>> 1; const p = c(a[m], y) as number; if (p === 0) { return m; } if (p <= 0) { l = m + 1; } else { h = m - 1; } } return -1; } /** * Specialized binary search functions that compare DocWithIndexString * entries directly against an index string, avoiding temporary array allocations. * Used in query() and count() hot paths. */ export function boundGEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number { let l = 0; let h = a.length - 1; let i: number = h + 1; while (l <= h) { const m = (l + h) >>> 1; if (a[m][0] >= indexString) { i = m; h = m - 1; } else { l = m + 1; } } return i; } export function boundGTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number { let l = 0; let h = a.length - 1; let i = h + 1; while (l <= h) { const m = (l + h) >>> 1; if (a[m][0] > indexString) { i = m; h = m - 1; } else { l = m + 1; } } return i; } export function boundEQByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number { let l = 0; let h = a.length - 1; while (l <= h) { const m = (l + h) >>> 1; const s = a[m][0]; if (s === indexString) { return m; } if (s < indexString) { l = m + 1; } else { h = m - 1; } } return -1; } export function boundLTByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number { let l = 0; let h = a.length - 1; let i = l - 1; while (l <= h) { const m = (l + h) >>> 1; if (a[m][0] < indexString) { i = m; l = m + 1; } else { h = m - 1; } } return i; } export function boundLEByIndexString<T extends [string, ...any[]]>(a: T[], indexString: string): number { let l = 0; let h = a.length - 1; let i = l - 1; while (l <= h) { const m = (l + h) >>> 1; if (a[m][0] <= indexString) { i = m; l = m + 1; } else { h = m - 1; } } return i; }