Add in memory caching for the patch cache

Just use @lru_cache() to keep it, and just discard it entirely on any change. Nothing clever, but this should allow for quick lookups from StoreItem.

I am not caching the actual missing status because the user could fix this by renaming things, and that would leave us with a stale cache. Let us hope we don't need that cached.
This commit is contained in:
Daniel Johnson 2023-07-09 09:56:45 -04:00
parent 668cd25220
commit b9b96a4f0c
3 changed files with 22 additions and 13 deletions

View file

@ -1,11 +1,10 @@
"""Game representation for views"""
import os
import time
from lutris.database import games
from lutris.database.games import get_service_games
from lutris.runners import get_runner_human_name
from lutris.scanners.lutris import get_path_cache
from lutris.scanners.lutris import is_game_missing
from lutris.services import SERVICES
from lutris.util.log import logger
from lutris.util.strings import get_formatted_playtime, gtk_safe
@ -121,13 +120,7 @@ class StoreItem:
@property
def missing(self):
"""Game is installed, but its directory is not found."""
if self.installed:
cache = get_path_cache()
id = self.id
path = cache.get(str(id))
if path and not os.path.exists(path):
return True
return False
return self.installed and is_game_missing(self.id)
def get_media_path(self):
"""Returns the path to the image file for this item"""

View file

@ -351,7 +351,6 @@ class GridViewCellRendererImage(Gtk.CellRenderer):
font = layout.get_context().get_font_description()
font.set_weight(Pango.Weight.BOLD)
font.set_absolute_size(self.badge_size[1] * Pango.SCALE * 3 / 4)
v = font.get_size_is_absolute()
layout.set_font_description(font)
_, text_bounds = layout.get_extents()
text_width = text_bounds.width / Pango.SCALE

View file

@ -1,6 +1,7 @@
import json
import os
import time
from functools import lru_cache
from lutris import settings
from lutris.api import get_api_games, get_game_installers
@ -150,6 +151,7 @@ def build_path_cache(recreate=False):
game_paths = get_game_paths()
json.dump(game_paths, cache_file, indent=2)
end_time = time.time()
get_path_cache.cache_clear()
logger.debug("Game path cache built in %0.2f seconds", end_time - start_time)
@ -160,25 +162,34 @@ def add_to_path_cache(game):
if not path:
logger.warning("No path for %s", game)
return
current_cache = get_path_cache()
current_cache = read_path_cache()
current_cache[game.id] = path
with open(GAME_PATH_CACHE_PATH, "w", encoding="utf-8") as cache_file:
json.dump(current_cache, cache_file, indent=2)
get_path_cache.cache_clear()
def remove_from_path_cache(game):
logger.debug("Removing %s from path cache", game)
current_cache = get_path_cache()
current_cache = read_path_cache()
if str(game.id) not in current_cache:
logger.warning("Game %s (id=%s) not in cache path", game, game.id)
return
del current_cache[str(game.id)]
with open(GAME_PATH_CACHE_PATH, "w", encoding="utf-8") as cache_file:
json.dump(current_cache, cache_file, indent=2)
get_path_cache.cache_clear()
@lru_cache()
def get_path_cache():
"""Return the contents of the path cache file"""
"""Return the contents of the path cache file; this
dict is cached, so do not modify it."""
return read_path_cache()
def read_path_cache():
"""Read the contents of the path cache file, and does not cache it."""
with open(GAME_PATH_CACHE_PATH, encoding="utf-8") as cache_file:
try:
return json.load(cache_file)
@ -194,3 +205,9 @@ def get_missing_game_ids():
if not os.path.exists(path):
missing_ids.append(game_id)
return missing_ids
def is_game_missing(game_id):
cache = get_path_cache()
path = cache.get(str(game_id))
return path and not os.path.exists(path)