Skip to content

Instantly share code, notes, and snippets.

@naithar
Created February 10, 2017 07:37
Show Gist options
  • Save naithar/74444bf1b448843d3ae402c3ef9fb859 to your computer and use it in GitHub Desktop.
Save naithar/74444bf1b448843d3ae402c3ef9fb859 to your computer and use it in GitHub Desktop.
Foundation Test NSCache
Darwin implementation
=======
I. Default keys for NSCache (current NSCache behavior. If not Darwin -> should match Darwin's)
=======
using NSCache with SwiftNoHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <swift.noHash.10> (0)
set value 'b' for key <swift.noHash.10> (1)
Stored value for key (0): <swift.noHash.10> = a
Stored value for key (1): <swift.noHash.10> = b
Stored value for dynamic key: <swift.noHash.10> = none
using NSCache with SwiftHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <swift.hash.10> (0)
set value 'b' for key <swift.hash.10> (1)
Stored value for key (0): <swift.hash.10> = a
Stored value for key (1): <swift.hash.10> = b
Stored value for dynamic key: <swift.hash.10> = none
using NSCache with NSKeyNoHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = a
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = none
using NSCache with NSKeyHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = b
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = b
using NSCache with NSString
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key 10 (0)
set value 'b' for key 10 (1)
Stored value for key (0): 10 = b
Stored value for key (1): 10 = b
Stored value for dynamic key: 10 = b
=======
II. Container keys for NSCache (should match 'I' on Darwin)
=======
using NSCache with SwiftNoHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<swift.noHash.10>> (0)
set value 'b' for key <container.<swift.noHash.10>> (1)
Stored value for key (0): <container.<swift.noHash.10>> = a
Stored value for key (1): <container.<swift.noHash.10>> = b
Stored value for dynamic key: <container.<swift.noHash.10>> = none
using NSCache with SwiftHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<swift.hash.10>> (0)
set value 'b' for key <container.<swift.hash.10>> (1)
Stored value for key (0): <container.<swift.hash.10>> = a
Stored value for key (1): <container.<swift.hash.10>> = b
Stored value for dynamic key: <container.<swift.hash.10>> = none
using NSCache with NSKeyNoHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = a
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = none
using NSCache with NSKeyHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = b
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = b
using NSCache with NSString in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.10> (0)
set value 'b' for key <container.10> (1)
Stored value for key (0): <container.10> = b
Stored value for key (1): <container.10> = b
Stored value for dynamic key: <container.10> = b
====
III. Dictionary with default keys
====
Note: 'SwiftNoHash' key is unavailable as it does not conform to hashable
using Dictionary<> with SwiftHash
set value 'a' for key <swift.hash.10> (0)
set value 'b' for key <swift.hash.10> (1)
Stored value for key (0): <swift.hash.10> = b
Stored value for key (1): <swift.hash.10> = b
Stored value for dynamic key: <swift.hash.10> = b
using Dictionary<> with NSKeyNoHash
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = a
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = none
using Dictionary<> with NSKeyHash
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = b
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = b
using Dictionary<> with NSString
set value 'a' for key 10 (0)
set value 'b' for key 10 (1)
Stored value for key (0): 10 = b
Stored value for key (1): 10 = b
Stored value for dynamic key: 10 = b
====
IV. Dictionary with container keys (should match 'I' on Darwin)
====
Note: 'SwiftNoHash' key is used
using Dictionary<> with SwiftNoHash in Container
set value 'a' for key <container.<swift.noHash.10>> (0)
set value 'b' for key <container.<swift.noHash.10>> (1)
Stored value for key (0): <container.<swift.noHash.10>> = a
Stored value for key (1): <container.<swift.noHash.10>> = b
Stored value for dynamic key: <container.<swift.noHash.10>> = none
using Dictionary<> with SwiftHash in Container
set value 'a' for key <container.<swift.hash.10>> (0)
set value 'b' for key <container.<swift.hash.10>> (1)
Stored value for key (0): <container.<swift.hash.10>> = a
Stored value for key (1): <container.<swift.hash.10>> = b
Stored value for dynamic key: <container.<swift.hash.10>> = none
using Dictionary<> with NSKeyNoHash in Container
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = a
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = none
using Dictionary<> with NSKeyHash in Container
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = b
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = b
using Dictionary<> with NSString in Container
set value 'a' for key <container.10> (0)
set value 'b' for key <container.10> (1)
Stored value for key (0): <container.10> = b
Stored value for key (1): <container.10> = b
Stored value for dynamic key: <container.10> = b
OSS Foundation Implementation
=======
I. Default keys for NSCache (current NSCache behavior. If not Darwin -> should match Darwin's)
=======
using NSCache with SwiftNoHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <swift.noHash.10> (0)
set value 'b' for key <swift.noHash.10> (1)
Stored value for key (0): <swift.noHash.10> = a
Stored value for key (1): <swift.noHash.10> = b
Stored value for dynamic key: <swift.noHash.10> = none
using NSCache with SwiftHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <swift.hash.10> (0)
set value 'b' for key <swift.hash.10> (1)
Stored value for key (0): <swift.hash.10> = a
Stored value for key (1): <swift.hash.10> = b
Stored value for dynamic key: <swift.hash.10> = none
using NSCache with NSKeyNoHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = a
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = none
using NSCache with NSKeyHash
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = b
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = b
using NSCache with NSString
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key 10 (0)
set value 'b' for key 10 (1)
Stored value for key (0): 10 = b
Stored value for key (1): 10 = b
Stored value for dynamic key: 10 = b
=======
II. Container keys for NSCache (should match 'I' on Darwin)
=======
using NSCache with SwiftNoHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<swift.noHash.10>> (0)
set value 'b' for key <container.<swift.noHash.10>> (1)
Stored value for key (0): <container.<swift.noHash.10>> = a
Stored value for key (1): <container.<swift.noHash.10>> = b
Stored value for dynamic key: <container.<swift.noHash.10>> = none
using NSCache with SwiftHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<swift.hash.10>> (0)
set value 'b' for key <container.<swift.hash.10>> (1)
Stored value for key (0): <container.<swift.hash.10>> = a
Stored value for key (1): <container.<swift.hash.10>> = b
Stored value for dynamic key: <container.<swift.hash.10>> = none
using NSCache with NSKeyNoHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = a
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = none
using NSCache with NSKeyHash in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = b
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = b
using NSCache with NSString in Container
default NSCache values: '.totalCostLimit' = 0, '.countLimit' = 0
set value 'a' for key <container.10> (0)
set value 'b' for key <container.10> (1)
Stored value for key (0): <container.10> = b
Stored value for key (1): <container.10> = b
Stored value for dynamic key: <container.10> = b
====
III. Dictionary with default keys
====
Note: 'SwiftNoHash' key is unavailable as it does not conform to hashable
using Dictionary<> with SwiftHash
set value 'a' for key <swift.hash.10> (0)
set value 'b' for key <swift.hash.10> (1)
Stored value for key (0): <swift.hash.10> = b
Stored value for key (1): <swift.hash.10> = b
Stored value for dynamic key: <swift.hash.10> = b
using Dictionary<> with NSKeyNoHash
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = a
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = none
using Dictionary<> with NSKeyHash
set value 'a' for key <ns.noHash.10> (0)
set value 'b' for key <ns.noHash.10> (1)
Stored value for key (0): <ns.noHash.10> = b
Stored value for key (1): <ns.noHash.10> = b
Stored value for dynamic key: <ns.noHash.10> = b
using Dictionary<> with NSString
set value 'a' for key 10 (0)
set value 'b' for key 10 (1)
Stored value for key (0): 10 = b
Stored value for key (1): 10 = b
Stored value for dynamic key: 10 = b
====
IV. Dictionary with container keys (should match 'I' on Darwin)
====
Note: 'SwiftNoHash' key is used
using Dictionary<> with SwiftNoHash in Container
set value 'a' for key <container.<swift.noHash.10>> (0)
set value 'b' for key <container.<swift.noHash.10>> (1)
Stored value for key (0): <container.<swift.noHash.10>> = a
Stored value for key (1): <container.<swift.noHash.10>> = b
Stored value for dynamic key: <container.<swift.noHash.10>> = none
using Dictionary<> with SwiftHash in Container
set value 'a' for key <container.<swift.hash.10>> (0)
set value 'b' for key <container.<swift.hash.10>> (1)
Stored value for key (0): <container.<swift.hash.10>> = a
Stored value for key (1): <container.<swift.hash.10>> = b
Stored value for dynamic key: <container.<swift.hash.10>> = none
using Dictionary<> with NSKeyNoHash in Container
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = a
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = none
using Dictionary<> with NSKeyHash in Container
set value 'a' for key <container.<ns.noHash.10>> (0)
set value 'b' for key <container.<ns.noHash.10>> (1)
Stored value for key (0): <container.<ns.noHash.10>> = b
Stored value for key (1): <container.<ns.noHash.10>> = b
Stored value for dynamic key: <container.<ns.noHash.10>> = b
using Dictionary<> with NSString in Container
set value 'a' for key <container.10> (0)
set value 'b' for key <container.10> (1)
Stored value for key (0): <container.10> = b
Stored value for key (1): <container.10> = b
Stored value for dynamic key: <container.10> = b
class SwiftKeyNoHash: CustomStringConvertible {
var value: Int
init(_ value: Int) {
self.value = value
}
var description: String {
return "<swift.noHash.\(self.value)>"
}
}
class SwiftKeyHash: Hashable, CustomStringConvertible {
var hashValue: Int {
return self.value.hashValue
}
var value: Int
init(_ value: Int) {
self.value = value
}
public static func ==(lhs: SwiftKeyHash, rhs: SwiftKeyHash) -> Bool {
return lhs.value == rhs.value
}
var description: String {
return "<swift.hash.\(self.value)>"
}
}
class NSKeyNoHash: NSObject {
var value: Int
init(_ value: Int) {
self.value = value
super.init()
}
override var description: String {
return "<ns.noHash.\(self.value)>"
}
}
class NSKeyHash: NSObject {
override var hashValue: Int {
return self.value.hashValue
}
var value: Int
init(_ value: Int) {
self.value = value
super.init()
}
override func isEqual(_ object: Any?) -> Bool {
guard let other = object as? NSKeyHash else { return false }
return self.value == other.value
}
override var description: String {
return "<ns.noHash.\(self.value)>"
}
}
class NSCacheKey: NSObject {
override var hashValue: Int {
switch self.value {
case let value as NSObject:
return value.hashValue
case let value as Hashable:
return value.hashValue
default:
return 0
}
}
var value: AnyObject
init(_ value: AnyObject) {
self.value = value
super.init()
}
override func isEqual(_ object: Any?) -> Bool {
guard let other = object as? NSCacheKey else { return false }
if self.value === other.value {
return true
} else {
guard let left = self.value as? NSObject,
let right = other.value as? NSObject else { return false }
return left.isEqual(right)
}
}
override var description: String {
return "<container.\(self.value)>"
}
}
protocol Testable {
func run()
}
func foo() {
class CacheTestValues<KeyType: AnyObject>: Testable {
var description: String
var cache = NSCache<KeyType, NSString>()
var keys: (KeyType, KeyType)
var generator: () -> KeyType
init(_ description: String, keys: (KeyType, KeyType), generator: @autoclosure @escaping () -> KeyType) {
self.description = description
self.keys = keys
self.generator = generator
}
func run() {
print("using NSCache with \(self.description)")
print("default NSCache values: '.totalCostLimit' = \(self.cache.totalCostLimit), '.countLimit' = \(self.cache.countLimit)")
self.cache.setObject("a", forKey: self.keys.0)
print("set value 'a' for key \(self.keys.0) (0)")
self.cache.setObject("b", forKey: self.keys.1)
print("set value 'b' for key \(self.keys.1) (1)")
print("Stored value for key (0): \(self.keys.0) = \(self.cache.object(forKey: self.keys.0) ?? "none")")
print("Stored value for key (1): \(self.keys.1) = \(self.cache.object(forKey: self.keys.1) ?? "none")")
let key = self.generator()
print("Stored value for dynamic key: \(key) = \(self.cache.object(forKey: key) ?? "none")")
}
}
class DictionaryTestValues<KeyType: Hashable>: Testable {
var description: String
var dictionary = [KeyType : String]()
var keys: (KeyType, KeyType)
var generator: () -> KeyType
init(_ description: String, keys: (KeyType, KeyType), generator: @autoclosure @escaping () -> KeyType) {
self.description = description
self.keys = keys
self.generator = generator
}
func run() {
print("using Dictionary<> with \(self.description)")
self.dictionary[self.keys.0] = "a"
print("set value 'a' for key \(self.keys.0) (0)")
self.dictionary[self.keys.1] = "b"
print("set value 'b' for key \(self.keys.1) (1)")
print("Stored value for key (0): \(self.keys.0) = \(self.dictionary[self.keys.0] ?? "none")")
print("Stored value for key (1): \(self.keys.1) = \(self.dictionary[self.keys.1] ?? "none")")
let key = self.generator()
print("Stored value for dynamic key: \(key) = \(self.dictionary[key] ?? "none")")
}
}
print("=======")
print("I. Default keys for NSCache (current NSCache behavior. If not Darwin -> should match Darwin's)")
print("=======")
var container: [Testable] = [
CacheTestValues("SwiftNoHash", keys: (SwiftKeyNoHash(10), SwiftKeyNoHash(10)), generator: SwiftKeyNoHash(10)),
CacheTestValues("SwiftHash", keys: (SwiftKeyHash(10), SwiftKeyHash(10)), generator: SwiftKeyHash(10)),
CacheTestValues("NSKeyNoHash", keys: (NSKeyNoHash(10), NSKeyNoHash(10)), generator: NSKeyNoHash(10)),
CacheTestValues("NSKeyHash", keys: (NSKeyHash(10), NSKeyHash(10)), generator: NSKeyHash(10)),
CacheTestValues("NSString", keys: (NSString(string: "10"), NSString(string: "10")), generator: NSString(string: "10")),
]
for item in container {
item.run()
}
print("=======")
print("II. Container keys for NSCache (should match 'I' on Darwin)")
print("=======")
container = [
CacheTestValues("SwiftNoHash in Container", keys: (NSCacheKey(SwiftKeyNoHash(10)), NSCacheKey(SwiftKeyNoHash(10))), generator: NSCacheKey(SwiftKeyNoHash(10))),
CacheTestValues("SwiftHash in Container", keys: (NSCacheKey(SwiftKeyHash(10)), NSCacheKey(SwiftKeyHash(10))), generator: NSCacheKey(SwiftKeyHash(10))),
CacheTestValues("NSKeyNoHash in Container", keys: (NSCacheKey(NSKeyNoHash(10)), NSCacheKey(NSKeyNoHash(10))), generator: NSCacheKey(NSKeyNoHash(10))),
CacheTestValues("NSKeyHash in Container", keys: (NSCacheKey(NSKeyHash(10)), NSCacheKey(NSKeyHash(10))), generator: NSCacheKey(NSKeyHash(10))),
CacheTestValues("NSString in Container", keys: (NSCacheKey(NSString(string: "10")), NSCacheKey(NSString(string: "10"))), generator: NSCacheKey(NSString(string: "10"))),
]
for item in container {
item.run()
}
print("====")
print("III. Dictionary with default keys")
print("====")
print("Note: 'SwiftNoHash' key is unavailable as it does not conform to hashable")
container = [
DictionaryTestValues("SwiftHash", keys: (SwiftKeyHash(10), SwiftKeyHash(10)), generator: SwiftKeyHash(10)),
DictionaryTestValues("NSKeyNoHash", keys: (NSKeyNoHash(10), NSKeyNoHash(10)), generator: NSKeyNoHash(10)),
DictionaryTestValues("NSKeyHash", keys: (NSKeyHash(10), NSKeyHash(10)), generator: NSKeyHash(10)),
DictionaryTestValues("NSString", keys: (NSString(string: "10"), NSString(string: "10")), generator: NSString(string: "10")),
]
for item in container {
item.run()
}
print("====")
print("IV. Dictionary with container keys (should match 'I' on Darwin)")
print("====")
print("Note: 'SwiftNoHash' key is used")
container = [
DictionaryTestValues("SwiftNoHash in Container", keys: (NSCacheKey(SwiftKeyNoHash(10)), NSCacheKey(SwiftKeyNoHash(10))), generator: NSCacheKey(SwiftKeyNoHash(10))),
DictionaryTestValues("SwiftHash in Container", keys: (NSCacheKey(SwiftKeyHash(10)), NSCacheKey(SwiftKeyHash(10))), generator: NSCacheKey(SwiftKeyHash(10))),
DictionaryTestValues("NSKeyNoHash in Container", keys: (NSCacheKey(NSKeyNoHash(10)), NSCacheKey(NSKeyNoHash(10))), generator: NSCacheKey(NSKeyNoHash(10))),
DictionaryTestValues("NSKeyHash in Container", keys: (NSCacheKey(NSKeyHash(10)), NSCacheKey(NSKeyHash(10))), generator: NSCacheKey(NSKeyHash(10))),
DictionaryTestValues("NSString in Container", keys: (NSCacheKey(NSString(string: "10")), NSCacheKey(NSString(string: "10"))), generator: NSCacheKey(NSString(string: "10"))),
]
for item in container {
item.run()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment