Add a metadata loader cache

Promote the Plugin Controller source file to Objective-C++, and add a
simple data cache that holds on to requests for up to 5 seconds after
their last access, for preventing spammed requests from hitting files
over and over. This is apparently really relevant to the CUESheet reader
and its embedded CUESheet handling, as that tends to reread the same
file over and over as it populates the playlist with tracks. The nested
reader can also lead to repeated reading even on files without CUESheets
embedded.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
CQTexperiment
Christopher Snowhill 2022-02-26 23:24:32 -08:00
parent b3247578ed
commit da4630f4c5
4 changed files with 183 additions and 11 deletions

View File

@ -39,8 +39,13 @@
17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17D21EBD0B8BF44000D1EBDE /* AudioPlayer.h in Headers */ = {isa = PBXBuildFile; fileRef = 17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */; settings = {ATTRIBUTES = (Public, ); }; };
17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */; }; 17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */ = {isa = PBXBuildFile; fileRef = 17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */; };
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DD30B8D0F7000A34E87 /* PluginController.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DD30B8D0F7000A34E87 /* PluginController.h */; settings = {ATTRIBUTES = (Public, ); }; };
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.m */; }; 17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */ = {isa = PBXBuildFile; fileRef = 17F94DD40B8D0F7000A34E87 /* PluginController.mm */; };
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; }; 17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */ = {isa = PBXBuildFile; fileRef = 17F94DDC0B8D101100A34E87 /* Plugin.h */; settings = {ATTRIBUTES = (Public, ); }; };
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */; };
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */; };
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */ = {isa = PBXBuildFile; fileRef = 8328995527CB51B700D7F028 /* SHA256Digest.h */; };
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */ = {isa = PBXBuildFile; fileRef = 8328995627CB51B700D7F028 /* SHA256Digest.m */; };
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 8328995927CB51C900D7F028 /* Security.framework */; };
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */; }; 8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */; };
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */; }; 8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */ = {isa = PBXBuildFile; fileRef = 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */; };
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EA27AF8F380063BC83 /* AudioChunk.h */; }; 834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FD4EA27AF8F380063BC83 /* AudioChunk.h */; };
@ -139,9 +144,14 @@
17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AudioPlayer.h; sourceTree = "<group>"; }; 17D21EBB0B8BF44000D1EBDE /* AudioPlayer.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = AudioPlayer.h; sourceTree = "<group>"; };
17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AudioPlayer.m; sourceTree = "<group>"; }; 17D21EBC0B8BF44000D1EBDE /* AudioPlayer.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = AudioPlayer.m; sourceTree = "<group>"; };
17F94DD30B8D0F7000A34E87 /* PluginController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginController.h; sourceTree = "<group>"; }; 17F94DD30B8D0F7000A34E87 /* PluginController.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = PluginController.h; sourceTree = "<group>"; };
17F94DD40B8D0F7000A34E87 /* PluginController.m */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.objc; path = PluginController.m; sourceTree = "<group>"; }; 17F94DD40B8D0F7000A34E87 /* PluginController.mm */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.objcpp; path = PluginController.mm; sourceTree = "<group>"; };
17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; }; 17F94DDC0B8D101100A34E87 /* Plugin.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; path = Plugin.h; sourceTree = "<group>"; };
32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; }; 32DBCF5E0370ADEE00C91783 /* CogAudio_Prefix.pch */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CogAudio_Prefix.pch; sourceTree = "<group>"; };
8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = RedundantPlaylistDataStore.m; path = ../../Utils/RedundantPlaylistDataStore.m; sourceTree = "<group>"; };
8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = RedundantPlaylistDataStore.h; path = ../../Utils/RedundantPlaylistDataStore.h; sourceTree = "<group>"; };
8328995527CB51B700D7F028 /* SHA256Digest.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SHA256Digest.h; path = ../../Utils/SHA256Digest.h; sourceTree = "<group>"; };
8328995627CB51B700D7F028 /* SHA256Digest.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = SHA256Digest.m; path = ../../Utils/SHA256Digest.m; sourceTree = "<group>"; };
8328995927CB51C900D7F028 /* Security.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Security.framework; path = System/Library/Frameworks/Security.framework; sourceTree = SDKROOT; };
8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+CreateFile.h"; path = "../../Utils/NSFileHandle+CreateFile.h"; sourceTree = "<group>"; }; 8347C73F2796C58800FA8A7D /* NSFileHandle+CreateFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSFileHandle+CreateFile.h"; path = "../../Utils/NSFileHandle+CreateFile.h"; sourceTree = "<group>"; };
8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+CreateFile.m"; path = "../../Utils/NSFileHandle+CreateFile.m"; sourceTree = "<group>"; }; 8347C7402796C58800FA8A7D /* NSFileHandle+CreateFile.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSFileHandle+CreateFile.m"; path = "../../Utils/NSFileHandle+CreateFile.m"; sourceTree = "<group>"; };
834FD4EA27AF8F380063BC83 /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioChunk.h; sourceTree = "<group>"; }; 834FD4EA27AF8F380063BC83 /* AudioChunk.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AudioChunk.h; sourceTree = "<group>"; };
@ -190,6 +200,7 @@
isa = PBXFrameworksBuildPhase; isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
8328995A27CB51C900D7F028 /* Security.framework in Frameworks */,
83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */, 83725A9127AA16D50003F694 /* AVFoundation.framework in Frameworks */,
8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */, 8DC2EF570486A6940098B216 /* Cocoa.framework in Frameworks */,
83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */, 83725A9027AA16C90003F694 /* Accelerate.framework in Frameworks */,
@ -264,7 +275,7 @@
839366651815923C006DD712 /* CogPluginMulti.h */, 839366651815923C006DD712 /* CogPluginMulti.h */,
839366661815923C006DD712 /* CogPluginMulti.m */, 839366661815923C006DD712 /* CogPluginMulti.m */,
17F94DD30B8D0F7000A34E87 /* PluginController.h */, 17F94DD30B8D0F7000A34E87 /* PluginController.h */,
17F94DD40B8D0F7000A34E87 /* PluginController.m */, 17F94DD40B8D0F7000A34E87 /* PluginController.mm */,
17D21C750B8BE4BA00D1EBDE /* Chain */, 17D21C750B8BE4BA00D1EBDE /* Chain */,
17D21C9B0B8BE4BA00D1EBDE /* Output */, 17D21C9B0B8BE4BA00D1EBDE /* Output */,
17D21C9E0B8BE4BA00D1EBDE /* Status.h */, 17D21C9E0B8BE4BA00D1EBDE /* Status.h */,
@ -349,6 +360,10 @@
17D21CDC0B8BE5B400D1EBDE /* Utils */ = { 17D21CDC0B8BE5B400D1EBDE /* Utils */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8328995527CB51B700D7F028 /* SHA256Digest.h */,
8328995627CB51B700D7F028 /* SHA256Digest.m */,
8328995227CB511000D7F028 /* RedundantPlaylistDataStore.h */,
8328995127CB510F00D7F028 /* RedundantPlaylistDataStore.m */,
835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */, 835FAC5C27BCA14D00BA8562 /* BadSampleCleaner.h */,
835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */, 835FAC5D27BCA14D00BA8562 /* BadSampleCleaner.m */,
8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */, 8399CF2A27B5D1D4008751F1 /* NSDictionary+Merge.h */,
@ -436,6 +451,7 @@
83725A8F27AA16C90003F694 /* Frameworks */ = { 83725A8F27AA16C90003F694 /* Frameworks */ = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8328995927CB51C900D7F028 /* Security.framework */,
); );
name = Frameworks; name = Frameworks;
sourceTree = "<group>"; sourceTree = "<group>";
@ -470,6 +486,7 @@
17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */, 17D21CA70B8BE4BA00D1EBDE /* Node.h in Headers */,
8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */, 8399CF2C27B5D1D5008751F1 /* NSDictionary+Merge.h in Headers */,
17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */, 17D21CA90B8BE4BA00D1EBDE /* OutputNode.h in Headers */,
8328995427CB511000D7F028 /* RedundantPlaylistDataStore.h in Headers */,
17D21CC50B8BE4BA00D1EBDE /* OutputCoreAudio.h in Headers */, 17D21CC50B8BE4BA00D1EBDE /* OutputCoreAudio.h in Headers */,
834FD4F427AFA2150063BC83 /* Downmix.h in Headers */, 834FD4F427AFA2150063BC83 /* Downmix.h in Headers */,
17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */, 17D21CC70B8BE4BA00D1EBDE /* Status.h in Headers */,
@ -481,6 +498,7 @@
834FD4F027AF93680063BC83 /* ChunkList.h in Headers */, 834FD4F027AF93680063BC83 /* ChunkList.h in Headers */,
17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */, 17F94DD50B8D0F7000A34E87 /* PluginController.h in Headers */,
17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */, 17F94DDD0B8D101100A34E87 /* Plugin.h in Headers */,
8328995727CB51B700D7F028 /* SHA256Digest.h in Headers */,
834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */, 834FD4EB27AF8F380063BC83 /* AudioChunk.h in Headers */,
17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */, 17A2D3C50B8D1D37000778C4 /* AudioDecoder.h in Headers */,
8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */, 8347C7412796C58800FA8A7D /* NSFileHandle+CreateFile.h in Headers */,
@ -590,12 +608,14 @@
17D21CF40B8BE5EF00D1EBDE /* Semaphore.m in Sources */, 17D21CF40B8BE5EF00D1EBDE /* Semaphore.m in Sources */,
8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */, 8347C7422796C58800FA8A7D /* NSFileHandle+CreateFile.m in Sources */,
17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */, 17D21DC80B8BE79700D1EBDE /* CoreAudioUtils.m in Sources */,
8328995327CB511000D7F028 /* RedundantPlaylistDataStore.m in Sources */,
8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */, 8377C64C27B8C51500E8BC0F /* fft_accelerate.c in Sources */,
839366681815923C006DD712 /* CogPluginMulti.m in Sources */, 839366681815923C006DD712 /* CogPluginMulti.m in Sources */,
835C88AA2797D4D400E28EAE /* lpc.c in Sources */, 835C88AA2797D4D400E28EAE /* lpc.c in Sources */,
17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */, 17D21EBE0B8BF44000D1EBDE /* AudioPlayer.m in Sources */,
17F94DD60B8D0F7000A34E87 /* PluginController.m in Sources */, 17F94DD60B8D0F7000A34E87 /* PluginController.mm in Sources */,
17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */, 17A2D3C60B8D1D37000778C4 /* AudioDecoder.m in Sources */,
8328995827CB51B700D7F028 /* SHA256Digest.m in Sources */,
17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */, 17C940240B900909008627D6 /* AudioMetadataReader.m in Sources */,
17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */, 17B619310B909BC300BC003F /* AudioPropertiesReader.m in Sources */,
17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */, 17ADB13D0B97926D00257CA2 /* AudioSource.m in Sources */,

View File

@ -8,6 +8,125 @@
#import "NSDictionary+Merge.h" #import "NSDictionary+Merge.h"
#import "RedundantPlaylistDataStore.h"
#import <chrono>
#import <map>
#import <mutex>
#import <thread>
struct Cached_Metadata {
std::chrono::steady_clock::time_point time_accessed;
NSDictionary *properties;
NSDictionary *metadata;
Cached_Metadata()
: properties(nil), metadata(nil) {
}
};
static std::mutex Cache_Lock;
static std::map<std::string, Cached_Metadata> Cache_List;
static RedundantPlaylistDataStore *Cache_Data_Store = nil;
static bool Cache_Running = false;
static std::thread *Cache_Thread = NULL;
static void cache_run();
static void cache_init() {
Cache_Data_Store = [[RedundantPlaylistDataStore alloc] init];
Cache_Thread = new std::thread(cache_run);
}
static void cache_deinit() {
Cache_Running = false;
Cache_Thread->join();
delete Cache_Thread;
Cache_Data_Store = nil;
}
static void cache_insert_properties(NSURL *url, NSDictionary *properties) {
std::lock_guard<std::mutex> lock(Cache_Lock);
std::string path = [[url absoluteString] UTF8String];
properties = [Cache_Data_Store coalesceEntryInfo:properties];
Cached_Metadata &entry = Cache_List[path];
entry.properties = properties;
entry.time_accessed = std::chrono::steady_clock::now();
}
static void cache_insert_metadata(NSURL *url, NSDictionary *metadata) {
std::lock_guard<std::mutex> lock(Cache_Lock);
std::string path = [[url absoluteString] UTF8String];
metadata = [Cache_Data_Store coalesceEntryInfo:metadata];
Cached_Metadata &entry = Cache_List[path];
entry.metadata = metadata;
entry.time_accessed = std::chrono::steady_clock::now();
}
static NSDictionary *cache_access_properties(NSURL *url) {
std::lock_guard<std::mutex> lock(Cache_Lock);
std::string path = [[url absoluteString] UTF8String];
Cached_Metadata &entry = Cache_List[path];
if(entry.properties) {
entry.time_accessed = std::chrono::steady_clock::now();
return entry.properties;
}
return nil;
}
static NSDictionary *cache_access_metadata(NSURL *url) {
std::lock_guard<std::mutex> lock(Cache_Lock);
std::string path = [[url absoluteString] UTF8String];
Cached_Metadata &entry = Cache_List[path];
if(entry.metadata) {
entry.time_accessed = std::chrono::steady_clock::now();
return entry.metadata;
}
return nil;
}
static void cache_run() {
std::chrono::milliseconds dura(250);
while(Cache_Running) {
std::chrono::steady_clock::time_point now = std::chrono::steady_clock::now();
{
std::lock_guard<std::mutex> lock(Cache_Lock);
for(auto it = Cache_List.begin(); it != Cache_List.end();) {
auto elapsed = std::chrono::duration_cast<std::chrono::seconds>(now - it->second.time_accessed);
if(elapsed.count() >= 10) {
it = Cache_List.erase(it);
continue;
}
++it;
}
if(Cache_List.size() == 0)
[Cache_Data_Store reset];
}
std::this_thread::sleep_for(dura);
}
}
@implementation PluginController @implementation PluginController
@synthesize sources; @synthesize sources;
@ -49,11 +168,17 @@ static PluginController *sharedPluginController = nil;
self.decodersByMimeType = [[NSMutableDictionary alloc] init]; self.decodersByMimeType = [[NSMutableDictionary alloc] init];
[self setup]; [self setup];
cache_init();
} }
return self; return self;
} }
- (void)dealloc {
cache_deinit();
}
- (void)setup { - (void)setup {
if(self.configured == NO) { if(self.configured == NO) {
self.configured = YES; self.configured = YES;
@ -457,6 +582,9 @@ static PluginController *sharedPluginController = nil;
[urlScheme isEqualToString:@"https"]) [urlScheme isEqualToString:@"https"])
return nil; return nil;
NSDictionary *cacheData = cache_access_metadata(url);
if(cacheData) return cacheData;
NSString *ext = [url pathExtension]; NSString *ext = [url pathExtension];
NSArray *readers = [metadataReaders objectForKey:[ext lowercaseString]]; NSArray *readers = [metadataReaders objectForKey:[ext lowercaseString]];
NSString *classString; NSString *classString;
@ -470,9 +598,13 @@ static PluginController *sharedPluginController = nil;
else else
++i; ++i;
} }
return [CogMetadataReaderMulti metadataForURL:url readers:_readers]; cacheData = [CogMetadataReaderMulti metadataForURL:url readers:_readers];
cache_insert_metadata(url, cacheData);
return cacheData;
} }
return [CogMetadataReaderMulti metadataForURL:url readers:readers]; cacheData = [CogMetadataReaderMulti metadataForURL:url readers:readers];
cache_insert_metadata(url, cacheData);
return cacheData;
} else { } else {
classString = [readers objectAtIndex:0]; classString = [readers objectAtIndex:0];
} }
@ -482,7 +614,9 @@ static PluginController *sharedPluginController = nil;
Class metadataReader = NSClassFromString(classString); Class metadataReader = NSClassFromString(classString);
return [metadataReader metadataForURL:url]; cacheData = [metadataReader metadataForURL:url];
cache_insert_metadata(url, cacheData);
return cacheData;
} }
// If no properties reader is defined, use the decoder's properties. // If no properties reader is defined, use the decoder's properties.
@ -493,6 +627,10 @@ static PluginController *sharedPluginController = nil;
return nil; return nil;
NSDictionary *properties = nil; NSDictionary *properties = nil;
properties = cache_access_properties(url);
if(properties) return properties;
NSString *ext = [url pathExtension]; NSString *ext = [url pathExtension];
id<CogSource> source = [self audioSourceForURL:url]; id<CogSource> source = [self audioSourceForURL:url];
@ -504,8 +642,10 @@ static PluginController *sharedPluginController = nil;
if(readers) { if(readers) {
if([readers count] > 1) { if([readers count] > 1) {
properties = [CogPropertiesReaderMulti propertiesForSource:source readers:readers]; properties = [CogPropertiesReaderMulti propertiesForSource:source readers:readers];
if(properties != nil && [properties count]) if(properties != nil && [properties count]) {
cache_insert_properties(url, properties);
return properties; return properties;
}
} else { } else {
classString = [readers objectAtIndex:0]; classString = [readers objectAtIndex:0];
} }
@ -514,8 +654,10 @@ static PluginController *sharedPluginController = nil;
if(readers) { if(readers) {
if([readers count] > 1) { if([readers count] > 1) {
properties = [CogPropertiesReaderMulti propertiesForSource:source readers:readers]; properties = [CogPropertiesReaderMulti propertiesForSource:source readers:readers];
if(properties != nil && [properties count]) if(properties != nil && [properties count]) {
cache_insert_properties(url, properties);
return properties; return properties;
}
} else { } else {
classString = [readers objectAtIndex:0]; classString = [readers objectAtIndex:0];
} }
@ -526,8 +668,10 @@ static PluginController *sharedPluginController = nil;
Class propertiesReader = NSClassFromString(classString); Class propertiesReader = NSClassFromString(classString);
properties = [propertiesReader propertiesForSource:source]; properties = [propertiesReader propertiesForSource:source];
if(properties != nil && [properties count]) if(properties != nil && [properties count]) {
cache_insert_properties(url, properties);
return properties; return properties;
}
} }
{ {
@ -541,7 +685,9 @@ static PluginController *sharedPluginController = nil;
[decoder close]; [decoder close];
return [NSDictionary dictionaryByMerging:properties with:metadata]; NSDictionary *cacheData = [NSDictionary dictionaryByMerging:properties with:metadata];
cache_insert_properties(url, cacheData);
return cacheData;
} }
} }

View File

@ -21,6 +21,7 @@ NS_ASSUME_NONNULL_BEGIN
- (id)init; - (id)init;
- (NSDictionary *)coalesceEntryInfo:(NSDictionary *)pe; - (NSDictionary *)coalesceEntryInfo:(NSDictionary *)pe;
- (void)reset;
@end @end

View File

@ -69,4 +69,9 @@
return [NSDictionary dictionaryWithDictionary:ret]; return [NSDictionary dictionaryWithDictionary:ret];
} }
- (void)reset {
[stringStore removeAllObjects];
[artStore removeAllObjects];
}
@end @end