Cog/Utils/RedundantPlaylistDataStore.m
Christopher Snowhill 6222e25adc Experimental tag support redesign
This redesign completely changes how tags are stored in memory. Now all
arbitrary tag names are supported, where possible. Some extra work will
be needed to support arbitrary tags with TagLib, such as replacing it
with a different library.

Translation pending for a couple of strings.

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
2022-07-08 16:34:50 -07:00

93 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