use cache to store char-to-column mapping

This is faster by O(n) to O(n²) compared to the previous algorithm
that would re-compute the column for each call.
This commit is contained in:
2021-12-20 20:09:29 +01:00
parent ffea831e2d
commit ba241b12e0
2 changed files with 18 additions and 4 deletions

View File

@@ -45,7 +45,10 @@ class HighlightSelection(Highlight):
start_column = line.char_to_column(start_char)
end_column = line.char_to_column(end_char)
length_in_columns = end_column - start_column
if end_column >= 0:
length_in_columns = end_column - start_column
else:
length_in_columns = 4096
return [HighlightedRange(start_column, length_in_columns, brush=QBrush(QColor(156, 215, 255, 192)),
pen=Qt.PenStyle.NoPen)]

17
line.py
View File

@@ -1,3 +1,5 @@
from typing import Dict
import constants
@@ -6,6 +8,7 @@ class Line:
self._byte_offset = byte_offset
self._byte_end = byte_end
self._line = line
self._char_to_column_cache = self._cache_char_to_column()
def byte_offset(self) -> int:
return self._byte_offset
@@ -63,17 +66,25 @@ class Line:
return result
# todo this method is slow
def char_to_column(self, char_in_line: int) -> int:
if not char_in_line in self._char_to_column_cache:
# print("%d in %s" % (char_in_line, self._char_to_column_cache))
return -1
return self._char_to_column_cache[char_in_line]
def _cache_char_to_column(self) -> Dict[int, int]:
char_to_column_cache = {}
result = 0
i = 0
while i < char_in_line:
char_to_column_cache[0] = 0
while i < len(self._line):
if i < len(self._line) and self._line[i] == "\t":
result = result + constants.tab_width - result % constants.tab_width
else:
result = result + 1
i = i + 1
return result
char_to_column_cache[i] = result
return char_to_column_cache
def includes_byte(self, byte: int) -> bool:
return self._byte_offset <= byte <= self._byte_end