Compare commits

..

3 Commits

Author SHA1 Message Date
be53c209ea cache lines to speed up rendering 2024-04-23 10:28:44 +02:00
aa2bfa967e style fixes 2024-04-22 17:52:15 +02:00
2b91b19ef3 fix test test_column_to_char_ignore_nonspacing_mark_charaters 2024-04-22 17:51:12 +02:00
3 changed files with 38 additions and 11 deletions

View File

@@ -116,7 +116,7 @@ class Line:
# todo there are many other character combinations that should be skipped
while i < len(self._line) and unicodedata.category(self._line[i]) == "Mn":
self._char_to_column_cache[i] = result - 1
if not result in self._column_to_char_cache:
if (result - 1) not in self._column_to_char_cache:
self._column_to_char_cache[result - 1] = i
i = i + 1

View File

@@ -7,6 +7,7 @@ from src.ui.bigtext.highlighting import Highlighting
from src.ui.bigtext.line import Line
import os
from src.settings.settings import Settings
from functools import lru_cache
class LogFileModel:
@@ -21,6 +22,8 @@ class LogFileModel:
range_start = 0
range_end = -1
_line_cache = {}
def __init__(self, file: str, settings: Settings, original_file: str = False):
"""
:param file:
@@ -133,6 +136,13 @@ class LogFileModel:
def _is_word_char(self, char: str) -> bool:
return re.match(r"\w", char) is not None
def prune_cache(self, range_start: int, range_end: int):
for key in list(self._line_cache.keys()):
line = self._line_cache[key]
if range_start > line.byte_end() or line.byte_offset() > range_end:
del self._line_cache[key]
def data(self, byte_offset: int, scroll_lines: int, lines: int, range_start: int, range_end: int) -> List[Line]:
# print("data(%s, %s, %s)" % (byte_offset, scroll_lines, lines))
lines_before_offset: List[Line] = []
@@ -148,19 +158,36 @@ class LogFileModel:
offset = max(0,
max(range_start - self.settings.max_line_length(), offset - self.settings.max_line_length()))
self.prune_cache(range_start, range_end)
previous_line_is_complete = False
f.seek(offset)
while l := f.readline():
while True:
line: Line | None = self._line_cache.get(offset)
if line is None:
line_bytes = f.readline()
if not line_bytes:
break
new_offset = f.tell()
if 0 <= range_end < new_offset:
break
line = Line(offset, new_offset, l.decode("utf8", errors="ignore"))
line = Line(offset, new_offset, line_bytes.decode("utf8", errors="ignore"))
if previous_line_is_complete: # only cache lines when we know they are complete
self._line_cache[offset] = line
offset = new_offset
previous_line_is_complete = True
else:
# print(f"loaded cached line at offset {offset}")
offset = line.byte_end() # line.byte_end() returns the end byte +1
f.seek(offset)
previous_line_is_complete = True
if line.byte_end() <= byte_offset: # line.byte_end() returns the end byte +1
if line.byte_offset() >= range_start: # only add if in range
lines_before_offset.append(line)
else:
lines_after_offset.append(line)
offset = f.tell()
if len(lines_after_offset) >= lines_to_find:
break

View File

@@ -31,9 +31,9 @@ class MyTestCase(unittest.TestCase):
self.assertEqual(9, line.column_to_char(15)) # tab
self.assertEqual(10, line.column_to_char(16)) # g
def test_column_to_char_ignore_nonspacing_mark_charaters(self):
def test_column_to_char_ignore_nonspacing_mark_characters(self):
"""
nonspacing mark charaters are those little decorations that are applied to the previous character,
nonspacing mark characters are those little decorations that are applied to the previous character,
e.g. x\u0308 to make ẍ
:return:
"""
@@ -63,7 +63,7 @@ class MyTestCase(unittest.TestCase):
def test_char_to_column_ignore_nonspacing_mark_charaters(self):
"""
nonspacing mark charaters are those little decorations that are applied to the previous character,
nonspacing mark characters are those little decorations that are applied to the previous character,
e.g. x\u0308 to make ẍ
:return:
"""
@@ -119,7 +119,7 @@ class MyTestCase(unittest.TestCase):
for i in range(128):
if unicodedata.category(chr(i)) == "Cc":
# print(i, " -> ", ord(chr(i)), " --> ", chr(9216 + i))
if not i in [9, 10, 11, 13]:
if i not in [9, 10, 11, 13]:
text = text + chr(i)
line = Line(byte_offset=byte_offset, byte_end=byte_offset + len(text.encode("utf8")), line=text)