cog/Utils/RedundantPlaylistDataStore.m

94 lines
2.2 KiB
Objective-C

//
// RedundantPlaylistDataStore.m
// Cog
//
// Created by Christopher Snowhill on 2/16/22.
//
// Coalesce an entryInfo dictionary from tag loading into a common data dictionary, to
// reduce the memory footprint of adding a lot of tracks to the playlist.
#import "RedundantPlaylistDataStore.h"
#import "SHA256Digest.h"
@implementation RedundantPlaylistDataStore
- (id)init {
self = [super init];
if(self) {
stringStore = [[NSMutableArray alloc] init];
artStore = [[NSMutableDictionary alloc] init];
}
return self;
}
- (NSString *)coalesceString:(NSString *)in {
if(in == nil) return in;
NSUInteger index = [stringStore indexOfObject:in];
if(index == NSNotFound) {
[stringStore addObject:in];
return in;
} else {
return [stringStore objectAtIndex:index];
}
}
- (NSData *)coalesceArt:(NSData *)in {
if(in == nil) return in;
NSString *key = [SHA256Digest digestDataAsString:in];
NSData *ret = [artStore objectForKey:key];
if(ret == nil) {
[artStore setObject:in forKey:key];
return in;
} else {
return ret;
}
}
- (NSArray *)coalesceArray:(NSArray *)input {
if(input == nil) return input;
NSMutableArray *array = [[NSMutableArray alloc] init];
for(NSString *string in input) {
[array addObject:[self coalesceString:string]];
}
return [NSArray arrayWithArray:array];
}
- (NSDictionary *)coalesceEntryInfo:(NSDictionary *)entryInfo {
if(entryInfo == nil) return entryInfo;
__block NSMutableDictionary *ret = [[NSMutableDictionary alloc] initWithCapacity:[entryInfo count]];
[entryInfo enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL *_Nonnull stop) {
if([obj isKindOfClass:[NSString class]]) {
NSString *stringObj = (NSString *)obj;
[ret setObject:[self coalesceString:stringObj] forKey:key];
} else if([obj isKindOfClass:[NSData class]]) {
NSData *dataObj = (NSData *)obj;
[ret setObject:[self coalesceArt:dataObj] forKey:key];
} else if([obj isKindOfClass:[NSArray class]]) {
NSArray *arrayObj = (NSArray *)obj;
[ret setObject:[self coalesceArray:arrayObj] forKey:key];
} else {
[ret setObject:obj forKey:key];
}
}];
return [NSDictionary dictionaryWithDictionary:ret];
}
- (void)reset {
[stringStore removeAllObjects];
[artStore removeAllObjects];
}
@end