From fe4dc9a69a7731c63d82c87fa50c168ffaea1a45 Mon Sep 17 00:00:00 2001 From: Sami Samhuri Date: Thu, 11 Aug 2016 00:11:51 -0700 Subject: [PATCH] convert tabs to spaces --- CacheCreekTests/LRUCacheTests.swift | 312 ++++++++++++++-------------- Source/AnyKey.swift | 48 ++--- Source/LRUCache.swift | 234 ++++++++++----------- 3 files changed, 297 insertions(+), 297 deletions(-) diff --git a/CacheCreekTests/LRUCacheTests.swift b/CacheCreekTests/LRUCacheTests.swift index dab0c57..0c9dcaf 100644 --- a/CacheCreekTests/LRUCacheTests.swift +++ b/CacheCreekTests/LRUCacheTests.swift @@ -14,247 +14,247 @@ class CacheCreekTests: XCTestCase { typealias Node = DoublyLinkedListNode func testSettingAndGettingItems() { - let cache = LRUCache() + let cache = LRUCache() cache.set(item: 123, forKey: "123") - XCTAssert(cache.count == 1) + XCTAssert(cache.count == 1) XCTAssert(cache.item(forKey: "123") == 123) - XCTAssert(cache[123] == nil) + XCTAssert(cache[123] == nil) - cache[234] = "234" + cache[234] = "234" - XCTAssert(cache.count == 2) + XCTAssert(cache.count == 2) XCTAssert(cache.item(forKey: 234) == "234") - // Test setting/getting an array - let array = [1, 2, 3, 4, 5] - cache[5] = array + // Test setting/getting an array + let array = [1, 2, 3, 4, 5] + cache[5] = array - XCTAssert(cache.count == 3) + XCTAssert(cache.count == 3) if let fetchedArray: [Int] = cache.item(forKey: 5) { - XCTAssert(fetchedArray == array) - } - else { - XCTFail("Expected an int array") - } + XCTAssert(fetchedArray == array) + } + else { + XCTFail("Expected an int array") + } - let testStruct = TestStruct(name: "Testing", value: Int(arc4random_uniform(100000))) - cache["TestingStruct"] = testStruct + let testStruct = TestStruct(name: "Testing", value: Int(arc4random_uniform(100000))) + cache["TestingStruct"] = testStruct guard let fetchedStruct: TestStruct = cache.item(forKey: "TestingStruct") else { - XCTFail() - return - } - XCTAssert(testStruct.name == fetchedStruct.name) - XCTAssert(testStruct.value == fetchedStruct.value) - } + XCTFail() + return + } + XCTAssert(testStruct.name == fetchedStruct.name) + XCTAssert(testStruct.value == fetchedStruct.value) + } - func testDifferentKindsOfKeys() { - let cache = LRUCache() + func testDifferentKindsOfKeys() { + let cache = LRUCache() - let floatKey: Float = 123.456 + let floatKey: Float = 123.456 cache.set(item: 123.456, forKey: floatKey) XCTAssert(cache.item(forKey: floatKey) as Double? == .Some(123.456)) - cache[floatKey] = 456.789 - XCTAssert(cache.count == 1) - XCTAssert(cache[floatKey] as? Double == .Some(456.789)) + cache[floatKey] = 456.789 + XCTAssert(cache.count == 1) + XCTAssert(cache[floatKey] as? Double == .Some(456.789)) cache.set(item: "123.456", forKey: "123.456") - XCTAssert(cache.count == 2) + XCTAssert(cache.count == 2) XCTAssert(cache.item(forKey: "123.456") as String? == .Some("123.456")) - let boolKey = true + let boolKey = true cache.set(item: true, forKey: boolKey) - XCTAssert(cache.count == 3) + XCTAssert(cache.count == 3) XCTAssert(cache.item(forKey: boolKey) as Bool? == .Some(true)) cache.removeItem(forKey: boolKey) - XCTAssert(cache.count == 2) + XCTAssert(cache.count == 2) XCTAssert(cache.item(forKey: boolKey) as Bool? == .None) - } + } - func testSettingAndGettingEnum() { - let cache = LRUCache() - cache["ABC"] = TestEnum.ABC - cache["DEF"] = TestEnum.DEF("BlahBlahBlah") - cache["GHI"] = TestEnum.GHI(-500) + func testSettingAndGettingEnum() { + let cache = LRUCache() + cache["ABC"] = TestEnum.ABC + cache["DEF"] = TestEnum.DEF("BlahBlahBlah") + cache["GHI"] = TestEnum.GHI(-500) guard let abc: TestEnum = cache.item(forKey: "ABC"), def: TestEnum = cache.item(forKey: "DEF"), ghi: TestEnum = cache.item(forKey: "GHI") - else { - XCTFail() - return - } - switch (abc, def, ghi) { - case (.ABC, .DEF(let stringValue), .GHI(let intValue)): - XCTAssert(stringValue == "BlahBlahBlah") - XCTAssert(intValue == -500) - default: - XCTFail() - } - } + else { + XCTFail() + return + } + switch (abc, def, ghi) { + case (.ABC, .DEF(let stringValue), .GHI(let intValue)): + XCTAssert(stringValue == "BlahBlahBlah") + XCTAssert(intValue == -500) + default: + XCTFail() + } + } - func testSubscripts() { - let cache = LRUCache() + func testSubscripts() { + let cache = LRUCache() - // Int subscript - cache[123] = 123 - XCTAssert(cache[123] as? Int == .Some(123)) - XCTAssert(cache.count == 1) + // Int subscript + cache[123] = 123 + XCTAssert(cache[123] as? Int == .Some(123)) + XCTAssert(cache.count == 1) - cache[123] = nil - XCTAssert(cache[123] as? Int == .None) - XCTAssert(cache.count == 0) + cache[123] = nil + XCTAssert(cache[123] as? Int == .None) + XCTAssert(cache.count == 0) - // String subscript - cache["123"] = 123 - XCTAssert(cache["123"] as? Int == .Some(123)) - XCTAssert(cache.count == 1) + // String subscript + cache["123"] = 123 + XCTAssert(cache["123"] as? Int == .Some(123)) + XCTAssert(cache.count == 1) - cache["123"] = nil - XCTAssert(cache["123"] as? Int == .None) - XCTAssert(cache.count == 0) + cache["123"] = nil + XCTAssert(cache["123"] as? Int == .None) + XCTAssert(cache.count == 0) - // Float subscript - let floatKey: Float = 3.14 - cache[floatKey] = 123 - XCTAssert(cache[floatKey] as? Int == .Some(123)) - XCTAssert(cache.count == 1) - - cache[floatKey] = nil - XCTAssert(cache[floatKey] as? Int == .None) - XCTAssert(cache.count == 0) - } + // Float subscript + let floatKey: Float = 3.14 + cache[floatKey] = 123 + XCTAssert(cache[floatKey] as? Int == .Some(123)) + XCTAssert(cache.count == 1) + + cache[floatKey] = nil + XCTAssert(cache[floatKey] as? Int == .None) + XCTAssert(cache.count == 0) + } - func testRemovingItems() { - let cache = LRUCache() + func testRemovingItems() { + let cache = LRUCache() cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) cache.removeItem(forKey: 123) - XCTAssert(cache.count == 3) - XCTAssert(cache[123] == nil) + XCTAssert(cache.count == 3) + XCTAssert(cache[123] == nil) - cache[234] = nil + cache[234] = nil - XCTAssert(cache.count == 2) - XCTAssert(cache[234] == nil) + XCTAssert(cache.count == 2) + XCTAssert(cache[234] == nil) - cache.removeAllItems() + cache.removeAllItems() - XCTAssert(cache.count == 0) + XCTAssert(cache.count == 0) cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) - NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidReceiveMemoryWarningNotification, object: UIApplication.sharedApplication()) + NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidReceiveMemoryWarningNotification, object: UIApplication.sharedApplication()) - XCTAssert(cache.count == 0) + XCTAssert(cache.count == 0) - cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 123, forKey: 123) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) - NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidEnterBackgroundNotification, object: UIApplication.sharedApplication()) + NSNotificationCenter.defaultCenter().postNotificationName(UIApplicationDidEnterBackgroundNotification, object: UIApplication.sharedApplication()) - XCTAssert(cache.count == 0) + XCTAssert(cache.count == 0) - cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 123, forKey: 123) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) - // Make sure an unknown key doesn't have any weird side effects - cache[567] = nil + // Make sure an unknown key doesn't have any weird side effects + cache[567] = nil - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) cache.removeItem(forKey: 999) - XCTAssert(cache.count == 4) - } + XCTAssert(cache.count == 4) + } - func testCountLimit() { - let cache = LRUCache() - cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + func testCountLimit() { + let cache = LRUCache() + cache.set(item: 123, forKey: 123) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 4) + XCTAssert(cache.count == 4) - cache.countLimit = 3 + cache.countLimit = 3 - XCTAssert(cache.count == 3) + XCTAssert(cache.count == 3) - cache.removeAllItems() + cache.removeAllItems() - XCTAssert(cache.count == 0) + XCTAssert(cache.count == 0) - cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 123, forKey: 123) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - XCTAssert(cache.count == 3) + XCTAssert(cache.count == 3) - cache[567] = 567 - XCTAssert(cache.count == 3) + cache[567] = 567 + XCTAssert(cache.count == 3) - cache.removeAllItems() + cache.removeAllItems() - cache.set(item: 123, forKey: 123) - cache.set(item: 234, forKey: 234) - cache.set(item: 345, forKey: 345) - cache.set(item: 456, forKey: 456) + cache.set(item: 123, forKey: 123) + cache.set(item: 234, forKey: 234) + cache.set(item: 345, forKey: 345) + cache.set(item: 456, forKey: 456) - cache.countLimit = 2 + cache.countLimit = 2 - XCTAssert(cache.count == 2) - } + XCTAssert(cache.count == 2) + } - func testEmptyEviction() { - // Make sure that an eviction on an empty dictionary doesn't crash - let cache = LRUCache() - cache.evictItems() - } + func testEmptyEviction() { + // Make sure that an eviction on an empty dictionary doesn't crash + let cache = LRUCache() + cache.evictItems() + } - func testObjCObjects() { - let cache = LRUCache() + func testObjCObjects() { + let cache = LRUCache() - let oldCache = NSCache() - cache.set(item: oldCache, forKey: "InceptionCache") + let oldCache = NSCache() + cache.set(item: oldCache, forKey: "InceptionCache") guard let _: NSCache = cache.item(forKey: "InceptionCache") else { - XCTFail("Expected an NSCache object") - return - } - } + XCTFail("Expected an NSCache object") + return + } + } } private struct TestStruct { - let name: String - let value: Int + let name: String + let value: Int } private enum TestEnum { - case ABC - case DEF(String) - case GHI(Int) + case ABC + case DEF(String) + case GHI(Int) } diff --git a/Source/AnyKey.swift b/Source/AnyKey.swift index fd08004..f3201b2 100644 --- a/Source/AnyKey.swift +++ b/Source/AnyKey.swift @@ -13,33 +13,33 @@ import Foundation /// /// `AnyKey` is a simple struct that conforms to `Hashable` to allow any other `Hashable` key to be used in the cache dictionary struct AnyKey: Hashable { - /// The underlying value - private let underlying: Any - /// The hashing function - private let hashValueFunc: () -> Int - /// The equality function - private let equalityFunc: (Any) -> Bool + /// The underlying value + private let underlying: Any + /// The hashing function + private let hashValueFunc: () -> Int + /// The equality function + private let equalityFunc: (Any) -> Bool - init(_ key: T) { - underlying = key - // Capture the key's hashability and equatability using closures. - // The Key shares the hash of the underlying value. - hashValueFunc = { key.hashValue } - - // The Key is equal to a Key of the same underlying type, - // whose underlying value is "==" to ours. - equalityFunc = { - if let other = $0 as? T { - return key == other - } - return false - } - } + init(_ key: T) { + underlying = key + // Capture the key's hashability and equatability using closures. + // The Key shares the hash of the underlying value. + hashValueFunc = { key.hashValue } + + // The Key is equal to a Key of the same underlying type, + // whose underlying value is "==" to ours. + equalityFunc = { + if let other = $0 as? T { + return key == other + } + return false + } + } - /// `Hashable` protocol conformance - var hashValue: Int { return hashValueFunc() } + /// `Hashable` protocol conformance + var hashValue: Int { return hashValueFunc() } } func ==(x: AnyKey, y: AnyKey) -> Bool { - return x.equalityFunc(y.underlying) + return x.equalityFunc(y.underlying) } diff --git a/Source/LRUCache.swift b/Source/LRUCache.swift index e029313..a5c99d2 100644 --- a/Source/LRUCache.swift +++ b/Source/LRUCache.swift @@ -13,167 +13,167 @@ import Foundation /// It is designed to work similar to the `NSCache`, but with native Swift support. /// public class LRUCache { - // MARK: - Private variables - /// An array of `NSNotificationCenter` observers that need to be removed upon deinitialization - private var notificationObservers: [NSObjectProtocol] = [] + // MARK: - Private variables + /// An array of `NSNotificationCenter` observers that need to be removed upon deinitialization + private var notificationObservers: [NSObjectProtocol] = [] /// The list of cached items. Most recently used item at head, least recently used item at tail. private var items: DoublyLinkedList = DoublyLinkedList() - /// Maps keys of cached items to nodes in the linked list. - private var keyToNodeMap: [AnyKey:DoublyLinkedListNode] = [:] + /// Maps keys of cached items to nodes in the linked list. + private var keyToNodeMap: [AnyKey:DoublyLinkedListNode] = [:] - // MARK: - Public variables - /// The number of items in the cache. - public var count: Int { - return items.count - } + // MARK: - Public variables + /// The number of items in the cache. + public var count: Int { + return items.count + } - /// The limit of the amount of items that can be held in the cache. This defaults to 0, which means there is no limit. - public var countLimit: Int = 0 { - didSet { + /// The limit of the amount of items that can be held in the cache. This defaults to 0, which means there is no limit. + public var countLimit: Int = 0 { + didSet { assert(countLimit >= 0) - evictItems() - } - } + evictItems() + } + } - // MARK: - Initialization methods - public init() { - let removalBlock = { [unowned self] (_: NSNotification) in - self.removeAllItems() - } + // MARK: - Initialization methods + public init() { + let removalBlock = { [unowned self] (_: NSNotification) in + self.removeAllItems() + } - var notificationObserver = NSNotificationCenter.defaultCenter() - .addObserverForName(UIApplicationDidReceiveMemoryWarningNotification, - object: UIApplication.sharedApplication(), - queue: nil, - usingBlock: removalBlock) - notificationObservers.append(notificationObserver) - notificationObserver = NSNotificationCenter.defaultCenter() - .addObserverForName(UIApplicationDidEnterBackgroundNotification, - object: UIApplication.sharedApplication(), - queue: nil, - usingBlock: removalBlock) - notificationObservers.append(notificationObserver) - } + var notificationObserver = NSNotificationCenter.defaultCenter() + .addObserverForName(UIApplicationDidReceiveMemoryWarningNotification, + object: UIApplication.sharedApplication(), + queue: nil, + usingBlock: removalBlock) + notificationObservers.append(notificationObserver) + notificationObserver = NSNotificationCenter.defaultCenter() + .addObserverForName(UIApplicationDidEnterBackgroundNotification, + object: UIApplication.sharedApplication(), + queue: nil, + usingBlock: removalBlock) + notificationObservers.append(notificationObserver) + } - deinit { - notificationObservers.forEach { - NSNotificationCenter.defaultCenter().removeObserver($0) - } - } + deinit { + notificationObservers.forEach { + NSNotificationCenter.defaultCenter().removeObserver($0) + } + } - // MARK: - Internal methods - /// Evicts items if the `countLimit` has been reached. - /// - func evictItems() { + // MARK: - Internal methods + /// Evicts items if the `countLimit` has been reached. + /// + func evictItems() { guard countLimit > 0 else { return } while items.count > countLimit { if let node = items.removeLast() { keyToNodeMap[node.key] = nil } - } - } + } + } - // MARK: - Public methods - /// Adds an item to the cache for any given `Hashable` key. - /// - /// - parameter item: The item to be cached - /// - parameter key: The key with which to cache the item - /// - public func set(item item: Any, forKey key: K) { + // MARK: - Public methods + /// Adds an item to the cache for any given `Hashable` key. + /// + /// - parameter item: The item to be cached + /// - parameter key: The key with which to cache the item + /// + public func set(item item: Any, forKey key: K) { let key = AnyKey(key) if let existingNode = keyToNodeMap[key] { items.remove(node: existingNode) } let node = items.prepend(key: key, value: item) keyToNodeMap[key] = node - evictItems() - } + evictItems() + } - /// Gets an item from the cache if it exists for a given `Hashable` key. - /// This method uses generics to infer the type that should be returned. - /// - /// Note: Even if an item exists for the key, but does not match the given type, it will return `nil`. - /// - /// - parameter key: The key whose item should be fetched - /// - returns: The item from the cache if it exists, or `nil` if an item could not be found - /// - public func item(forKey key: K) -> T? { + /// Gets an item from the cache if it exists for a given `Hashable` key. + /// This method uses generics to infer the type that should be returned. + /// + /// Note: Even if an item exists for the key, but does not match the given type, it will return `nil`. + /// + /// - parameter key: The key whose item should be fetched + /// - returns: The item from the cache if it exists, or `nil` if an item could not be found + /// + public func item(forKey key: K) -> T? { let key = AnyKey(key) - if let node = keyToNodeMap[key], let item = node.value as? T { + if let node = keyToNodeMap[key], let item = node.value as? T { items.moveToHead(node: node) - return item - } - return nil - } + return item + } + return nil + } - /// Discards an item for a given `Hashable` key. - /// - /// - parameter key: The key whose item should be removed - /// - public func removeItem(forKey key: K) { + /// Discards an item for a given `Hashable` key. + /// + /// - parameter key: The key whose item should be removed + /// + public func removeItem(forKey key: K) { let key = AnyKey(key) if let node = keyToNodeMap[key] { items.remove(node: node) keyToNodeMap[key] = nil } - } + } - /// Clears the entire cache. - /// - public func removeAllItems() { + /// Clears the entire cache. + /// + public func removeAllItems() { items.removeAll() - keyToNodeMap.removeAll() - } + keyToNodeMap.removeAll() + } - // MARK: - Subscript methods - // TODO: Consolidate these subscript methods once subscript generics with constraints are supported - /// A subscript method that allows `Int` key subscripts. - /// - public subscript(key: Int) -> Any? { - get { + // MARK: - Subscript methods + // TODO: Consolidate these subscript methods once subscript generics with constraints are supported + /// A subscript method that allows `Int` key subscripts. + /// + public subscript(key: Int) -> Any? { + get { return item(forKey: key) - } - set { - if let newValue = newValue { + } + set { + if let newValue = newValue { set(item: newValue, forKey: key) - } - else { + } + else { removeItem(forKey: key) - } - } - } + } + } + } - /// A subscript method that allows `Float` key subscripts. - /// - public subscript(key: Float) -> Any? { - get { + /// A subscript method that allows `Float` key subscripts. + /// + public subscript(key: Float) -> Any? { + get { return item(forKey: key) - } - set { - if let newValue = newValue { + } + set { + if let newValue = newValue { set(item: newValue, forKey: key) - } - else { + } + else { removeItem(forKey: key) - } - } - } + } + } + } - /// A subscript method that allows `String` key subscripts. - /// - public subscript(key: String) -> Any? { - get { + /// A subscript method that allows `String` key subscripts. + /// + public subscript(key: String) -> Any? { + get { return item(forKey: key) - } - set { - if let newValue = newValue { + } + set { + if let newValue = newValue { set(item: newValue, forKey: key) - } - else { + } + else { removeItem(forKey: key) - } - } - } + } + } + } }