From e63f97bd240df2b6d6a9fc90ca0210ffdf46812e Mon Sep 17 00:00:00 2001 From: Vladimir Agafonkin Date: Wed, 14 Mar 2018 18:54:08 +0200 Subject: [PATCH] optimize location with binary search --- src/utils/getLocator.js | 42 ++++++++++++++++------------------------- 1 file changed, 16 insertions(+), 26 deletions(-) diff --git a/src/utils/getLocator.js b/src/utils/getLocator.js index 3043f12..82a2d35 100644 --- a/src/utils/getLocator.js +++ b/src/utils/getLocator.js @@ -1,35 +1,25 @@ export default function getLocator ( source ) { const originalLines = source.split( '\n' ); + const lineOffsets = []; - let start = 0; - const lineRanges = originalLines.map( ( line, i ) => { - const end = start + line.length + 1; - const range = { start, end, line: i }; - - start = end; - return range; - }); - - let i = 0; - - function rangeContains ( range, index ) { - return range.start <= index && index < range.end; - } - - function getLocation ( range, index ) { - return { line: range.line, column: index - range.start }; + for ( let i = 0, pos = 0; i < originalLines.length; i++ ) { + lineOffsets.push( pos ); + pos += originalLines[i].length + 1; } return function locate ( index ) { - let range = lineRanges[i]; - - const d = index >= range.end ? 1 : -1; - - while ( range ) { - if ( rangeContains( range, index ) ) return getLocation( range, index ); - - i += d; - range = lineRanges[i]; + let i = 0; + let j = lineOffsets.length; + while ( i < j ) { + const m = ( i + j ) >> 1; + if ( index < lineOffsets[m] ) { + j = m; + } else { + i = m + 1; + } } + const line = i - 1; + const column = index - lineOffsets[line]; + return { line, column }; }; }