Don't cache CNContact.

pull/1/head
Matthew Chen 7 years ago
parent d3d9d2e64c
commit b9e2963f47

@ -36,7 +36,7 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification
@property (nonatomic, readonly) SystemContactsFetcher *systemContactsFetcher;
@property (nonatomic, readonly) YapDatabaseConnection *dbReadConnection;
@property (nonatomic, readonly) YapDatabaseConnection *dbWriteConnection;
@property (nonatomic, readonly) NSCache<NSString *, CNContact *> *cnContactCache;
@property (nonatomic, readonly) AnyLRUCache *cnContactCache;
@end
@ -61,8 +61,7 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification
_signalAccounts = @[];
_systemContactsFetcher = [SystemContactsFetcher new];
_systemContactsFetcher.delegate = self;
_cnContactCache = [NSCache new];
_cnContactCache.countLimit = 50;
_cnContactCache = [[AnyLRUCache alloc] initWithMaxSize:50];
OWSSingletonAssert();
@ -145,11 +144,14 @@ NSString *const OWSContactsManagerSignalAccountsDidChangeNotification
return nil;
}
CNContact *_Nullable cnContact = [self.cnContactCache objectForKey:contactId];
if (!cnContact) {
cnContact = [self.systemContactsFetcher fetchCNContactWithContactId:contactId];
if (cnContact) {
[self.cnContactCache setObject:cnContact forKey:contactId];
CNContact *_Nullable cnContact;
@synchronized(self.cnContactCache) {
cnContact = (CNContact * _Nullable)[self.cnContactCache getWithKey:contactId];
if (!cnContact) {
cnContact = [self.systemContactsFetcher fetchCNContactWithContactId:contactId];
if (cnContact) {
[self.cnContactCache setWithKey:contactId value:cnContact];
}
}
}

@ -24,26 +24,46 @@ public class AnyLRUCache: NSObject {
}
// A simple LRU cache bounded by the number of entries.
//
// TODO: We might want to observe memory pressure notifications.
public class LRUCache<KeyType: Hashable & Equatable, ValueType> {
private var cacheMap: [KeyType: ValueType] = [:]
private var cacheOrder: [KeyType] = []
private let maxSize: Int
@objc
public init(maxSize: Int) {
self.maxSize = maxSize
NotificationCenter.default.addObserver(self,
selector: #selector(didReceiveMemoryWarning),
name: NSNotification.Name.UIApplicationDidReceiveMemoryWarning,
object: nil)
}
deinit {
NotificationCenter.default.removeObserver(self)
}
@objc func didReceiveMemoryWarning() {
SwiftAssertIsOnMainThread(#function)
cacheMap.removeAll()
cacheOrder.removeAll()
}
private func updateCacheOrder(key: KeyType) {
cacheOrder = cacheOrder.filter { $0 != key }
cacheOrder.append(key)
}
public func get(key: KeyType) -> ValueType? {
guard let value = cacheMap[key] else {
// Miss
return nil
}
// Update cache order.
cacheOrder = cacheOrder.filter { $0 != key }
cacheOrder.append(key)
// Hit
updateCacheOrder(key: key)
return value
}
@ -51,9 +71,7 @@ public class LRUCache<KeyType: Hashable & Equatable, ValueType> {
public func set(key: KeyType, value: ValueType) {
cacheMap[key] = value
// Update cache order.
cacheOrder = cacheOrder.filter { $0 != key }
cacheOrder.append(key)
updateCacheOrder(key: key)
while cacheOrder.count > maxSize {
guard let staleKey = cacheOrder.first else {

Loading…
Cancel
Save