YYCache设计思路及源码学习
设计思路
利用YYCache来进行操作,实质操作分为了内存缓存操作(YYMemoryCache)和硬盘缓存操作(YYDiskCache)。内存缓存设计一般是在内存中开辟一个空间用以保存请求的数据(一般使用字典操作)。硬盘缓存设计即是将文件保存至本地,这种保存分为小文件保存和大文件保存,对于小文件保存使用数据库操作性能效率相对较高,对于大文件则使用直接存放。YYDiskCache为线程安全的类,其操作是基于YYKVStorage(线程不安全的类)的操作。以下为大致源码分析
主类YYCache
必须初始化名字 名字即为存储路径,NS_DESIGNATED_INITIALIZER提示为设计初始化方法,UNAVAILABLE_ATTRIBUTE定义为未实现方法,关于这两种宏定义都存在于系统框架中
- (instancetype)initWithPath:(NSString *)path NS_DESIGNATED_INITIALIZER;
- (instancetype)init UNAVAILABLE_ATTRIBUTE;
+ (instancetype)new UNAVAILABLE_ATTRIBUTE;
最终构造函数如下所示:包含了硬盘缓存和内存缓存
- (instancetype)initWithPath:(NSString *)path {
if (path.length == 0) return nil;
YYDiskCache *diskCache = [[YYDiskCache alloc] initWithPath:path];
if (!diskCache) return nil;
NSString *name = [path lastPathComponent];
YYMemoryCache *memoryCache = [YYMemoryCache new];
memoryCache.name = name;
self = [super init];
_name = name;
_diskCache = diskCache;
_memoryCache = memoryCache;
return self;
}
对于YYCache所设计方法,所做操作本质上来说就是增删改查,内部本质是对YYDiskCache和YYMemoryCache的操作,由于读取效率的问题,读取时先有内存缓存中读取,若没有则由硬盘缓存中读取(再存入内存缓存中)
- (BOOL)containsObjectForKey:(NSString *)key
- (void)containsObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key, BOOL contains))block
- (id<NSCoding>)objectForKey:(NSString *)key
- (void)objectForKey:(NSString *)key withBlock:(void(^)(NSString *key, id<NSCoding> object))block
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key
- (void)setObject:(id<NSCoding>)object forKey:(NSString *)key withBlock:(void(^)(void))block
- (void)removeObjectForKey:(NSString *)key
- (void)removeObjectForKey:(NSString *)key withBlock:(void(^)(NSString *key))block
- (void)removeAllObjects
- (void)removeAllObjectsWithBlock:(void(^)(void))block
- (void)removeAllObjectsWithProgressBlock:(void(^)(int removedCount, int totalCount))progress
endBlock:(void(^)(BOOL error))end
YYMemoryCache和YYDiskCache
为了方便理解和YYCache对YYDiskCache和YYMemoryCache的操作,两类的通用接口设计如下
- (BOOL)containsObjectForKey:(id)key
- (id)objectForKey:(id)key
- (void)setObject:(id)object forKey:(id)key
- (void)setObject:(id)object forKey:(id)key withCost:(NSUInteger)cost
- (void)removeObjectForKey:(id)key
- (void)removeAllObjects
在YYDiskCache则包含了YYCache中所有的接口设计
YYMemoryCache
主要成员变量
pthread_mutex_t(保证线程安全)
_YYLinkedMap自定义类(主包含数据映射字典和链表(根据LRU算法计算自动移除的节点))
dispatch_queue_t操作队列(保证线程不阻塞)
其中YYLinkeedMap包含了如下成员变量--LRU算法:常使用节点被移动到头结点,即经常使用的节点靠前越靠后就为越不常使用的节点具体实现可查看类中的insertNodeAtHead和bringNodeToHead方法CFMutableDictionaryRef _dic; // 字典内 存放对应的缓存数据
NSUInteger _totalCost;
NSUInteger _totalCount;
_YYLinkedMapNode *_head; // 头结点
_YYLinkedMapNode *_tail; // 尾节点,利用LRU算法实现
BOOL _releaseOnMainThread;
BOOL _releaseAsynchronously;
YYDiskCache
主要成员变量
- YYKVStorage *_kv; //硬盘存储主要类(线程不安全)
- dispatch_semaphore_t _lock;
- dispatch_queue_t _queue;
在YYDiskCache中所做的操作都是基于YYKVStorage的操作,只是增加了信号量上锁以保证线程安全
YYKVStorage
此类主要是利用sqlite3和数据库打交道,当然对于比较大型的文件是直接使用系统的write方法来进行文件保存,这样能更大限度的提升效率。在YYKVStorage的存储中都是以对象的方式进行存储,其对象封装为YYKVStorageItem其中的字段设计如下
key text,
filename text,
size integer,
inline_data blob,
modification_time integer,
last_access_time integer,
extended_data blob,
primary key(key)
剩下的就是YYKVStorage如何利用sqlite3进行数据的访问,关于sqlite3的操作就不详述了。
以上便是整个YYCache设计的主要思路,当然里面包含了其他的一些东西。以笔者目前的功力还不能吃透,其中便是YYDispatchQueuePool,在这里YYCache中利用了自己设计的队列池来进行管理。由于没有这方面的经验和时间来学习。这一块就算留作以后研究的一个点吧。
最后贴上YY大神关于自己YYCache的设计思路链接
YYCache设计思路及源码学习的更多相关文章
- asp.net abp模块化开发之通用树2:设计思路及源码解析
一.前言 上一篇大概说了下abp通用树形模块如何使用,本篇主要分析下设计思路. 日常开发中会用到很多树状结构的数据,比如:产品的多级分类.省市区县,大多数系统也会用到类似“通用字典/数据字典”的功能, ...
- CopyOnWriteArrayList设计思路与源码分析
CopyOnWriteArrayList实现了List接口,RandomAccess,Cloneable,Serializable接口. CopyOnWriteArrayList特性 1.线程安全,在 ...
- 【 js 基础 】【 源码学习 】源码设计 (持续更新)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析第二部分:undersc ...
- 【 js 基础 】【 源码学习 】源码设计 (更新了backbone分析)
学习源码,除了学习对一些方法的更加聪明的代码实现,同时也要学习源码的设计,把握整体的架构.(推荐对源码有一定熟悉了之后,再看这篇文章) 目录结构:第一部分:zepto 设计分析 第二部分:unders ...
- Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载)
Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构(源码可下载) 说明:Java开源生鲜电商平台-性能优化以及服务器优化的设计与架构,我采用以下三种维度来讲解 1. 代码层面. 2. 数 ...
- Vue2.1.7源码学习
原本文章的名字叫做<源码解析>,不过后来想想,还是用“源码学习”来的合适一点,在没有彻底掌握源码中的每一个字母之前,“解析”就有点标题党了.建议在看这篇文章之前,最好打开2.1.7的源码对 ...
- JDK源码学习笔记——Integer
一.类定义 public final class Integer extends Number implements Comparable<Integer> 二.属性 private fi ...
- Vue.js 源码学习笔记
最近饶有兴致的又把最新版 Vue.js 的源码学习了一下,觉得真心不错,个人觉得 Vue.js 的代码非常之优雅而且精辟,作者本身可能无 (bu) 意 (xie) 提及这些.那么,就让我来吧:) 程序 ...
- spring源码学习之AOP(一)
继续源码学习,看了spring中基础的容器和AOP感觉自己也没有什么长进,哈哈,我也不知道到底有用没有,这可能是培养自己的一种精神吧,不管那么多,继续学习!AOP中 AOP中几个重要的概念:(1)Ad ...
随机推荐
- c#:如何处理对对象进行深度拷贝
/// <summary> /// 对对象进行深度拷贝 /// </summary> /// <param name="obj"></pa ...
- 开始学习bizTalk server了
开始学习bizTalk Server 2013 R2了,有兴趣的朋友可以关注我,一同学习
- MVC中使用jquery uploadify上传图片报302错误
使用jquery uploadify上传图片报302错误研究了半天,发现我上传的action中有根据session判断用户是否登录,如果没有登录就跳到登陆页,所以就出现了302跳转错误.原来更新了fl ...
- 论文阅读(Xiang Bai——【PAMI2017】An End-to-End Trainable Neural Network for Image-based Sequence Recognition and Its Application to Scene Text Recognition)
白翔的CRNN论文阅读 1. 论文题目 Xiang Bai--[PAMI2017]An End-to-End Trainable Neural Network for Image-based Seq ...
- cento下安装elasticsearch2.4.2小记
1.首先需要安装好java,并配置好环境变量 2.下载elasticsearch的rpm包,命令如下: wget https://download.elastic.co/elasticsearch/r ...
- (五)SQL入门 数据库查询
什么是查询?查询就是Select语句对数据库的探究. 查询是一种目的,一种需求,一种期望.是Select语句去实现的.Select语句不是只是指select语句,而是多个子句一起使用得组合. sele ...
- iOS屏幕旋转
三种方法 需求:全局主要是竖屏 个别界面需要横屏
- c# winform vlcPlayer播放器
vlcPlayer是一款免费开源的播放器项目,可以播放几乎所有的视频格式. 第一步:获取dll 安装vlcplayer视频播放器,在安装目录下面获取所需的dll. dll文件夹:plugins 还有2 ...
- Fuel UX wizard example
<!DOCTYPE html> <html class="no-js fuelux"> <head> <meta charset=&quo ...
- 基于layerpage 前后端异步分页
#下载jquery 和 layerpage1.核心分页方法 laypage({ cont: 'page1', //容器.值支持id名.原生dom对象,jquery对象. pages: json.tot ...