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 PlaybackController *playbackController;
|
||||
|
||||
NSOperationQueue *containerQueue;
|
||||
NSOperationQueue *queue;
|
||||
|
||||
BOOL metadataLoadInProgress;
|
||||
|
|
|
@ -52,6 +52,9 @@ extern NSMutableDictionary<NSString *, AlbumArtwork *> *kArtworkDictionary;
|
|||
if(self) {
|
||||
[self initDefaults];
|
||||
|
||||
containerQueue = [[NSOperationQueue alloc] init];
|
||||
[containerQueue setMaxConcurrentOperationCount:8];
|
||||
|
||||
queue = [[NSOperationQueue alloc] init];
|
||||
[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 {
|
||||
NSMutableSet *uniqueURLs = [NSMutableSet set];
|
||||
__block NSMutableSet *uniqueURLs = [NSMutableSet set];
|
||||
|
||||
NSMutableArray *expandedURLs = [NSMutableArray array];
|
||||
NSMutableArray *containedURLs = [NSMutableArray array];
|
||||
NSMutableArray *fileURLs = [NSMutableArray array];
|
||||
NSMutableArray *validURLs = [NSMutableArray array];
|
||||
NSMutableArray *folderURLs = [NSMutableArray array];
|
||||
NSMutableArray *dependencyURLs = [NSMutableArray array];
|
||||
NSDictionary *xmlData = nil;
|
||||
__block NSMutableArray *expandedURLs = [[NSMutableArray alloc] init];
|
||||
__block NSMutableArray *containedURLs = [[NSMutableArray alloc] init];
|
||||
__block NSMutableArray *fileURLs = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *validURLs = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *folderURLs = [[NSMutableArray alloc] init];
|
||||
NSMutableArray *dependencyURLs = [[NSMutableArray alloc] init];
|
||||
__block NSDictionary *xmlData = nil;
|
||||
|
||||
BOOL addOtherFilesInFolder = [[NSUserDefaults standardUserDefaults] boolForKey:@"addOtherFilesInFolders"];
|
||||
|
||||
|
@ -422,23 +425,49 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
|
||||
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
|
||||
for(size_t i = 0, j = [expandedURLs count]; i < j; ++i) {
|
||||
NSBlockOperation *op = [[NSBlockOperation alloc] init];
|
||||
|
||||
[op addExecutionBlock:^{
|
||||
id<SentrySpan> pathTask = nil;
|
||||
id<SentrySpan> innerTask = nil;
|
||||
@try {
|
||||
if(containerTask) {
|
||||
pathTask = [containerTask startChildWithOperation:@"Process path as container" description:[NSString stringWithFormat:@"Checking if file is container: %@", url]];
|
||||
if([[self acceptableContainerTypes] containsObject:[[url pathExtension] lowercaseString]]) {
|
||||
id<SentrySpan> innerTask = [pathTask startChildWithOperation:@"Container, processing"];
|
||||
}
|
||||
|
||||
[lock lock];
|
||||
NSURL *url = [expandedURLs objectAtIndex:0];
|
||||
[expandedURLs removeObjectAtIndex:0];
|
||||
[lock unlock];
|
||||
|
||||
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];
|
||||
|
@ -451,7 +480,9 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
}
|
||||
}
|
||||
if(depURLs) {
|
||||
[lock lock];
|
||||
[dependencyURLs addObjectsFromArray:depURLs];
|
||||
[lock unlock];
|
||||
|
||||
for(NSURL *u in depURLs) {
|
||||
if([u isFileURL]) {
|
||||
|
@ -465,29 +496,54 @@ static inline void dispatch_sync_reentrant(dispatch_queue_t queue, dispatch_bloc
|
|||
}
|
||||
} 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];
|
||||
} else if([[[url pathExtension] lowercaseString] isEqualToString:@"xml"]) {
|
||||
xmlData = [XmlContainer entriesForContainerURL:url];
|
||||
} else {
|
||||
[fileURLs addObject:url];
|
||||
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(pathTask) {
|
||||
[pathTask finish];
|
||||
pathTask = nil;
|
||||
}
|
||||
}
|
||||
@catch(id anException) {
|
||||
DLog(@"Exception caught while processing for containers: %@", anException);
|
||||
[SentrySDK captureException:anException];
|
||||
if(innerTask) {
|
||||
[innerTask finishWithStatus:kSentrySpanStatusInternalError];
|
||||
}
|
||||
if(pathTask) {
|
||||
[pathTask finishWithStatus:kSentrySpanStatusInternalError];
|
||||
}
|
||||
}
|
||||
|
||||
progress += progressstep;
|
||||
[self setProgressJobStatus:progress];
|
||||
[lock lock];
|
||||
weakProgress += weakProgressstep;
|
||||
[self setProgressJobStatus:weakProgress];
|
||||
[lock unlock];
|
||||
}];
|
||||
|
||||
[containerQueue addOperation:op];
|
||||
}
|
||||
|
||||
[containerQueue waitUntilAllOperationsAreFinished];
|
||||
|
||||
progress = weakProgress;
|
||||
|
||||
[containerTask finish];
|
||||
}
|
||||
|
||||
progress = 0.0;
|
||||
[self completeProgressJob];
|
||||
|
|
Loading…
Reference in a new issue