[ui] maximum number of thumbnails on disk

This commit is contained in:
Loïc Vital 2023-01-06 15:24:50 +01:00
parent a96d886923
commit 220bcfb9e2
2 changed files with 38 additions and 7 deletions

View file

@ -122,9 +122,14 @@ class MeshroomApp(QApplication):
ThumbnailCache.thumbnailDir = thumbnailDir ThumbnailCache.thumbnailDir = thumbnailDir
# User specifed time limit for thumbnails on disk (expressed in days) # User specifed time limit for thumbnails on disk (expressed in days)
thumbnailTimeLimit = float(os.getenv('MESHROOM_THUMBNAIL_TIME_LIMIT')) thumbnailTimeLimit = os.getenv('MESHROOM_THUMBNAIL_TIME_LIMIT')
if thumbnailTimeLimit is not None: if thumbnailTimeLimit is not None:
ThumbnailCache.storageTimeLimit = thumbnailTimeLimit ThumbnailCache.storageTimeLimit = float(thumbnailTimeLimit)
# User specifed maximum number of thumbnails on disk
thumbnailMaxNumberOnDisk = os.getenv('MESHROOM_MAX_THUMBNAILS_ON_DISK')
if thumbnailMaxNumberOnDisk is not None:
ThumbnailCache.maxThumbnailsOnDisk = int(thumbnailMaxNumberOnDisk)
# Clean thumbnail directory # Clean thumbnail directory
ThumbnailCache.clean() ThumbnailCache.clean()

View file

@ -21,8 +21,14 @@ class ThumbnailCache(QObject):
This class also takes care of cleaning the thumbnail directory, This class also takes care of cleaning the thumbnail directory,
i.e. scanning this directory and removing thumbnails that have not been used for too long. i.e. scanning this directory and removing thumbnails that have not been used for too long.
The default time limit is 90 days. This operation also ensures that the number of thumbnails on disk does not exceed a certain limit,
This time limit can be overriden with the MESHROOM_THUMBNAIL_TIME_LIMIT environment variable. by removing thumbnails if necessary (from least recently used to most recently used).
The default time limit is 90 days,
and can be overriden with the MESHROOM_THUMBNAIL_TIME_LIMIT environment variable.
The default maximum number of thumbnails on disk is 100000,
and can be overriden with the MESHROOM_MAX_THUMBNAILS_ON_DISK.
The main use case for thumbnails in Meshroom is in the ImageGallery. The main use case for thumbnails in Meshroom is in the ImageGallery.
""" """
@ -36,6 +42,9 @@ class ThumbnailCache(QObject):
# Time limit for thumbnail storage on disk, expressed in days # Time limit for thumbnail storage on disk, expressed in days
storageTimeLimit = 90 storageTimeLimit = 90
# Maximum number of thumbnails in the cache directory
maxThumbnailsOnDisk = 100000
@Slot(QUrl, result=QUrl) @Slot(QUrl, result=QUrl)
def thumbnail(self, imgSource): def thumbnail(self, imgSource):
""" """
@ -100,8 +109,9 @@ class ThumbnailCache(QObject):
@staticmethod @staticmethod
def clean(): def clean():
""" """
Scan the thumbnail directory and Scan the thumbnail directory and:
remove all thumbnails that have not been used for more than storageTimeLimit days. 1. remove all thumbnails that have not been used for more than storageTimeLimit days
2. ensure that the number of thumbnails on disk does not exceed maxThumbnailsOnDisk.
""" """
# Check if thumbnail directory exists # Check if thumbnail directory exists
if not os.path.exists(ThumbnailCache.thumbnailDir): if not os.path.exists(ThumbnailCache.thumbnailDir):
@ -113,6 +123,7 @@ class ThumbnailCache(QObject):
# Scan thumbnail directory and gather all thumbnails to remove # Scan thumbnail directory and gather all thumbnails to remove
toRemove = [] toRemove = []
remaining = []
for entry in os.scandir(ThumbnailCache.thumbnailDir): for entry in os.scandir(ThumbnailCache.thumbnailDir):
if not entry.is_file(): if not entry.is_file():
continue continue
@ -122,12 +133,27 @@ class ThumbnailCache(QObject):
storageTime = now - lastUsage storageTime = now - lastUsage
logging.debug(f'[ThumbnailCache] Thumbnail {entry.name} has been stored for {storageTime}s') logging.debug(f'[ThumbnailCache] Thumbnail {entry.name} has been stored for {storageTime}s')
# Mark as removable if storage time exceeds limit
if storageTime > ThumbnailCache.storageTimeLimit * 3600 * 24: if storageTime > ThumbnailCache.storageTimeLimit * 3600 * 24:
# Mark as removable if storage time exceeds limit
logging.debug(f'[ThumbnailCache] {entry.name} exceeded storage time limit') logging.debug(f'[ThumbnailCache] {entry.name} exceeded storage time limit')
toRemove.append(entry.path) toRemove.append(entry.path)
else:
# Store path and last usage time for potentially sorting and removing later
remaining.append((entry.path, lastUsage))
# Remove all thumbnails marked as removable # Remove all thumbnails marked as removable
for path in toRemove: for path in toRemove:
logging.debug(f'[ThumbnailCache] Remove {path}') logging.debug(f'[ThumbnailCache] Remove {path}')
os.remove(path) os.remove(path)
# Check if number of thumbnails on disk exceeds limit
if len(remaining) > ThumbnailCache.maxThumbnailsOnDisk:
nbToRemove = len(remaining) - ThumbnailCache.maxThumbnailsOnDisk
logging.debug(f'[ThumbnailCache] Too many thumbnails: {len(remaining)} remaining, {nbToRemove} will be removed')
# Sort by last usage order and remove excess
remaining.sort(key=lambda elt: elt[1])
for i in range(nbToRemove):
path = remaining[i][0]
logging.debug(f'[ThumbnailCache] Remove {path}')
os.remove(path)