YYDiskCache
是YYCache
组件中负责磁盘缓存的。
涉及知识点:
- 磁盘缓存策略的分流优化
- KVStore非关系型数据存储
- 线程同步锁(信号量)
由于YYDiskCache
是对YYKVStorage
的封装调用
YYKVStorage
3种存储方式
1 2 3 4 5 6 7 8
| typedef NS_ENUM(NSUInteger, YYKVStorageType) { YYKVStorageTypeFile = 0, YYKVStorageTypeSQLite = 1, YYKVStorageTypeMixed = 2, };
|
本地文件路径
1 2 3 4 5 6 7 8 9
| /path/ /manifest.sqlite /manifest.sqlite-shm /manifest.sqlite-wal /data/ /e10adc3949ba59abbe56e057f20f883e /e10adc3949ba59abbe56e057f20f883e /trash/ /unused_file_or_folder
|
YYKVStorage
会根据存储方式进行数据的增删改查;
YYKVStorage
不是线程安全的
数据库
初始化
1 2 3 4 5 6 7 8 9 10 11
| create table if not exists manifest ( key text, filename text, size integer, inline_data blob, modification_time integer, last_access_time integer, extended_data blob, primary key(key) ); create index if not exists last_access_time_idx on manifest(last_access_time);
|
日志模式采用wal方式;sqlite3.7版本之后支持;
检查点
1 2 3 4 5
| - (void)_dbCheckpoint { if (![self _dbCheck]) return; sqlite3_wal_checkpoint(_db, NULL); }
|
YYKVStorageItem
数据流context
1 2 3 4 5 6 7 8 9
| @interface YYKVStorageItem : NSObject @property (nonatomic, strong) NSString *key; @property (nonatomic, strong) NSData *value; @property (nullable, nonatomic, strong) NSString *filename; @property (nonatomic) int size; @property (nonatomic) int modTime; @property (nonatomic) int accessTime; @property (nullable, nonatomic, strong) NSData *extendedData; @end
|
YYDiskCache
线程同步
1 2
| #define Lock() dispatch_semaphore_wait(self->_lock, DISPATCH_TIME_FOREVER) #define Unlock() dispatch_semaphore_signal(self->_lock)
|
读写的时候都用到了该锁
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| - (void)setObject:(id<NSCoding>)object forKey:(NSString *)key { ... Lock(); [_kv saveItemWithKey:key value:value filename:filename extendedData:extendedData]; Unlock(); }
- (id<NSCoding>)objectForKey:(NSString *)key { Lock(); YYKVStorageItem *item = [_kv getItemForKey:key]; Unlock(); ... }
|
自动清理
YYDiskCache
也使用了LRU的算法,定时清理
成长
- 磁盘缓存的解决方案
- 信号量实现线程锁
- 数据库wal的存储方式
- 封装同步执行和异步执行的思路