Thread safe general IOS cache swiftlycache

Time:2020-12-14

In IOS development, cache is more or less used to reduce network requests. There are many cache frameworks developed by Objective-C on the network, while the cache framework developed by swift is relatively less. Swiftlycache is a cache framework developed by me( github.com/hlc0000/Swi … )

characteristic

  • Support all complianceCodableThe data type of the protocol
  • supportLRUElimination algorithm
  • When a memory warning is received or the app enters the background, the memory cache can be configured to empty automatically or manually
  • Support the use ofSubscriptTo make reading and writing data more convenient
  • ProvidedMultiCacheGenneratorMemoryCacheGeneratorDiskCacheGeneratorFor supportfor..incompactMapmapfilterAnd so on

Architecture diagram:

Thread safe general IOS cache swiftlycache

Division of responsibilities of members:

Cacheware: provides some basic interface protocol, multicache, memorycache, diskcache and so on 
Multicache: multiple cache, calling memorycache and diskcache related methods 
Memory cache: responsible for processing small capacity, relatively high speed memory cache, thread safe, support asynchronous operation, support automatic and manual cache cleaning function 
Memo ryStorage:MemoryCache Double linked list class used 
Linked node class 
Diskcache: responsible for processing large capacity, relatively low speed disk cache, thread safe, support asynchronous operation, automatic and manual cache cleaning function 
Di skStorage:DiskCache Internal implementation class 
Diskstorageitem: used to load disk cache data 
Swiftlycache supports the use of subscript, which makes reading and writing more convenient 
Swiftlycache provides multicache generator, memorycachegenerator and diskcachegenerator to support a series of methods such as for... In, compactmap, map and filter

usage method:

CocoaPods:

1. Add pod in podfileSwiftlyCache
2. Executionpod installperhapspod update
3. ImportSwiftlyCache

Manual import:

1. DownloadSwiftlyCacheAll contents in folder
2SwiftlyCacheAdd source files within to your project

Use of attributes:

MemoryCacheAvailable properties:

Set the maximum memory cache size (0 is unlimited)

public var totalCostLimit:vm_size_t = 0

Set the maximum number of memory caches

public var totalCountLimit:vm_size_t = 0

System memory warning whether to delete all memory data, the default is true

public var autoRemoveAllObjectWhenMemoryWarning =true

Whether to delete all memory data in the background. The default value is true

public var autoRemoveAllObjectWhenEnterBackground =true

Properties available for diskcache:

Set maximum disk cache size (0 is unlimited)

public var maxSize:vm_size_t = 0

Set the maximum number of disk caches

public var maxCountLimit:vm_size_t = 0

The expiration time of the cache (default is one week)

public var maxCachePeriodInSecond:TimeInterval = 60 * 60 * 24 * 7

Automatic check time setting (default is 120 seconds)

Automatically check whether the disk cache reaches the limit. If the limit is reached, some data will be discarded automatically (maximum cache capacity limit, maximum cache number limit, and whether the data is expired)

public var autoInterval:TimeInterval = 120

Interface usage:

MultiCacheandMemoryCache,DiskCacheSet cache, get cache, according tokeyQuery whether there is corresponding cache data, remove all cache data, and according tokeyRemoving the corresponding cache data is subject toCacheAwareAgreed

Set cache object:(ValueFor all complianceCodableData type of protocol)

public funcset(forKey key: String, value: Value?, cost: vm_size_t = 0)->Bool
public funcset(forKey key:String,value:Value?,cost:vm_size_t = 0,completionHandler:@escaping((_ key:String,_ finished:Bool) -> Void))

It can be done throughSubscriptSituation setting cachekeyValue

cache["key"] = Value

Get cache object

public func object(forKey key: String) -> Value?public func object(forKey key:String,completionHandler:@escaping((_ key:String,_ value:Value?) -> Void))

It can also be done throughSubscriptTo get the corresponding cache object

let object = cache["key"]

According to the givenkeyFind if there is a correspondingValue

public func isExistsObjectForKey(forKey key: String) -> Bool
public func isExistsObjectForKey(forKey key:String,completionHandler:@escaping((_ key:String,_ contain:Bool) -> Void))

according tokeyRemove the correspondingvalue

public func removeObject(forKey key: String)
public func removeObject(forKey key: String, completionHandler: @escaping (() -> Void))

Remove all caches

public func removeAll()public func removeAll(completionHandler:@escaping(() -> Void)

It can also be done throughfor ... incompactMapmapfilterTo obtain the corresponding cache data

public func makeIterator() -> MultiCacheGenerator
let iterator = cache.makeIterator()
while let result = iterator.next(){}
let flatMapResult = cache.compactMap{$0}
print("flatMapResult:\(flatMapResult)")
let filterResult = cache.filter{(key,object) -> Bool in return key =="shirley2"}
print("filterResult:\(filterResult)")
cache.forEach(print($0) )
let values = cache.map{return$0}
print("value:\(value)")
for(key,object) in cache{
  print("key:\(key),object:\(object)")
}

MultiCacheAndMemoryCacheAll the available interfaces are introduced,DiskCacheIn addition to all the above interfaces, there are the following:

Remove all expired data

public func removeAllExpired()->Bool{}

Get the total number of disk caches

public func getTotalItemCount()->Int}
public func getTotalItemCount(completionHandler:@escaping((_ count:Int)->Void)){}

Get the total disk cache capacity

public func getTotalItemSize()->Int32{}
public func getTotalItemSize(completionHandler:@escaping((_ size:Int32)->Void)){}

Performance comparison:

I’ve seen some cache frameworks developed with Objective-C, such asPINCache,YYCacheAnd so on, they also basically understand some of their advantages and disadvantagesSwiftlyCacheThey also try to integrate some of their advantages

Single threadMemoryCachePerformance test (150000 times)
Thread safe general IOS cache swiftlycache
PINMemoryCacheWhen writing data, three dictionaries are used to record the cache object, cache time and cache capacity respectively. Each time the data is written, the three dictionaries need to be written in turn

YYMemoryCacheandSwiftlyCacheAt most one write operation is needed to the dictionary every time the data is written

After each completion of the cache data, it is necessary to discard the excessTotalCountandTotalCostData of,PINMemoryCacheYou need to be right at the time of eliminationDateThe dictionary reorders and discards the oldest data

andYYCacheandSwiftlyCacheYou need to remove it from the end of the linked list each time,YYCacheOfcostElimination occurs in asynchronous threads, andSwiftlyCacheThis is done in the current threadTotalCostIf the asynchronous thread is used, the overhead is very large

Single threadDiskCachePerformance test (1000 times, 10K on the left and 100k on the right)
Thread safe general IOS cache swiftlycache

PINDiskCacheUsing file cache data, setting file parameters, file size to manage cache data, adding, deleting, modifying and checking cache data is also converted into read write delete operation of file

YYDiskCacheandSwiftlyCacheinDiskCacheThey are all usedSQLiteData caching combined with file can better extend metadata and realizeLRUWhen the cache data exceeds 20K, the metadata is written to the database,valueWrite it in a file

Last words:

Finally completed the release of the final version, I can finally go to wantonly smoke a cigarette, hahaha, also hope that you can put forward more valuable opinions and suggestions… Thank you, cheerleading