Optimization: Perform container checks in queue
Perform the file container checks in an operation queue, since those are a major bottleneck at this point, too. Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
00d861efc0
commit
9fc7c99022
2 changed files with 120 additions and 63 deletions
|
@ -27,6 +27,7 @@ typedef enum {
|
||||||
IBOutlet NSScrollView *playlistView;
|
IBOutlet NSScrollView *playlistView;
|
||||||
IBOutlet PlaybackController *playbackController;
|
IBOutlet PlaybackController *playbackController;
|
||||||
|
|
||||||
|
NSOperationQueue *containerQueue;
|
||||||
NSOperationQueue *queue;
|
NSOperationQueue *queue;
|
||||||
|
|
||||||
BOOL metadataLoadInProgress;
|
BOOL metadataLoadInProgress;
|
||||||
|
|
|
@ -52,6 +52,9 @@ extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
|
||||||
if(self) {
|
if(self) {
|
||||||
[self initDefaults];
|
[self initDefaults];
|
||||||
|
|
||||||
|
containerQueue = [[NSOperationQueue alloc] init];
|
||||||
|
[containerQueue setMaxConcurrentOperationCount:8];
|
||||||
|
|
||||||
queue = [[NSOperationQueue alloc] init];
|
queue = [[NSOperationQueue alloc] init];
|
||||||
[queue setMaxConcurrentOperationCount:8];
|
[queue setMaxConcurrentOperationCount:8];
|
||||||
|
|
||||||
|
@ -335,15 +338,15 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
}
|
}
|
||||||
|
|
||||||
- (NSArray *)insertURLs:(NSArray *)urls atIndex:(NSInteger)index sort:(BOOL)sort {
|
- (NSArray *)insertURLs:(NSArray *)urls atIndex:(NSInteger)index sort:(BOOL)sort {
|
||||||
NSMutableSet *uniqueURLs = [NSMutableSet set];
|
__block NSMutableSet *uniqueURLs = [NSMutableSet set];
|
||||||
|
|
||||||
NSMutableArray *expandedURLs = [NSMutableArray array];
|
__block NSMutableArray *expandedURLs = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *containedURLs = [NSMutableArray array];
|
__block NSMutableArray *containedURLs = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *fileURLs = [NSMutableArray array];
|
__block NSMutableArray *fileURLs = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *validURLs = [NSMutableArray array];
|
NSMutableArray *validURLs = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *folderURLs = [NSMutableArray array];
|
NSMutableArray *folderURLs = [[NSMutableArray alloc] init];
|
||||||
NSMutableArray *dependencyURLs = [NSMutableArray array];
|
NSMutableArray *dependencyURLs = [[NSMutableArray alloc] init];
|
||||||
NSDictionary *xmlData = nil;
|
__block NSDictionary *xmlData = nil;
|
||||||
|
|
||||||
BOOL addOtherFilesInFolder = [[NSUserDefaults standardUserDefaults] boolForKey:@"addOtherFilesInFolders"];
|
BOOL addOtherFilesInFolder = [[NSUserDefaults standardUserDefaults] boolForKey:@"addOtherFilesInFolders"];
|
||||||
|
|
||||||
|
@ -422,73 +425,126 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
||||||
|
|
||||||
progressstep = [expandedURLs count] ? 100.0 / (double)([expandedURLs count]) : 0;
|
progressstep = [expandedURLs count] ? 100.0 / (double)([expandedURLs count]) : 0;
|
||||||
|
|
||||||
id<SentrySpan> containerTask = [mainTask startChildWithOperation:@"Process paths for containers"];
|
if([expandedURLs count]) {
|
||||||
|
__block id<SentrySpan> containerTask = [mainTask startChildWithOperation:@"Process paths for containers"];
|
||||||
|
|
||||||
|
__block NSLock *lock = [[NSLock alloc] init];
|
||||||
|
|
||||||
|
__block NSArray *acceptableContainerTypes = [self acceptableContainerTypes];
|
||||||
|
|
||||||
|
__block double weakProgress = progress;
|
||||||
|
__block double weakProgressstep = progressstep;
|
||||||
|
|
||||||
for(url in expandedURLs) {
|
|
||||||
// Container vs non-container url
|
// Container vs non-container url
|
||||||
id<SentrySpan> pathTask = nil;
|
for(size_t i = 0, j = [expandedURLs count]; i < j; ++i) {
|
||||||
@try {
|
NSBlockOperation *op = [[NSBlockOperation alloc] init];
|
||||||
pathTask = [containerTask startChildWithOperation:@"Process path as container" description:[NSString stringWithFormat:@"Checking if file is container: %@", url]];
|
|
||||||
if([[self acceptableContainerTypes] containsObject:[[url pathExtension] lowercaseString]]) {
|
[op addExecutionBlock:^{
|
||||||
id<SentrySpan> innerTask = [pathTask startChildWithOperation:@"Container, processing"];
|
id<SentrySpan> pathTask = nil;
|
||||||
|
id<SentrySpan> innerTask = nil;
|
||||||
NSArray *urls = [AudioContainer urlsForContainerURL:url];
|
@try {
|
||||||
|
if(containerTask) {
|
||||||
if(urls != nil && [urls count] != 0) {
|
pathTask = [containerTask startChildWithOperation:@"Process path as container" description:[NSString stringWithFormat:@"Checking if file is container: %@", url]];
|
||||||
[containedURLs addObjectsFromArray:urls];
|
|
||||||
|
|
||||||
// Make sure the container isn't added twice.
|
|
||||||
[uniqueURLs addObject:url];
|
|
||||||
|
|
||||||
// Find the dependencies
|
|
||||||
NSArray *depURLs = [AudioContainer dependencyUrlsForContainerURL:url];
|
|
||||||
|
|
||||||
BOOL localFound = NO;
|
|
||||||
for(NSURL *u in urls) {
|
|
||||||
if([u isFileURL]) {
|
|
||||||
localFound = YES;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
if(depURLs) {
|
|
||||||
[dependencyURLs addObjectsFromArray:depURLs];
|
[lock lock];
|
||||||
|
NSURL *url = [expandedURLs objectAtIndex:0];
|
||||||
for(NSURL *u in depURLs) {
|
[expandedURLs removeObjectAtIndex:0];
|
||||||
if([u isFileURL]) {
|
[lock unlock];
|
||||||
localFound = YES;
|
|
||||||
break;
|
if([acceptableContainerTypes containsObject:[[url pathExtension] lowercaseString]]) {
|
||||||
|
if(pathTask) {
|
||||||
|
innerTask = [pathTask startChildWithOperation:@"Container, processing"];
|
||||||
|
}
|
||||||
|
|
||||||
|
NSArray *urls = [AudioContainer urlsForContainerURL:url];
|
||||||
|
|
||||||
|
if(urls != nil && [urls count] != 0) {
|
||||||
|
[lock lock];
|
||||||
|
[containedURLs addObjectsFromArray:urls];
|
||||||
|
[lock unlock];
|
||||||
|
|
||||||
|
// Make sure the container isn't added twice.
|
||||||
|
[lock lock];
|
||||||
|
[uniqueURLs addObject:url];
|
||||||
|
[lock unlock];
|
||||||
|
|
||||||
|
// Find the dependencies
|
||||||
|
NSArray *depURLs = [AudioContainer dependencyUrlsForContainerURL:url];
|
||||||
|
|
||||||
|
BOOL localFound = NO;
|
||||||
|
for(NSURL *u in urls) {
|
||||||
|
if([u isFileURL]) {
|
||||||
|
localFound = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
if(depURLs) {
|
||||||
|
[lock lock];
|
||||||
|
[dependencyURLs addObjectsFromArray:depURLs];
|
||||||
|
[lock unlock];
|
||||||
|
|
||||||
|
for(NSURL *u in depURLs) {
|
||||||
|
if([u isFileURL]) {
|
||||||
|
localFound = YES;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if(localFound) {
|
||||||
|
[[SandboxBroker sharedSandboxBroker] requestFolderForFile:url];
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
/* Fall back on adding the raw file if all container parsers have failed. */
|
||||||
|
[lock lock];
|
||||||
|
[fileURLs addObject:url];
|
||||||
|
[lock unlock];
|
||||||
}
|
}
|
||||||
|
if(innerTask) {
|
||||||
|
[innerTask finish];
|
||||||
|
innerTask = nil;
|
||||||
|
}
|
||||||
|
} else if([[[url pathExtension] lowercaseString] isEqualToString:@"xml"]) {
|
||||||
|
[lock lock];
|
||||||
|
xmlData = [XmlContainer entriesForContainerURL:url];
|
||||||
|
[lock unlock];
|
||||||
|
} else {
|
||||||
|
[lock lock];
|
||||||
|
[fileURLs addObject:url];
|
||||||
|
[lock unlock];
|
||||||
}
|
}
|
||||||
if(localFound) {
|
if(pathTask) {
|
||||||
[[SandboxBroker sharedSandboxBroker] requestFolderForFile:url];
|
[pathTask finish];
|
||||||
|
pathTask = nil;
|
||||||
}
|
}
|
||||||
} else {
|
|
||||||
/* Fall back on adding the raw file if all container parsers have failed. */
|
|
||||||
[fileURLs addObject:url];
|
|
||||||
}
|
}
|
||||||
[innerTask finish];
|
@catch(id anException) {
|
||||||
} else if([[[url pathExtension] lowercaseString] isEqualToString:@"xml"]) {
|
DLog(@"Exception caught while processing for containers: %@", anException);
|
||||||
xmlData = [XmlContainer entriesForContainerURL:url];
|
[SentrySDK captureException:anException];
|
||||||
} else {
|
if(innerTask) {
|
||||||
[fileURLs addObject:url];
|
[innerTask finishWithStatus:kSentrySpanStatusInternalError];
|
||||||
}
|
}
|
||||||
[pathTask finish];
|
if(pathTask) {
|
||||||
}
|
[pathTask finishWithStatus:kSentrySpanStatusInternalError];
|
||||||
@catch(id anException) {
|
}
|
||||||
DLog(@"Exception caught while processing for containers: %@", anException);
|
}
|
||||||
[SentrySDK captureException:anException];
|
|
||||||
if(pathTask) {
|
[lock lock];
|
||||||
[pathTask finishWithStatus:kSentrySpanStatusInternalError];
|
weakProgress += weakProgressstep;
|
||||||
}
|
[self setProgressJobStatus:weakProgress];
|
||||||
|
[lock unlock];
|
||||||
|
}];
|
||||||
|
|
||||||
|
[containerQueue addOperation:op];
|
||||||
}
|
}
|
||||||
|
|
||||||
progress += progressstep;
|
[containerQueue waitUntilAllOperationsAreFinished];
|
||||||
[self setProgressJobStatus:progress];
|
|
||||||
|
progress = weakProgress;
|
||||||
|
|
||||||
|
[containerTask finish];
|
||||||
}
|
}
|
||||||
|
|
||||||
[containerTask finish];
|
|
||||||
|
|
||||||
progress = 0.0;
|
progress = 0.0;
|
||||||
[self completeProgressJob];
|
[self completeProgressJob];
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue