YYMemoryCache 的底层浅析
YYMemoryCache是内存缓存,主要用到两种数据结构的LRU淘汰算法。
两种数据结构分别为 :
哈希表、双向链表
LRU淘汰算法:
缓存淘汰算法,遵循先入先出原则,通过自定义缓存个数,超出缓存个数以后把不常用的缓存移出队列。
源码片段:
_YYLinkedMapNode: 双向指针结点
_prev: 头指针
_next: 尾指针
_key :缓存的key
_value:缓存的对象
_cost:开销
_time:记录缓存的时间戳
dic:哈希表
_head:头结点
_tail:尾结点
_totalCost:总缓存开销
_totalCount:总缓存数量
insertNodeAtHead
- (void)insertNodeAtHead:(_YYLinkedMapNode *)node {
CFDictionarySetValue(_dic, (__bridge const void *)(node->_key), (__bridge const void *)(node));
_totalCost += node->_cost;
_totalCount++;
if (_head) {
node->_next = _head;
_head->_prev = node;
_head = node;
} else {
_head = _tail = node;
}
}
插入数据到链表,通过累计插入的node的cost来计算总开销,每插入一个算出总得缓存数据
如果有数据就直接插入并建立连接
没有的话就给首尾借点赋值(没有使用虚拟结点)
bringNodeToHead
- (void)bringNodeToHead:(_YYLinkedMapNode *)node {
if (_head == node) return;
if (_tail == node) {
_tail = node->_prev;
_tail->_next = nil;
} else {
node->_next->_prev = node->_prev;
node->_prev->_next = node->_next;
}
node->_next = _head;
node->_prev = nil;
_head->_prev = node;
_head = node;
}
通过判断头结点是否与插入的结点是否相等,来判断是否只有一个,
如果尾结点合node相等,就是插入的node为链表最尾一位,把node前一位变成尾结点
如果node非首尾结点,就把node前后两个结点链接起来
最后把node结点放到头,原来的头结点在node后面
removeNode
- (void)removeNode:(_YYLinkedMapNode *)node {
CFDictionaryRemoveValue(_dic, (__bridge const void *)(node->_key));
_totalCost -= node->_cost;
_totalCount--;
if (node->_next) node->_next->_prev = node->_prev;
if (node->_prev) node->_prev->_next = node->_next;
if (_head == node) _head = node->_next;
if (_tail == node) _tail = node->_prev;
}
删除结点
通过node的key移除哈希表里面的缓存
通过node的key结算_totalCost总缓存
_totalCount总缓存数减小
如果node不为首尾结点,就把node的前后两位互相连结
如果node为头结点,头结点指向node的下一位结点
如果node为尾结点,尾结点指向node的前一位
本次浅析主要是对自己学习的一次记录,同时也为正在学习的你指个路。