Handle the caching in the DocSearch class
This commit is contained in:
@@ -26,13 +26,14 @@ along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import shutil
|
||||
import logging
|
||||
import shutil
|
||||
|
||||
from pathlib import Path
|
||||
from functools import partial
|
||||
from zipfile import ZipFile, is_zipfile
|
||||
from collections.abc import Iterable
|
||||
from functools import partial
|
||||
from pathlib import Path
|
||||
from time import time
|
||||
from zipfile import ZipFile, is_zipfile
|
||||
|
||||
from PyQt5.QtCore import QCoreApplication, QRegularExpression
|
||||
|
||||
@@ -315,6 +316,7 @@ class DocSearch:
|
||||
|
||||
# Project Cache
|
||||
self._uuid = ""
|
||||
self._time = 0.0
|
||||
self._cache: dict[str, str] = {}
|
||||
|
||||
return
|
||||
@@ -341,24 +343,15 @@ class DocSearch:
|
||||
self._escape = not state
|
||||
return
|
||||
|
||||
def clearTextCache(self, tHandle: str | None) -> None:
|
||||
"""Clear text cache for a given item, or all items if None."""
|
||||
if tHandle is None:
|
||||
self._cache = {}
|
||||
logger.debug("Search cache cleared")
|
||||
elif tHandle in self._cache:
|
||||
self._cache.pop(tHandle, None)
|
||||
logger.debug("Search cache cleared for '%s'", tHandle)
|
||||
return
|
||||
|
||||
def iterSearch(
|
||||
self, project: NWProject, search: str
|
||||
) -> Iterable[tuple[NWItem, list[tuple[int, int, str]], bool]]:
|
||||
"""Iteratively search through documents in a project."""
|
||||
if project.data.uuid != self._uuid:
|
||||
self.clearTextCache(None)
|
||||
if project.data.uuid != self._uuid or time() - self._time > 20.0:
|
||||
self._cache = {}
|
||||
|
||||
self._uuid = project.data.uuid
|
||||
self._time = time()
|
||||
self._regEx.setPattern(self._buildPattern(search))
|
||||
logger.debug("Searching with pattern '%s'", self._regEx.pattern())
|
||||
|
||||
@@ -367,8 +360,7 @@ class DocSearch:
|
||||
for item in project.tree:
|
||||
if item.isFileType():
|
||||
tHandle = item.itemHandle
|
||||
text = self._cache.get(tHandle)
|
||||
if text is None:
|
||||
if (text := self._cache.get(tHandle)) is None:
|
||||
text = storage.getDocument(tHandle).readDocument() or ""
|
||||
self._cache[tHandle] = text
|
||||
|
||||
|
||||
@@ -91,7 +91,6 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
|
||||
# Custom Signals
|
||||
statusMessage = pyqtSignal(str)
|
||||
docTextSaved = pyqtSignal(str)
|
||||
docCountsChanged = pyqtSignal(str, int, int, int)
|
||||
editedStatusChanged = pyqtSignal(bool)
|
||||
loadDocumentTagRequest = pyqtSignal(str, Enum)
|
||||
@@ -489,7 +488,6 @@ class GuiDocEditor(QPlainTextEdit):
|
||||
return False
|
||||
|
||||
self.setDocumentChanged(False)
|
||||
self.docTextSaved.emit(tHandle)
|
||||
|
||||
oldHeader = self._nwItem.mainHeading
|
||||
oldCount = SHARED.project.index.getHandleHeaderCount(tHandle)
|
||||
|
||||
@@ -48,7 +48,7 @@ class GuiItemDetails(QWidget):
|
||||
logger.debug("Create: GuiItemDetails")
|
||||
|
||||
# Internal Variables
|
||||
self._itemHandle = None
|
||||
self._handle = None
|
||||
|
||||
# Sizes
|
||||
hSp = CONFIG.pxInt(6)
|
||||
@@ -194,7 +194,7 @@ class GuiItemDetails(QWidget):
|
||||
|
||||
def clearDetails(self) -> None:
|
||||
"""Clear all the data values."""
|
||||
self._itemHandle = None
|
||||
self._handle = None
|
||||
self.labelIcon.clear()
|
||||
self.labelData.clear()
|
||||
self.statusIcon.clear()
|
||||
@@ -210,11 +210,11 @@ class GuiItemDetails(QWidget):
|
||||
|
||||
def refreshDetails(self) -> None:
|
||||
"""Reload the content of the details panel."""
|
||||
self.updateViewBox(self._itemHandle)
|
||||
self.updateViewBox(self._handle)
|
||||
|
||||
def updateTheme(self) -> None:
|
||||
"""Update theme elements."""
|
||||
self.updateViewBox(self._itemHandle)
|
||||
self.updateViewBox(self._handle)
|
||||
return
|
||||
|
||||
##
|
||||
@@ -233,7 +233,7 @@ class GuiItemDetails(QWidget):
|
||||
self.clearDetails()
|
||||
return
|
||||
|
||||
self._itemHandle = tHandle
|
||||
self._handle = tHandle
|
||||
iPx = int(round(0.8*SHARED.theme.baseIconSize))
|
||||
|
||||
# Label
|
||||
@@ -295,7 +295,7 @@ class GuiItemDetails(QWidget):
|
||||
"""Update the counts if the handle is the same as the one we're
|
||||
already showing. Otherwise, do nothing.
|
||||
"""
|
||||
if tHandle == self._itemHandle:
|
||||
if tHandle == self._handle:
|
||||
self.cCountData.setText(f"{cC:n}")
|
||||
self.wCountData.setText(f"{wC:n}")
|
||||
self.pCountData.setText(f"{pC:n}")
|
||||
|
||||
@@ -135,8 +135,6 @@ class GuiProjectSearch(QWidget):
|
||||
self.setLayout(self.outerBox)
|
||||
self.updateTheme()
|
||||
|
||||
SHARED.slowClockTick.connect(self._cacheTimeout)
|
||||
|
||||
logger.debug("Ready: GuiProjectSearch")
|
||||
|
||||
return
|
||||
@@ -205,17 +203,6 @@ class GuiProjectSearch(QWidget):
|
||||
super().keyPressEvent(event)
|
||||
return
|
||||
|
||||
##
|
||||
# Public Slots
|
||||
##
|
||||
|
||||
@pyqtSlot(str)
|
||||
def clearSearchCache(self, tHandle: str) -> None:
|
||||
"""Process document content change."""
|
||||
if not self._blocked:
|
||||
self._search.clearTextCache(tHandle)
|
||||
return
|
||||
|
||||
##
|
||||
# Private Slots
|
||||
##
|
||||
@@ -284,13 +271,6 @@ class GuiProjectSearch(QWidget):
|
||||
CONFIG.searchProjRegEx = state
|
||||
return
|
||||
|
||||
@pyqtSlot()
|
||||
def _cacheTimeout(self) -> None:
|
||||
"""Clear the cache after a period of inactivity."""
|
||||
if not self._blocked and time() - self._time > CACHE_TIMEOUT:
|
||||
self._search.clearTextCache(None)
|
||||
return
|
||||
|
||||
##
|
||||
# Internal Functions
|
||||
##
|
||||
|
||||
@@ -262,7 +262,6 @@ class GuiMain(QMainWindow):
|
||||
self.docEditor.requestProjectItemSelected.connect(self.projView.setSelectedHandle)
|
||||
self.docEditor.requestProjectItemRenamed.connect(self.projView.renameTreeItem)
|
||||
self.docEditor.requestNewNoteCreation.connect(self.projView.createNewNote)
|
||||
self.docEditor.docTextSaved.connect(self.projSearch.clearSearchCache)
|
||||
|
||||
self.docViewer.documentLoaded.connect(self.docViewerPanel.updateHandle)
|
||||
self.docViewer.loadDocumentTagRequest.connect(self._followTag)
|
||||
|
||||
Reference in New Issue
Block a user