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
parent
2e52066293
commit
740fdfa883
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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];
|
||||||
|
|
Loading…
Reference in New Issue