Attempt to wrangle memory usage from artwork

Now cache around NSData objects of individual pieces of album art,
unique by their byte contents. And the artwork image cacher will also
use the art ID keys from the database as the cache keys for NSImages,
so they'll not only be only read once per unique image, but also tracks
can have unique artwork per track, if the files so feature it.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
CQTexperiment
Christopher Snowhill 2022-02-10 22:37:37 -08:00
parent 2e52066293
commit 740fdfa883
4 changed files with 18 additions and 3 deletions

View File

@ -13,6 +13,7 @@
NSInteger shuffleIndex; NSInteger shuffleIndex;
NSInteger dbIndex; NSInteger dbIndex;
NSInteger entryId; NSInteger entryId;
NSInteger artId;
BOOL current; BOOL current;
BOOL removed; BOOL removed;
@ -106,6 +107,7 @@
@property NSInteger shuffleIndex; @property NSInteger shuffleIndex;
@property NSInteger dbIndex; @property NSInteger dbIndex;
@property NSInteger entryId; @property NSInteger entryId;
@property NSInteger artId;
@property(readonly) NSString *status; @property(readonly) NSString *status;
@property(readonly) NSString *statusMessage; @property(readonly) NSString *statusMessage;

View File

@ -15,6 +15,7 @@
@synthesize shuffleIndex; @synthesize shuffleIndex;
@synthesize dbIndex; @synthesize dbIndex;
@synthesize entryId; @synthesize entryId;
@synthesize artId;
@synthesize current; @synthesize current;
@synthesize removed; @synthesize removed;
@ -373,7 +374,7 @@
- (NSImage *)albumArt { - (NSImage *)albumArt {
if(!albumArtInternal || ![albumArtInternal length]) return nil; if(!albumArtInternal || ![albumArtInternal length]) return nil;
NSString *imageCacheTag = [NSString stringWithFormat:@"%@-%@-%@-%@", album, artist, genre, year]; NSString *imageCacheTag = [NSString stringWithFormat:@"%ld", artId];
NSImage *image = [NSImage imageNamed:imageCacheTag]; NSImage *image = [NSImage imageNamed:imageCacheTag];
if(image == nil) { if(image == nil) {
@ -457,6 +458,7 @@
pe->shuffleIndex = shuffleIndex; pe->shuffleIndex = shuffleIndex;
pe->dbIndex = dbIndex; pe->dbIndex = dbIndex;
pe->entryId = entryId; pe->entryId = entryId;
pe->artId = artId;
pe->current = current; pe->current = current;
pe->removed = removed; pe->removed = removed;
@ -482,7 +484,7 @@
pe->cuesheet = [cuesheet copyWithZone:zone]; pe->cuesheet = [cuesheet copyWithZone:zone];
pe->albumArtInternal = [albumArtInternal copyWithZone:zone]; pe->albumArtInternal = albumArtInternal; // Only allocated item not duplicated
pe->replayGainAlbumGain = replayGainAlbumGain; pe->replayGainAlbumGain = replayGainAlbumGain;
pe->replayGainAlbumPeak = replayGainAlbumPeak; pe->replayGainAlbumPeak = replayGainAlbumPeak;

View File

@ -19,6 +19,7 @@
sqlite3_stmt *stmt[39]; sqlite3_stmt *stmt[39];
@private @private
NSMutableArray *databaseMirror; NSMutableArray *databaseMirror;
NSMutableDictionary *artTable;
} }
@property(nonatomic, readwrite) NSString *databasePath; @property(nonatomic, readwrite) NSString *databasePath;

View File

@ -879,6 +879,8 @@ static SQLiteStore *g_sharedStore = NULL;
} }
} }
[artTable setValue:art forKey:[[NSNumber numberWithInteger:ret] stringValue]];
return ret; return ret;
} }
@ -886,6 +888,9 @@ static SQLiteStore *g_sharedStore = NULL;
if(artId < 0) if(artId < 0)
return [NSData data]; return [NSData data];
NSData *ret = [artTable valueForKey:[[NSNumber numberWithInteger:artId] stringValue]];
if(ret) return ret;
sqlite3_stmt *st = stmt[stmt_select_art_value]; sqlite3_stmt *st = stmt[stmt_select_art_value];
if(sqlite3_reset(st) || if(sqlite3_reset(st) ||
@ -900,7 +905,7 @@ static SQLiteStore *g_sharedStore = NULL;
return [NSData data]; return [NSData data];
} }
NSData *ret = [NSData data]; ret = [NSData data];
if(rc == SQLITE_ROW) { if(rc == SQLITE_ROW) {
const void *blob = sqlite3_column_blob(st, select_art_value_out_value); const void *blob = sqlite3_column_blob(st, select_art_value_out_value);
@ -912,6 +917,8 @@ static SQLiteStore *g_sharedStore = NULL;
sqlite3_reset(st); sqlite3_reset(st);
[artTable setValue:ret forKey:[[NSNumber numberWithInteger:artId] stringValue]];
return ret; return ret;
} }
@ -945,6 +952,8 @@ static SQLiteStore *g_sharedStore = NULL;
} }
if(refcount <= 1) { if(refcount <= 1) {
[artTable removeObjectForKey:[[NSNumber numberWithInteger:artId] stringValue]];
st = stmt[stmt_remove_art]; st = stmt[stmt_remove_art];
if(sqlite3_reset(st) || if(sqlite3_reset(st) ||
@ -1361,6 +1370,7 @@ static SQLiteStore *g_sharedStore = NULL;
[entry setReplayGainTrackGain:replaygaintrackgain]; [entry setReplayGainTrackGain:replaygaintrackgain];
[entry setReplayGainTrackPeak:replaygaintrackpeak]; [entry setReplayGainTrackPeak:replaygaintrackpeak];
[entry setArtId:artId];
[entry setAlbumArtInternal:[self getArt:artId]]; [entry setAlbumArtInternal:[self getArt:artId]];
[entry setMetadataLoaded:!!metadataloaded]; [entry setMetadataLoaded:!!metadataloaded];