Nodejs基于LRU算法实现的缓存处理操作示例


Posted in NodeJs onMarch 17, 2017

本文实例讲述了Nodejs基于LRU算法实现的缓存处理操作。分享给大家供大家参考,具体如下:

LRU是Least Recently Used的缩写,即最近最少使用页面置换算法,是为虚拟页式存储管理服务的,是根据页面调入内存后的使用情况进行决策了。由于无法预测各页面将来的使用情况,只能利用“最近的过去”作为“最近的将来”的近似,因此,LRU算法就是将最近最久未使用的页面予以淘汰。

可以用一个特殊的栈来保存当前正在使用的各个页面的页面号。当一个新的进程访问某页面时,便将该页面号压入栈顶,其他的页面号往栈底移,如果内存不够,则将栈底的页面号移除。这样,栈顶始终是最新被访问的页面的编号,而栈底则是最近最久未访问的页面的页面号。

如输入以下序列时:4,7,0,7,1,0,1,2,1,2,6

结果为:

4
4        7
4        7        0
4        0        7
4        0        7        1
4        7        1        0
4        7        0        1
4        7        0        1        2
4        7        0        2        1
4        7        0        1        2
7        0        1        2        6

适用于Node.js的一个LRU缓存,capacity为缓存容量,为0时构造一般缓存。

function CacheLRU(capacity) {
/* 利用Buffer写的一个LRU缓存,capacity为缓存容量,为0时不限容量。
myCache = new CacheLRU(capacity); //构造缓存
myCache.get(key); //读取名为key的缓存值
myCache.put(key, value); //写入名为key的缓存值
myCache.remove(key); //删除名为key的缓存值
myCache.removeAll(); //清空缓存
myCache.info(); //返回myCache缓存信息
LRU原理:对所有缓存数据的key构建hash链表,当对某一数据进行get或put操作时,将其key提到链表前端(最新)。当进行put数据超出容量时,删除链表尾端(最旧)的缓存数据。
hash链表操作可直接定位key,无需历遍整个hash对象,故读写极快。缓存容量不再影响读写速度。
*/
  this.capacity = capacity || Number.MAX_VALUE;
  this.data = {};
  this.hash = {};
  this.linkedList = {
    length: 0,
    head: null,
    end: null
  }
  if (capacity <= 0) this.capacity = Number.MAX_VALUE;
};
CacheLRU.prototype.get = function(key) {
  key = '_' + key;
  var lruEntry = this.hash[key];
  if (!lruEntry) return;
  refresh(this.linkedList, lruEntry);
  return JSON.parse(this.data[key].toString());
};
CacheLRU.prototype.put = function(key, value) {
  key = '_' + key;
  var lruEntry = this.hash[key];
  if (value === undefined) return this;
  if (!lruEntry) {
    this.hash[key] = {key: key};
    this.linkedList.length += 1;
    lruEntry = this.hash[key];
  }
  refresh(this.linkedList, lruEntry);
  this.data[key] = new Buffer(JSON.stringify(value));
  if (this.linkedList.length > this.capacity) this.remove(this.linkedList.end.key.slice(1));
  return this;
};
CacheLRU.prototype.remove = function(key) {
  key = '_' + key;
  var lruEntry = this.hash[key];
  if (!lruEntry) return this;
  if (lruEntry === this.linkedList.head) this.linkedList.head = lruEntry.p;
  if (lruEntry === this.linkedList.end) this.linkedList.end = lruEntry.n;
  link(lruEntry.n, lruEntry.p);
  delete this.hash[key];
  delete this.data[key];
  this.linkedList.length -= 1;
  return this;
};
CacheLRU.prototype.removeAll = function() {
  this.data = {};
  this.hash = {};
  this.linkedList = {
    length: 0,
    head: null,
    end: null
  }
  return this;
};
CacheLRU.prototype.info = function() {
  var size = 0,
    data = this.linkedList.head;
  while (data){
    size += this.data[data.key].length;
    data = data.p;
  }
  return {
    capacity: this.capacity,
    length: this.linkedList.length,
    size: size
  };
};
// 更新链表,把get或put方法操作的key提到链表head,即表示最新
function refresh(linkedList, entry) {
  if (entry != linkedList.head) {
    if (!linkedList.end) {
      linkedList.end = entry;
    } else if (linkedList.end == entry) {
      linkedList.end = entry.n;
    }
    link(entry.n, entry.p);
    link(entry, linkedList.head);
    linkedList.head = entry;
    linkedList.head.n = null;
  }
}
// 对两个链表对象建立链接,形成一条链
function link(nextEntry, prevEntry) {
  if (nextEntry != prevEntry) {
    if (nextEntry) nextEntry.p = prevEntry;
    if (prevEntry) prevEntry.n = nextEntry;
  }
}
module.exports = CacheLRU;
// test:
/*var user = new CacheLRU(5);
user.put('user1', {name:'admin', age: 30});
user.put('user2', {name:'user', age: 31});
user.put('user3', {name:'guest', age: 32});
user.put('user4', {name:'guest', age: 34});
user.put('user5', {name:'guest', age: 35});
console.log(user.get('user1'));
console.log(user.get('user2'));
console.log(user.get('user3'));
user.put('user6', {name:'guest', age: 36});
console.log(user.info());*/

LRU算法也可以用于一些实际的应用中,如你要做一个浏览器,或类似于淘宝客户端的应用的就要用到这个原理。大家都知道浏览器在浏览网页的时候会把下载的图片临时保存在本机的一个文件夹里,下次再访问时就会,直接从本机临时文件夹里读取。但保存图片的临时文件夹是有一定容量限制的,如果你浏览的网页太多,就会一些你最不常使用的图像删除掉,只保留最近最久使用的一些图片。这时就可以用到LRU算法 了,这时上面算法里的这个特殊的栈就不是保存页面的序号了,而是每个图片的序号或大小;所以上面这个栈的元素都用Object类来表示,这样的话这个栈就可以保存的对像了。

希望本文所述对大家nodejs程序设计有所帮助。

NodeJs 相关文章推荐
nodejs教程 安装express及配置app.js文件的详细步骤
May 11 NodeJs
NodeJS与Mysql的交互示例代码
Aug 18 NodeJs
NodeJS学习笔记之Connect中间件模块(二)
Jan 27 NodeJs
nodejs 整合kindEditor实现图片上传
Feb 03 NodeJs
Express与NodeJs创建服务器的两种方法
Feb 06 NodeJs
详解nodeJS之路径PATH模块
May 31 NodeJs
NodeJS安装图文教程
Apr 19 NodeJs
nodejs实现范围请求的实现代码
Oct 12 NodeJs
NodeJS实现同步的方法
Mar 02 NodeJs
Nodejs核心模块之net和http的使用详解
Apr 02 NodeJs
监控Nodejs的性能实例代码
Jul 02 NodeJs
使用 Koa + TS + ESLlint 搭建node服务器的过程详解
May 30 NodeJs
用nodeJS搭建本地文件服务器的几种方法小结
Mar 16 #NodeJs
nodejs+express实现文件上传下载管理网站
Mar 15 #NodeJs
nodejs搭建本地http服务器教程
Mar 13 #NodeJs
搭建简单的nodejs http服务器详解
Mar 09 #NodeJs
nodejs读写json文件的简单方法(必看)
Mar 09 #NodeJs
Nodejs 获取时间加手机标识的32位标识实现代码
Mar 07 #NodeJs
nodejs中全局变量的实例解析
Mar 07 #NodeJs
You might like
php中的登陆login
2007/01/18 PHP
thinkphp中的url跳转用法分析
2016/07/12 PHP
php获取数据库中数据的实现方法
2017/06/01 PHP
PHP新特性之字节码缓存和内置服务器
2017/08/11 PHP
laravel多条件查询方法(and,or嵌套查询)
2019/10/09 PHP
解决FireFox下[使用event很麻烦]的问题
2006/11/26 Javascript
用AJAX返回HTML片段中的JavaScript脚本
2010/01/04 Javascript
用console.table()调试javascript
2014/09/04 Javascript
基于Jquery实现表单验证
2020/07/20 Javascript
jQuery实现的网页左侧在线客服效果代码
2015/10/23 Javascript
javascript设计模式之module(模块)模式
2016/08/19 Javascript
jQuery双向列表选择器DIV模拟版
2016/11/01 Javascript
Javascript同时声明一连串(多个)变量的方法
2017/01/23 Javascript
浅谈jQuery中的$.extend方法来扩展JSON对象
2017/02/12 Javascript
Vue.js实现按钮的动态绑定效果及实现代码
2017/08/21 Javascript
js es6系列教程 - 基于new.target属性与es5改造es6的类语法
2017/09/02 Javascript
jQuery自动或手动图片切换效果
2017/10/11 jQuery
Vue实现购物车场景下的应用
2017/11/27 Javascript
js实现九宫格布局效果
2020/05/28 Javascript
vue如何在用户要关闭当前网页时弹出提示的实现
2020/05/31 Javascript
微信小程序实现页面监听自定义组件的触发事件
2020/11/01 Javascript
简单谈谈python的反射机制
2016/06/28 Python
python中退出多层循环的方法
2018/11/27 Python
Python3.5文件读与写操作经典实例详解
2019/05/01 Python
对python3 sort sorted 函数的应用详解
2019/06/27 Python
django如何自己创建一个中间件
2019/07/24 Python
把vgg-face.mat权重迁移到pytorch模型示例
2019/12/27 Python
基于PyTorch的permute和reshape/view的区别介绍
2020/06/18 Python
中国专业的综合网上购物商城:京东
2016/08/02 全球购物
专门出售各种儿童读物的网站:Put Me In The Story
2016/08/07 全球购物
Elemental Herbology官网:英国美容品牌
2019/04/27 全球购物
货代行业个人求职简历的自我评价
2013/10/22 职场文书
大学总结自我鉴定
2014/01/18 职场文书
黑暗中的舞者观后感
2015/06/18 职场文书
教学工作总结范文5篇
2019/08/19 职场文书
MySQL千万级数据表的优化实战记录
2021/08/04 MySQL