Răsfoiți Sursa

Extending memory expire duration

onevcat 7 ani în urmă
părinte
comite
731d8419a2

+ 1 - 5
Sources/Cache/DiskStorage.swift

@@ -26,11 +26,7 @@
 
 import Foundation
 
-protocol ExtendingStorage: Storage {
-    func extendExpriration(forKey key: KeyType, lastAccessDate: Date, nextExpiration: StorageExpiration) throws
-}
-
-public class DiskStorage<T: DataTransformable>: ExtendingStorage {
+public class DiskStorage<T: DataTransformable> {
 
     public struct Config {
         let name: String

+ 42 - 1
Sources/Cache/MemoryStorage.swift

@@ -26,14 +26,41 @@
 
 import Foundation
 
+/// Represents a storage which stores a certain type of value in memory. It provides fast access,
+/// but limited storing size. The stored value type needs to conform to `CacheCostCalculatable`,
+/// and its `cacheCost` will be used to determine the cost of size for the cache item.
+///
+/// You can config a `MemoryStorage` in its initializer by passing a `MemoryStorage.Config` value.
+/// or modifying the `config` property after it being created. The backend of `MemoryStorage` has
+/// upper limitaion on cost size in memory and item count. All items in the storage has an expiration
+/// date. When retrieved, if the target item is already expired, it will be recognized as it does not
+/// exist in the storage. The `MemoryStorage` also contains a scheduled self clean task, to evict expired
+/// items from memory.
 public class MemoryStorage<T: CacheCostCalculatable>: Storage {
 
+    /// Represents the config used in a `MemoryStorage`.
     public struct Config {
+        
+        /// Total cost limit of the storage in bytes.
         public var totalCostLimit: Int
+        
+        /// The item count limit of the memory storage.
         public var countLimit: Int = .max
+        
+        /// The `StorageExpiration` used in this memory storage. Default is `.seconds(300)`,
+        /// means that the memory cache would expire in 5 minutes.
         public var expiration: StorageExpiration = .seconds(300)
+        
+        /// The time interval between the storage do clean work for swiping expired items.
+        /// Default is 120, means the auto eviction happens once per two minutes.
         public var cleanInterval: TimeInterval = 120
 
+        /// Creates a config from a given `totalCostLimit` value.
+        ///
+        /// - Parameter totalCostLimit: Total cost limit of the storage in bytes.
+        ///
+        /// - Note:
+        /// Other members of `MemoryStorage.Config` will use their default values when created.
         public init(totalCostLimit: Int) {
             self.totalCostLimit = totalCostLimit
         }
@@ -45,6 +72,8 @@ public class MemoryStorage<T: CacheCostCalculatable>: Storage {
     var cleanTimer: Timer? = nil
     let lock = NSLock()
 
+    /// The config used in this storage. It is a setable value and you can
+    /// use it to config the storage in air.
     public var config: Config {
         didSet {
             storage.totalCostLimit = config.totalCostLimit
@@ -52,6 +81,10 @@ public class MemoryStorage<T: CacheCostCalculatable>: Storage {
         }
     }
 
+    /// Creates a `MemoryStorage` with a given `config`.
+    ///
+    /// - Parameter config: The config used to create the storage. It determines the max size limitation,
+    ///                     default expiration setting and more.
     public init(config: Config) {
         self.config = config
         storage.totalCostLimit = config.totalCostLimit
@@ -102,18 +135,26 @@ public class MemoryStorage<T: CacheCostCalculatable>: Storage {
     }
 
     func value(forKey key: String) throws -> T? {
+        return try value(forKey: key, extendingExpiration: true)
+    }
+    
+    func value(forKey key: String, extendingExpiration: Bool) throws -> T? {
         guard let object = storage.object(forKey: key as NSString) else {
             return nil
         }
         guard object.estimatedExpiration.isFuture else {
             return nil
         }
+        
+        if extendingExpiration { object.extendExpiration() }
         return object.value
     }
 
     func isCached(forKey key: String) -> Bool {
         do {
-            guard let _ = try value(forKey: key) else { return false }
+            guard let _ = try value(forKey: key, extendingExpiration: false) else {
+                return false
+            }
             return true
         } catch {
             return false

+ 12 - 0
Sources/Cache/Storage.swift

@@ -26,10 +26,20 @@
 
 import Foundation
 
+/// Represents the expiration strategy used in storage.
+///
+/// - never: The item never expires.
+/// - seconds: The item expires after a time duration of given seconds from now.
+/// - days: The item expires after a time duration of given days from now.
+/// - date: The item expires after a given date.
 public enum StorageExpiration {
+    /// The item never expires.
     case never
+    /// The item expires after a time duration of given seconds from now.
     case seconds(TimeInterval)
+    /// The item expires after a time duration of given days from now.
     case days(Int)
+    /// The item expires after a given date.
     case date(Date)
 
     func dateSince(_ date: Date) -> Date {
@@ -82,10 +92,12 @@ class StorageObject<T> {
     }
 }
 
+/// Represents types which cost in memory can be calculated.
 public protocol CacheCostCalculatable {
     var cacheCost: Int { get }
 }
 
+/// Represents types which can be converted to and from data.
 public protocol DataTransformable {
     func toData() throws -> Data
     static func fromData(_ data: Data) throws -> Self