缓存中实现LRU算法

1、原理概述
     AppCache的实现当中,加上内存缓存,这里使用LRU算法。先说一下LRU算法,其思想就是最近使用的数据那么他下次也是用的概率就会更高,基于这一思想,我们把最近使用的数据放入内存缓存里面,将不常使用的数据存入磁盘,这样来有效的减少访问磁盘的次数,毕竟磁盘访问会占用更多的内存,消耗更长的时间。那么加上一层内存缓存的话可以提升用户体验。
    思路是这样:
          我们用Data来存储数据,内存里面的缓存的话我们就用MutableDictionary,将data作为值(value),将存入文件的名称作为建(key)。算法的实现就交给MutableArray,mutableArray可以方便的取到数组中的第一个元素和最后一个元素(数组中的顺序就是按照最常使用来排序的,当成队列来操作,当用到这个数据,判断是否在array中,如果不在的话就直接插入到队首。如果在的话就删除数据,然后再将其插入到队首)。为了能让array和dictionary一一对应,我们在这里将dictionary的key存放在array当中,这样便于增加和删除数据。
2、具体实现
     首先我们使用单例模式,确保每个类里面使用的都是同一个对象
      + ( instancetype )shareInstance{
   
static ISSTAppCache *cache;
   
static dispatch_once_t predicate;
   
dispatch_once (&predicate, ^{
        cache = [[
ISSTAppCache alloc ] init ];
    });
   
return cache;
}
下面的我们开始使用array和dictionary来实现该算法
NSMutableDictionary *memoryCache;
NSMutableArray *recentlyAccessedKeys;
NSInteger kCacheMemoryLimit;
下面就是主要的实现逻辑,详情在代码中都有备注。
- ( void )cacheData:( NSData *)data toFile:( NSString *)fileName{
   
// 将数据存入缓存
    [
memoryCache setObject :data forKey :fileName];
   
// 判断是否在缓存中,如果在就删除
   
if ([ recentlyAccessedKeys containsObject :fileName]) {
        [
recentlyAccessedKeys removeObject :fileName];
    }
   
// 将最近使用的数据插入队首
    [
recentlyAccessedKeys insertObject :fileName atIndex : 0 ];
   
// 给出一个限制,防止堆满内存
   
if ([ recentlyAccessedKeys count ] > kCacheMemoryLimit ) {
       
// 取出最不常使用的数据
       
NSString *leastRecentlyUsedDataFileName = [ recentlyAccessedKeys lastObject ];
       
NSData *leastRecentlyUsedData = [ memoryCache objectForKey :leastRecentlyUsedDataFileName];
       
// 将这个数据存入到磁盘
       
NSString *archivePath = [[ ISSTAppCache cacheDirectory ] stringByAppendingString :fileName];
        [leastRecentlyUsedData
writeToFile :archivePath atomically : YES ];
       
// 同时删除内存里的数据,注意同时管理 array dictionary
        [
recentlyAccessedKeys removeLastObject ];
        [
memoryCache removeObjectForKey :leastRecentlyUsedDataFileName];
    }
}

- (
NSData *)dataForFile:( NSString *)fileName{
   
// 取出内存缓存,如果有的话直接 return 该数据
   
NSData *data = [ memoryCache objectForKey :fileName];
   
if (data) {
       
return data;
    }
   
// 内存没有的情况下就从磁盘读取
   
NSString *archiverPath = [[ ISSTAppCache cacheDirectory ] stringByAppendingString :fileName];
    data = [
NSData dataWithContentsOfFile :archiverPath];
   
if (data) {
       
// 注意不要忘了将该数据在读入内存当中
        [
self cacheData :data toFile :fileName];
    }
   
return data;
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值