热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

Magix.Cache引见

转载请说明出处:https:github.comthxmagix…在前端开辟过程当中,我们常常会在内存中缓存一些数据,实在javascript的缓存比较简朴,只须要声明一个变量或把

转载请说明出处:https://github.com/thx/magix/…

在前端开辟过程当中,我们常常会在内存中缓存一些数据,实在Javascript的缓存比较简朴,只须要声明一个变量或把一些数据挂到某个对象上即可,比方我们要完成一个对一切的ajax请求缓存的要领,简朴完成以下:

var cache={};
var request=function(url,callback){
if(cache[url]){
callback(cache[url]);
}else{
$.ajax({
url:url,
success:function(data){
callback(cache[url]=data);
}
});
}
};

注重
示例中仅做简朴演示,未斟酌同时对雷同的url请求屡次,比方

request('/a');
request('/a');

在上述代码中依旧会提议2次对a的请求,这不是我们议论的重点,我们重点议论请求胜利并缓存数据后,再请求该url的事变,所以这个题目略过不题

我们转头看一下我们的request要领,会发明如许的题目:

有些url在全部项目中也许只请求一次,我们依旧对它的效果举行缓存,形成资本被白白占用,假如应用在挪动端,挪动端的内存资本自身就比较珍贵,所以我们不能糟蹋

所以针对request要领中的缓存做一些革新,使它更智能些。我们须要一种算法,保证缓存的个数不能太多,同时缓存的资本数超多时,它能智慧的删掉那些不经常运用的缓存数据

那我们看一下,当我们要完成如许一个算法有哪些症结点要斟酌:

  1. 我们须要晓得缓存中缓存了多少个资本

  2. 当我们从缓存中猎取某个缓存资本时,猎取的算法庞杂度应该是o(1),缓存模块的作用是进步顺序的效力,拿空间换时刻,所以缓存模块不应该占用过量的CPU时刻

明白目的后,我们就须要寻觅适宜的对象来缓存我们的数据:

var obj={}

依据key从obj上查找某个对象,庞杂度是o(1),满足我们的第2条请求,但obj上缓存了多少个资本须要我们自已保护

var obj=[]

依据key查找某个对象时,庞杂度是o(n),但数组有length,能够自动的帮我们保护当前缓存了多少个资本

我们晓得数组是特别的对象,所以我们能够把数组当做一般的对象来用。

当我们把一个缓存对象push进数组时,再依据缓存对象唯一的key,把它放到这个数组对象上

所以这时刻我们第1版本的代码能够相似如许:

var Cache=function(){
this.$cache=[];
};
Cache.prototype.set=function(key,item){
var cache=this.$cache;
var wrap={//包装一次,轻易我们放别的信息,同时应用对象援用通报
key:key,
item:item
};
cache.push(wrap);
cache['cache_'+key]=wrap;//加上cache_的原因是:防备key是数字或可转化为数字的字符串,如许的话就变成了如 cache['2'] 经由过程下标接见数组内里的元素了。
};
Cache.prototype.get=function(key){
var res=this.$cache['cache_'+key];
return res.item;//返回放入的资本
};

运用示例以下:

var c=new Cache();
c.set('/api/userinfo',{
name:'彳刂'
});
console.log(c.get('/api/userinfo'));

这时刻我们就完成了开端请求,晓得缓存个数,查找时庞杂度是o(1)

不过我们依旧须要更智能一些的缓存:

  1. 晓得单个缓存资本的运用频次

  2. 晓得单个缓存资本的末了运用时刻

  3. 缓存中最多能放多少个缓存资本

  4. 什么时刻清算缓存资本

我们革新下适才的代码:

var Cache=function(max){
this.$cache=[];
+ this.$max=max | 0 ||20;
};
Cache.prototype.set=function(key,item){
var cache=this.$cache;
- var wrap={//包装一次,轻易我们放别的信息,同时应用对象援用通报
- key:key,
- item:item
- };
+ key='cache_'+key;
+ var wrap=cache[key];
+ if(!cache.hasOwnProperty(key){
+ wrap={};
+ cache.push(wrap);
+ cache[key]=wrap;
+ }
+ wrap.item=item;
+ wrap.fre=1;//初始运用频次为1
+ wrap.key=key;
+ wrap.time=new Date().getTime();
};
Cache.prototype.get=function(key){
var res=this.$cache['cache_'+key];
if(res){
res.fre++;//更新运用频次
res.time=new Date().getTime();
}
return res.item;//返回放入的资本
};

在我们第2版本的代码中,我们添加了最多缓存资本数max,同时每一个缓存资本到场了运用频次fre及末了运用时刻time,同时我们修改了set要领,斟酌了雷同key的屡次set题目。

我们简朴测试下:

var c=new Cache();
c.set('/api/userinfo',{
name:'彳刂'
});
console.log(c.$cache[0].fre);//1
console.log(c.get('/api/userinfo'));
console.log(c.$cache[0].fre);//2

接下来我们要斟酌一但缓存资本数超出了我们划定的max时,我们要清算掉不经常运用的资本。清算时我们依据频次的运用fre标志,fre最小的优先清算,同时雷同的fre,我们优先清算time比较小的,这也是time设想的意义地点。

所以第3版我们的代码以下:

var Cache=function(max){
this.$cache=[];
this.$max=max | 0 ||20;
};
Cache.prototype.set=function(key,item){
var cache=this.$cache;
key='cache_'+key;
var wrap=cache[key];
if(!cache.hasOwnProperty(key){
+ if(cache.length>=this.$max){
+ cache.sort(function(a,b){
+ return b.fre==a.fre?b.time-a.time:b.fre-a.fre;
+ });
+ var item=cache.pop();//删除频次运用最小,时刻最早的1个
+ delete cache[item.key];//
+ }
wrap={};
cache.push(wrap);
cache[key]=wrap;
}
wrap.item=item;
wrap.fre=1;//初始运用频次为1
wrap.key=key;
wrap.time=new Date().getTime();
};
Cache.prototype.get=function(key){
var res=this.$cache['cache_'+key];
if(res){
res.fre++;//更新运用频次
res.time=new Date().getTime();
}
return res.item;//返回放入的资本
};
+Cache.prototype.has=funciton(key){
+ return this.$cache.hasOwnProperty('cache_'+key);
+};

OK,到这里我们就完成了想要的缓存,我们连系最最先的request要领来举行现实测试:

var cache=new Cache(2);
var request=function(url,callback){
if(cache.has(url)){
callback(cache.get(url);
}else{
$.ajax({
url:url,
success:function(data){
cache.set(url,data);
callback(data);
}
});
}
})
};
//现实运用(假定下一个request要领被调用时,前面request的已完成请求并缓存好了数据):
request('/api/item1');
request('/api/item2');
request('/api/item1');//掷中缓存
request('/api/item3');//到达上限2,cache对象的内部$cache排序一次,删除/api/item2的缓存
request('/api/item4');//依旧到达上限2,cache对象的内部$cache排序一次,删除/api/item3的缓存
request('/api/item3');//接下来须要屡次运用/api/item3,但在请求/api/item4时,它已被删除了,所以我们须要从新请求。完成请求后,由于上限2依旧满足,所以cache对象内部的$cache依旧须要排序一次,删除/api/item4
request('/api/item3');//掷中缓存

依据上述运用,我们发明,一但到达缓存的上限后,带来的题目以下:

  1. 新的缓存资本进来一个,就须要从新排序一次,机能不好

  2. 有能够误删除接下来能够频次运用到的缓存资本

这时刻我们就须要寻觅打破。类比我们常常运用的操作系统的缓存区,我们的缓存是不是也能够到场一个缓冲区呢?当全部缓存列表加上缓冲区都满的时刻,才清空一次缓存区,不只能处理频仍排序的题目,也能很好的保存接下来顺序中能够频仍运用到的缓存资本

来,缓存的第4版:

var Cache=function(max,buffer){
this.$cache=[];
this.$max=max | 0 ||20;
+ this.$buffer=buffer | 0 ||5;
};
Cache.prototype.set=function(key,item){
var cache=this.$cache;
key='cache_'+key;
var wrap=cache[key];
if(!cache.hasOwnProperty(key){
- if(cache.length>=this.$max){
+ if(cache.length>=this.$max+this.$buffer){
cache.sort(function(a,b){
return b.fre==a.fre?b.time-a.time:b.fre-a.fre;
});
- var item=cache.pop();//删除频次运用最小,时刻最早的1个
- delete cache[item.key];//
+ var buffer=this.$buffer;
+ while(buffer--){
+ var item=cache.pop();
+ delete cache[item.key];
+ }
}
wrap={};
cache.push(wrap);
cache[key]=wrap;
}
wrap.item=item;
wrap.fre=1;//初始运用频次为1
wrap.key=key;
wrap.time=new Date().getTime();
};
Cache.prototype.get=function(key){
var res=this.$cache['cache_'+key];
if(res){
res.fre++;//更新运用频次
res.time=new Date().getTime();
}
return res.item;//返回放入的资本
};
Cache.prototype.has=funciton(key){
return this.$cache.hasOwnProperty('cache_'+key);
};

这时刻我们再连系request来测试一下:

var cache=new Cache(2,2);//最大2个,2个缓存区,实在能够缓存4个
var request=function(url,callback){
if(cache.has(url)){
callback(cache.get(url);
}else{
//$.ajax略
}
};
request('/api/item1');
request('/api/item2');
request('/api/item3');//放在缓冲区
request('/api/item4');//放在缓冲区
request('/api/item5');//排序一次,消灭/api/item2 /api/item1
request('/api/item6');//放在缓冲区
request('/api/item7');//放在缓冲区

至此我们就完成了比较完善的缓存模块

固然,后续我们增添缓存资本的性命期,比方20分钟后消灭,也是较轻易的,不在这里详解。

Magix的Cache模块比这里轻微再庞杂些,不过道理都是一样的。

Magix是一个区块治理框架,项目地点在这里magix

区块引见在这里magix区块引见


推荐阅读
  • 计算机存储系统的层次结构及其优势
    本文介绍了计算机存储系统的层次结构,包括高速缓存、主存储器和辅助存储器三个层次。通过分层存储数据可以提高程序的执行效率。计算机存储系统的层次结构将各种不同存储容量、存取速度和价格的存储器有机组合成整体,形成可寻址存储空间比主存储器空间大得多的存储整体。由于辅助存储器容量大、价格低,使得整体存储系统的平均价格降低。同时,高速缓存的存取速度可以和CPU的工作速度相匹配,进一步提高程序执行效率。 ... [详细]
  • WebSocket与Socket.io的理解
    WebSocketprotocol是HTML5一种新的协议。它的最大特点就是,服务器可以主动向客户端推送信息,客户端也可以主动向服务器发送信息,是真正的双向平等对话,属于服务器推送 ... [详细]
  • 服务器上的操作系统有哪些,如何选择适合的操作系统?
    本文介绍了服务器上常见的操作系统,包括系统盘镜像、数据盘镜像和整机镜像的数量。同时,还介绍了共享镜像的限制和使用方法。此外,还提供了关于华为云服务的帮助中心,其中包括产品简介、价格说明、购买指南、用户指南、API参考、最佳实践、常见问题和视频帮助等技术文档。对于裸金属服务器的远程登录,本文介绍了使用密钥对登录的方法,并提供了部分操作系统配置示例。最后,还提到了SUSE云耀云服务器的特点和快速搭建方法。 ... [详细]
  • 模板引擎StringTemplate的使用方法和特点
    本文介绍了模板引擎StringTemplate的使用方法和特点,包括强制Model和View的分离、Lazy-Evaluation、Recursive enable等。同时,还介绍了StringTemplate语法中的属性和普通字符的使用方法,并提供了向模板填充属性的示例代码。 ... [详细]
  • 一、Hadoop来历Hadoop的思想来源于Google在做搜索引擎的时候出现一个很大的问题就是这么多网页我如何才能以最快的速度来搜索到,由于这个问题Google发明 ... [详细]
  • 本文介绍了闭包的定义和运转机制,重点解释了闭包如何能够接触外部函数的作用域中的变量。通过词法作用域的查找规则,闭包可以访问外部函数的作用域。同时还提到了闭包的作用和影响。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 本文介绍了Redis的基础数据结构string的应用场景,并以面试的形式进行问答讲解,帮助读者更好地理解和应用Redis。同时,描述了一位面试者的心理状态和面试官的行为。 ... [详细]
  • 图解redis的持久化存储机制RDB和AOF的原理和优缺点
    本文通过图解的方式介绍了redis的持久化存储机制RDB和AOF的原理和优缺点。RDB是将redis内存中的数据保存为快照文件,恢复速度较快但不支持拉链式快照。AOF是将操作日志保存到磁盘,实时存储数据但恢复速度较慢。文章详细分析了两种机制的优缺点,帮助读者更好地理解redis的持久化存储策略。 ... [详细]
  • 本文介绍了在Vue项目中如何结合Element UI解决连续上传多张图片及图片编辑的问题。作者强调了在编码前要明确需求和所需要的结果,并详细描述了自己的代码实现过程。 ... [详细]
  • 深入理解Kafka服务端请求队列中请求的处理
    本文深入分析了Kafka服务端请求队列中请求的处理过程,详细介绍了请求的封装和放入请求队列的过程,以及处理请求的线程池的创建和容量设置。通过场景分析、图示说明和源码分析,帮助读者更好地理解Kafka服务端的工作原理。 ... [详细]
  • 在编写业务代码时,常常会遇到复杂的业务逻辑导致代码冗长混乱的情况。为了解决这个问题,可以利用中间件模式来简化代码逻辑。中间件模式可以帮助我们更好地设计架构和代码,提高代码质量。本文介绍了中间件模式的基本概念和用法。 ... [详细]
  • Imtryingtofigureoutawaytogeneratetorrentfilesfromabucket,usingtheAWSSDKforGo.我正 ... [详细]
  • 网络请求模块选择——axios框架的基本使用和封装
    本文介绍了选择网络请求模块axios的原因,以及axios框架的基本使用和封装方法。包括发送并发请求的演示,全局配置的设置,创建axios实例的方法,拦截器的使用,以及如何封装和请求响应劫持等内容。 ... [详细]
  • 本文介绍了获取关联数组键的列表的方法,即使用Object.keys()函数。同时还提到了该方法在不同浏览器的支持情况,并附上了一个代码片段供读者参考。 ... [详细]
author-avatar
廖汉林1026_843
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有