最近為了更深入學(xué)習(xí)緩存,決定閱讀下YYCache這個(gè)高性能的的緩存框架,剛開始閱讀的時(shí)候各種蒙圈(什么c語言知識啊,鏈表知識啊都是比較少接觸的),慶幸的是這些薄弱的知識在網(wǎng)上都有比較多資源可以學(xué)習(xí)到。
首先去學(xué)習(xí)了下雙向鏈表,簡單點(diǎn)說就是這種鏈表的每個(gè)節(jié)點(diǎn)都有兩個(gè)指針域,分別指向前驅(qū)和后繼,通過這倆個(gè)指針可以訪問節(jié)點(diǎn)的上一個(gè)節(jié)點(diǎn)或下一個(gè)節(jié)點(diǎn)。
然后根據(jù)雙向鏈表知識閱讀了_YYLinkedMap是怎么對鏈表進(jìn)行操作的
把節(jié)點(diǎn)移到鏈表頭節(jié)點(diǎn)
- (void)bringNodeToHead:(_YYLinkedMapNode *)node {
if (_head == node) return;
if (_tail == node) { // node等于鏈表尾節(jié)點(diǎn)時(shí),把_tail往前移一個(gè)節(jié)點(diǎn)并重新設(shè)置為鏈表尾節(jié)點(diǎn)
_tail = node->_prev; // _tail指向鏈表尾節(jié)點(diǎn)上一個(gè)節(jié)點(diǎn)
_tail->_next = nil; // _tail的后繼節(jié)點(diǎn)(鏈表尾節(jié)點(diǎn))置空,使_tail重新成為鏈表尾節(jié)點(diǎn)
} else { // node不等于鏈表尾節(jié)點(diǎn)時(shí),把node前向節(jié)點(diǎn)的下一個(gè)節(jié)點(diǎn)設(shè)置為node后繼節(jié)點(diǎn)
node->_next->_prev = node->_prev; // 把node前向節(jié)點(diǎn)賦值給后繼節(jié)點(diǎn)的前驅(qū)指針
node->_prev->_next = node->_next; // 把node后繼節(jié)點(diǎn)賦值給前向節(jié)點(diǎn)的后驅(qū)指針
}
// 把node設(shè)置成頭節(jié)點(diǎn)
node->_next = _head; //_head賦值給node的后繼指針
node->_prev = nil; //node的前驅(qū)指針置空
_head->_prev = node; //node賦值給_head的前驅(qū)指針
_head = node; //_head指向node
}
把節(jié)點(diǎn)插入鏈表頭節(jié)點(diǎn)
- (void)insertNodeAtHead:(_YYLinkedMapNode *)node {
CFDictionarySetValue(_dic, (__bridge const void *)(node->_key), (__bridge const void *)(node)); // 字典保存鏈表節(jié)點(diǎn)node
_totalCost += node->_cost; // 疊加該緩存開銷到總內(nèi)存開銷
_totalCount++; // 總緩存數(shù)+1
if (_head) {
// 存在鏈表頭,取代當(dāng)前表頭
node->_next = _head;
_head->_prev = node;
// 重新賦值鏈表表頭臨時(shí)變量_head
_head = node;
} else {
// 不存在鏈表頭
_head = _tail = node;
}
}
移除節(jié)點(diǎn)
- (void)removeNode:(_YYLinkedMapNode *)node {
CFDictionaryRemoveValue(_dic, (__bridge const void *)(node->_key)); // 從字典中移除node
_totalCost -= node->_cost; // 減掉總內(nèi)存消耗
_totalCount--; // 總緩存數(shù)-1
//移除node節(jié)點(diǎn)
if (node->_next) node->_next->_prev = node->_prev; // 如果node存在下一個(gè)節(jié)點(diǎn),則把上一個(gè)節(jié)點(diǎn)賦值給下一個(gè)節(jié)點(diǎn)的前驅(qū)指針
if (node->_prev) node->_prev->_next = node->_next; // 如果node存在上一個(gè)節(jié)點(diǎn),則把下一個(gè)節(jié)點(diǎn)賦值給上一個(gè)節(jié)點(diǎn)的后繼指針
if (_head == node) _head = node->_next; // 如果鏈表頭節(jié)點(diǎn)等于node,則node的下一個(gè)節(jié)點(diǎn)賦值給鏈表頭節(jié)點(diǎn)
if (_tail == node) _tail = node->_prev; // 如果鏈表尾節(jié)點(diǎn)等于node,則把node的上一個(gè)節(jié)點(diǎn)賦值給鏈表尾節(jié)點(diǎn)
}
移除尾節(jié)點(diǎn)
- (_YYLinkedMapNode *)removeTailNode {
if (!_tail) return nil;
_YYLinkedMapNode *tail = _tail;// 保留一份要?jiǎng)h除的尾節(jié)點(diǎn)指針
CFDictionaryRemoveValue(_dic, (__bridge const void *)(_tail->_key));// 移除鏈表尾節(jié)點(diǎn)
_totalCost -= _tail->_cost;// 減掉總內(nèi)存消耗
_totalCount--;// 總緩存數(shù)-1
if (_head == _tail) {
_head = _tail = nil;// 清除節(jié)點(diǎn),鏈表上已無節(jié)點(diǎn)了
} else {
// 設(shè)倒數(shù)第二個(gè)節(jié)點(diǎn)為鏈表尾節(jié)點(diǎn)
_tail = _tail->_prev;
_tail->_next = nil;
}
// 返回完tail后_tail將會釋放
return tail;
}
移除所有緩存
- (void)removeAll {
// 清空內(nèi)存開銷與緩存數(shù)量
_totalCost = 0;
_totalCount = 0;
// 清空頭尾節(jié)點(diǎn)
_head = nil;
_tail = nil;
if (CFDictionaryGetCount(_dic) > 0) {
CFMutableDictionaryRef holder = _dic;// 拷貝一份字典
_dic = CFDictionaryCreateMutable(CFAllocatorGetDefault(), 0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);// 重新分配新的空間
if (_releaseAsynchronously) {
// 異步釋放緩存
dispatch_queue_t queue = _releaseOnMainThread ? dispatch_get_main_queue() : YYMemoryCacheGetReleaseQueue();
dispatch_async(queue, ^{
CFRelease(holder); // hold and release in specified queue
});
} else if (_releaseOnMainThread && !pthread_main_np()) {
// 主線程上釋放緩存
dispatch_async(dispatch_get_main_queue(), ^{
CFRelease(holder); // hold and release in specified queue
});
} else {
// 同步釋放緩存
CFRelease(holder);
}
}
}