Felix Paul Kühne pushed to branch master at VideoLAN / VLC
Commits:
5a928423 by Claudio Cambra at 2026-01-11T16:37:43+01:00
macosx: Add VLCLibraryNameCache
Signed-off-by: Claudio Cambra <[email protected]>
- - - - -
79f8a58e by Claudio Cambra at 2026-01-11T16:37:43+01:00
macosx: Leverage name cache for artists name in library item
Signed-off-by: Claudio Cambra <[email protected]>
- - - - -
1aba1ab2 by Claudio Cambra at 2026-01-11T16:37:43+01:00
macosx: Use cache for audio table view delegate and songs table view
Signed-off-by: Claudio Cambra <[email protected]>
- - - - -
80e62b79 by Claudio Cambra at 2026-01-11T16:37:43+01:00
macosx: Limit VLCLibraryNameCache cache sizes to 1MB
Signed-off-by: Claudio Cambra <[email protected]>
- - - - -
5 changed files:
- modules/gui/macosx/Makefile.am
- modules/gui/macosx/library/VLCLibraryDataTypes.m
- + modules/gui/macosx/library/VLCLibraryNameCache.h
- + modules/gui/macosx/library/VLCLibraryNameCache.m
- modules/gui/macosx/library/audio-library/VLCLibraryAudioTableViewDelegate.m
Changes:
=====================================
modules/gui/macosx/Makefile.am
=====================================
@@ -170,6 +170,8 @@ libmacosx_plugin_la_SOURCES = \
gui/macosx/library/VLCLibraryDataSource.h \
gui/macosx/library/VLCLibraryDataTypes.h \
gui/macosx/library/VLCLibraryDataTypes.m \
+ gui/macosx/library/VLCLibraryNameCache.h \
+ gui/macosx/library/VLCLibraryNameCache.m \
gui/macosx/library/VLCLibraryHeroView.h \
gui/macosx/library/VLCLibraryHeroView.m \
gui/macosx/library/VLCLibraryImageCache.h \
=====================================
modules/gui/macosx/library/VLCLibraryDataTypes.m
=====================================
@@ -26,6 +26,7 @@
#import "extensions/NSString+Helpers.h"
#import "library/VLCInputItem.h"
#import "library/VLCLibraryController.h"
+#import "library/VLCLibraryNameCache.h"
#import <vlc_media_library.h>
#import <vlc_url.h>
@@ -1355,10 +1356,7 @@ static NSString
*genreArrayDisplayString(NSArray<VLCMediaLibraryGenre *> * const
case VLC_ML_MEDIA_SUBTYPE_MOVIE:
return self.inputItem.director;
case VLC_ML_MEDIA_SUBTYPE_ALBUMTRACK:
- {
- VLCMediaLibraryArtist * const artist = [VLCMediaLibraryArtist
artistWithID:_artistID];
- return artist.name;
- }
+ return [VLCLibraryNameCache.sharedInstance artistNameForID:_artistID];
default:
return nil;
}
=====================================
modules/gui/macosx/library/VLCLibraryNameCache.h
=====================================
@@ -0,0 +1,43 @@
+/*****************************************************************************
+ * VLCLibraryNameCache.h: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301,
USA.
+ *****************************************************************************/
+
+#import <Foundation/Foundation.h>
+
+NS_ASSUME_NONNULL_BEGIN
+
+@interface VLCLibraryNameCache : NSObject
+
++ (instancetype)sharedInstance;
+
+- (nullable NSString *)albumTitleForID:(int64_t)albumID;
+- (nullable NSString *)albumArtistForID:(int64_t)albumID;
+- (nullable NSString *)artistNameForID:(int64_t)artistID;
+- (nullable NSString *)genreNameForID:(int64_t)genreID;
+
+- (void)invalidateAlbumWithID:(int64_t)albumID;
+- (void)invalidateArtistWithID:(int64_t)artistID;
+- (void)invalidateGenreWithID:(int64_t)genreID;
+- (void)invalidateAll;
+
+@end
+
+NS_ASSUME_NONNULL_END
=====================================
modules/gui/macosx/library/VLCLibraryNameCache.m
=====================================
@@ -0,0 +1,231 @@
+/*****************************************************************************
+ * VLCLibraryNameCache.m: MacOS X interface module
+ *****************************************************************************
+ * Copyright (C) 2025 VLC authors and VideoLAN
+ *
+ * Authors: Claudio Cambra <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301,
USA.
+ *****************************************************************************/
+
+#import "VLCLibraryNameCache.h"
+
+#import "VLCLibraryDataTypes.h"
+#import "VLCLibraryModel.h"
+#import "extensions/NSString+Helpers.h"
+
+#include <vlc_media_library.h>
+
+const NSUInteger kVLCMaximumLibraryNameCacheSize = 1024 * 1024 * 1; // 1MB
+
+@implementation VLCLibraryNameCache {
+ NSCache<NSNumber *, NSString *> *_albumTitleCache;
+ NSCache<NSNumber *, NSString *> *_albumArtistCache;
+ NSCache<NSNumber *, NSString *> *_artistNameCache;
+ NSCache<NSNumber *, NSString *> *_genreNameCache;
+}
+
++ (instancetype)sharedInstance
+{
+ static VLCLibraryNameCache *instance = nil;
+ static dispatch_once_t onceToken;
+ dispatch_once(&onceToken, ^{
+ instance = [[VLCLibraryNameCache alloc] init];
+ });
+ return instance;
+}
+
+- (instancetype)init
+{
+ self = [super init];
+ if (self) {
+ _albumTitleCache = [NSCache new];
+ _albumArtistCache = [NSCache new];
+ _artistNameCache = [NSCache new];
+ _genreNameCache = [NSCache new];
+
+ _albumTitleCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
+ _albumArtistCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
+ _artistNameCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
+ _genreNameCache.totalCostLimit = kVLCMaximumLibraryNameCacheSize;
+
+ NSNotificationCenter * const center =
NSNotificationCenter.defaultCenter;
+ [center addObserver:self
+ selector:@selector(handleAlbumUpdate:)
+ name:VLCLibraryModelAlbumUpdated
+ object:nil];
+ [center addObserver:self
+ selector:@selector(handleGenreUpdate:)
+ name:VLCLibraryModelGenreUpdated
+ object:nil];
+ [center addObserver:self
+ selector:@selector(handleArtistUpdate:)
+ name:VLCLibraryModelArtistUpdated
+ object:nil];
+ }
+ return self;
+}
+
+- (void)dealloc
+{
+ [NSNotificationCenter.defaultCenter removeObserver:self];
+}
+
+- (void)handleAlbumUpdate:(NSNotification *)notification
+{
+ [self invalidateAlbumWithID:((VLCMediaLibraryAlbum
*)notification.object).libraryID];
+}
+
+- (void)handleGenreUpdate:(NSNotification *)notification
+{
+ [self invalidateGenreWithID:((VLCMediaLibraryGenre
*)notification.object).libraryID];
+}
+
+- (void)handleArtistUpdate:(NSNotification *)notification
+{
+ [self invalidateArtistWithID:((VLCMediaLibraryArtist
*)notification.object).libraryID];
+}
+
+- (NSString *)albumTitleForID:(int64_t)albumID
+{
+ if (albumID <= 0) {
+ return nil;
+ }
+
+ NSNumber * const key = @(albumID);
+ NSString * const cached = [_albumTitleCache objectForKey:key];
+ if (cached) {
+ return cached;
+ }
+
+ vlc_medialibrary_t * const p_ml = getMediaLibrary();
+ if (!p_ml) {
+ return nil;
+ }
+
+ vlc_ml_album_t * const p_album = vlc_ml_get_album(p_ml, albumID);
+ if (!p_album) {
+ return nil;
+ }
+
+ NSString * const title = toNSStr(p_album->psz_title);
+ NSString * const artist = toNSStr(p_album->psz_artist);
+
+ [_albumTitleCache setObject:title forKey:key];
+ [_albumArtistCache setObject:artist forKey:key];
+
+ vlc_ml_album_release(p_album);
+ return title;
+}
+
+- (NSString *)albumArtistForID:(int64_t)albumID
+{
+ if (albumID <= 0) {
+ return nil;
+ }
+
+ NSNumber * const key = @(albumID);
+ NSString * const cached = [_albumArtistCache objectForKey:key];
+ if (cached) {
+ return cached;
+ }
+
+ [self albumTitleForID:albumID];
+ return [_albumArtistCache objectForKey:key];
+}
+
+- (NSString *)genreNameForID:(int64_t)genreID
+{
+ if (genreID <= 0) {
+ return nil;
+ }
+
+ NSNumber * const key = @(genreID);
+ NSString * const cached = [_genreNameCache objectForKey:key];
+ if (cached) {
+ return cached;
+ }
+
+ vlc_medialibrary_t * const p_ml = getMediaLibrary();
+ if (!p_ml) {
+ return nil;
+ }
+
+ vlc_ml_genre_t * const p_genre = vlc_ml_get_genre(p_ml, genreID);
+ if (!p_genre) {
+ return nil;
+ }
+
+ NSString * const name = toNSStr(p_genre->psz_name);
+ [_genreNameCache setObject:name forKey:key];
+
+ vlc_ml_genre_release(p_genre);
+ return name;
+}
+
+- (NSString *)artistNameForID:(int64_t)artistID
+{
+ if (artistID <= 0) {
+ return nil;
+ }
+
+ NSNumber * const key = @(artistID);
+ NSString * const cached = [_artistNameCache objectForKey:key];
+ if (cached) {
+ return cached;
+ }
+
+ vlc_medialibrary_t * const p_ml = getMediaLibrary();
+ if (!p_ml) {
+ return nil;
+ }
+
+ vlc_ml_artist_t * const p_artist = vlc_ml_get_artist(p_ml, artistID);
+ if (!p_artist) {
+ return nil;
+ }
+
+ NSString * const name = toNSStr(p_artist->psz_name);
+ [_artistNameCache setObject:name forKey:key];
+
+ vlc_ml_artist_release(p_artist);
+ return name;
+}
+
+- (void)invalidateAlbumWithID:(int64_t)albumID
+{
+ [_albumTitleCache removeObjectForKey:@(albumID)];
+ [_albumArtistCache removeObjectForKey:@(albumID)];
+}
+
+- (void)invalidateGenreWithID:(int64_t)genreID
+{
+ [_genreNameCache removeObjectForKey:@(genreID)];
+}
+
+- (void)invalidateArtistWithID:(int64_t)artistID
+{
+ [_artistNameCache removeObjectForKey:@(artistID)];
+}
+
+- (void)invalidateAll
+{
+ [_albumTitleCache removeAllObjects];
+ [_albumArtistCache removeAllObjects];
+ [_artistNameCache removeAllObjects];
+ [_genreNameCache removeAllObjects];
+}
+
+@end
=====================================
modules/gui/macosx/library/audio-library/VLCLibraryAudioTableViewDelegate.m
=====================================
@@ -28,6 +28,7 @@
#import "VLCLibrarySongsTableViewSongPlayingTableCellView.h"
#import "library/VLCLibraryDataTypes.h"
+#import "library/VLCLibraryNameCache.h"
#import "library/VLCLibraryTableCellView.h"
@implementation VLCLibraryAudioTableViewDelegate
@@ -70,8 +71,10 @@
return nil;
}
- const VLCMediaLibraryAlbum * const album = [VLCMediaLibraryAlbum
albumWithID:mediaItem.albumID];
- const VLCMediaLibraryGenre * const genre = [VLCMediaLibraryGenre
genreWithID:mediaItem.genreID];
+ VLCLibraryNameCache * const cache = VLCLibraryNameCache.sharedInstance;
+ NSString * const albumArtist = [cache
albumArtistForID:mediaItem.albumID];
+ NSString * const albumTitle = [cache
albumTitleForID:mediaItem.albumID];
+ NSString * const genreName = [cache genreNameForID:mediaItem.genreID];
NSString *cellText = @"";
NSString *cellIdentifier = @"";
@@ -89,13 +92,13 @@
cellText = mediaItem.durationString;
} else if ([columnIdentifier
isEqualToString:VLCLibrarySongsTableViewArtistColumnIdentifier]) {
cellIdentifier =
@"VLCLibrarySongsTableViewArtistTableCellViewIdentifier";
- cellText = album.artistName.length == 0 ? @"" : album.artistName;
+ cellText = albumArtist.length == 0 ? @"" : albumArtist;
} else if ([columnIdentifier
isEqualToString:VLCLibrarySongsTableViewAlbumColumnIdentifier]) {
cellIdentifier =
@"VLCLibrarySongsTableViewAlbumTableCellViewIdentifier";
- cellText = album.title.length == 0 ? @"" : album.title;
+ cellText = albumTitle.length == 0 ? @"" : albumTitle;
} else if ([columnIdentifier
isEqualToString:VLCLibrarySongsTableViewGenreColumnIdentifier]) {
cellIdentifier =
@"VLCLibrarySongsTableViewGenreTableCellViewIdentifier";
- cellText = genre.name.length == 0 ? @"" : genre.name;
+ cellText = genreName.length == 0 ? @"" : genreName;
} else if ([columnIdentifier
isEqualToString:VLCLibrarySongsTableViewPlayCountColumnIdentifier]) {
cellIdentifier =
@"VLCLibrarySongsTableViewPlayCountTableCellViewIdentifier";
cellText = [@(mediaItem.playCount) stringValue];
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/f8cb176dc616e21e9aff4a7bad6963894cbf1e9f...80e62b79d0bf7ea35c158c5c0bb21a40b2878dd9
--
View it on GitLab:
https://code.videolan.org/videolan/vlc/-/compare/f8cb176dc616e21e9aff4a7bad6963894cbf1e9f...80e62b79d0bf7ea35c158c5c0bb21a40b2878dd9
You're receiving this email because of your account on code.videolan.org.
VideoLAN code repository instance_______________________________________________
vlc-commits mailing list
[email protected]
https://mailman.videolan.org/listinfo/vlc-commits