Source/TNLLRUCache.h (35 lines of code) (raw):

// // TNLLRUCache.h // TwitterNetworkLayer // // Created on 10/27/15. // Copyright © 2020 Twitter. All rights reserved. // #import <Foundation/Foundation.h> @protocol TNLLRUCacheDelegate; @protocol TNLLRUEntry; NS_ASSUME_NONNULL_BEGIN /** `TNLLRUCache` is a collection object that maintains a set of `TNLLRUEntry` objects. You can look up an entry by identifier in constant time and it maintains the entries so that you can remove the least-recently-used (LRU) entry. @warning This class is exposed as a convenience to consumers that might be able to take advantage of an LRU collection. It is not permanent though and may eventually move to a shared core utilities library that TNL will depend on. It is recommended to NOT use this class unless you are prepared to migrate to a shared core utilities library if one is created. */ @interface TNLLRUCache : NSObject <NSFastEnumeration> /** Optional delegate */ @property (nonatomic, weak, nullable) id<TNLLRUCacheDelegate> delegate; /** The head entry of the cache, most recently used entry. `nil` if the cache is empty. Accessing does not mutate this LRU cache. */ @property (nonatomic, readonly, nullable) id<TNLLRUEntry> headEntry; /** The tail entry of the cache, least recently used entry. `nil` if the cache is empty. Accessing does not mutate this LRU cache. */ @property (nonatomic, readonly, nullable) id<TNLLRUEntry> tailEntry; /** the number of entries in the manfiest. Execution time is constant, O(1) */ - (NSUInteger)numberOfEntries; /** designted initializer */ - (instancetype)initWithEntries:(nullable NSArray<id<TNLLRUEntry>> *)arrayOfLRUEntries delegate:(nullable id<TNLLRUCacheDelegate>)delegate NS_DESIGNATED_INITIALIZER; /** Access an entry by identifier. If entry is found, it is moved to head if _canMutate_ is `YES` and the entry's `shouldAccessMoveLRUEntryToHead` value is `YES`. Returns `nil` if no entry was found. Execution time is constant, O(1) */ - (nullable id<TNLLRUEntry>)entryWithIdentifier:(NSString *)identifier canMutate:(BOOL)moveToHead; /** Same as `entryWithIdentifier:canMutate:` with _canMutate being `YES` */ - (nullable id<TNLLRUEntry>)entryWithIdentifier:(NSString *)identifier; /** Copy all entries as an `NSArray` (does not count as an access that would affect order in LRU cache). Execution time is linear, O(n) */ - (NSArray<id<TNLLRUEntry>> *)allEntries; /** Sets the given _entry_ as the head entry. If _entry_ was not in the cache, it is added to the cache. If _entry_ was in the cache, it is just moved to the head if `[TNLLRUEntry shouldAccessMoveLRUEntryToHead]` returns `YES`. Execution time is constant, O(1) */ - (void)addEntry:(id<TNLLRUEntry>)entry; /** Adds the given _entry_ as the tail entry. Execution time is constant, O(1) @note this circumvents the value of the LRU cache, so it is recommended that only `addEntry:` is used. Using this method only really makes sense during `TNLLRUCache` set up time and not beyond that. */ - (void)appendEntry:(id<TNLLRUEntry>)entry; /** Removes the specified _entry_. Execution time is constant, O(1) @note This does will trigger the `[TNLLRUCacheDelegate tnl_cache:didEvictEntry:]` callback if then entry was in the cache */ - (void)removeEntry:(nullable id<TNLLRUEntry>)entry; /** Remove the tail entry (least-recently-used) if the cache is not empty. Execution time is constant, O(1) @return the entry removed or `nil` if no entry was removed. @note This does will trigger the `[TNLLRUCacheDelegate tnl_cache:didEvictEntry:]` callback if an entry was removed */ - (nullable id<TNLLRUEntry>)removeTailEntry; /** Clear all entries in the cache. Execution time is linear, O(n). This is because each value has to dealloc. @note This does NOT trigger the `[TNLLRUCacheDelegate tnl_cache:didEvictEntry:]` callback */ - (void)clearAllEntries; @end /** Delegate protocol for `TNLLRUCache` */ @protocol TNLLRUCacheDelegate <NSObject> @optional /** Optional callback for when a specific _entry_ is evicted from the _cache_. @note This method is NOT called on cache `dealloc` nor when `[TNLLRUCache clearAllEntries]` is called. */ - (void)tnl_cache:(TNLLRUCache *)cache didEvictEntry:(id<TNLLRUEntry>)entry; /** Optional callback to check if a specific _entry_ can be evicted from the _cache_. Return `NO` to prevent eviction. Default when unimplemented is `YES`. Only used in conjuction with `removeTailEntry`. */ - (BOOL)tnl_cache:(TNLLRUCache *)cache canEvictEntry:(id<TNLLRUEntry>)entry; @end /** Protocol for `TNLLRUCache` support. */ @protocol TNLLRUEntry <NSObject> @required /** The unique identifier for the entry */ - (NSString *)LRUEntryIdentifier; /** Return `YES` to update the entry as most-recently-used when it is accessed. Otherwise, return `NO`. */ - (BOOL)shouldAccessMoveLRUEntryToHead; /** A property to store the strong reference to the next entry. This property will be managed by the `TNLLRUManfiest` and should not be manipulated. */ @property (nonatomic, nullable) id<TNLLRUEntry> nextLRUEntry; /** A property to store the weak reference to the previous entry. This property will be managed by the `TNLLRUManfiest` and should not be manipulated. */ @property (nonatomic, nullable, weak) id<TNLLRUEntry> previousLRUEntry; @end NS_ASSUME_NONNULL_END