欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Nodejs基于LRU算法實(shí)現(xiàn)的緩存處理操作示例

 更新時(shí)間:2017年03月17日 14:35:55   作者:都市煙火  
這篇文章主要介紹了Nodejs基于LRU算法實(shí)現(xiàn)的緩存處理操作,結(jié)合具體實(shí)例形式分析了LRU算法的原理、功能以及nodejs使用LRU算法實(shí)現(xiàn)緩存處理操作的相關(guān)實(shí)現(xiàn)技巧,需要的朋友可以參考下

本文實(shí)例講述了Nodejs基于LRU算法實(shí)現(xiàn)的緩存處理操作。分享給大家供大家參考,具體如下:

LRU是Least Recently Used的縮寫,即最近最少使用頁(yè)面置換算法,是為虛擬頁(yè)式存儲(chǔ)管理服務(wù)的,是根據(jù)頁(yè)面調(diào)入內(nèi)存后的使用情況進(jìn)行決策了。由于無(wú)法預(yù)測(cè)各頁(yè)面將來(lái)的使用情況,只能利用“最近的過(guò)去”作為“最近的將來(lái)”的近似,因此,LRU算法就是將最近最久未使用的頁(yè)面予以淘汰。

可以用一個(gè)特殊的棧來(lái)保存當(dāng)前正在使用的各個(gè)頁(yè)面的頁(yè)面號(hào)。當(dāng)一個(gè)新的進(jìn)程訪問(wèn)某頁(yè)面時(shí),便將該頁(yè)面號(hào)壓入棧頂,其他的頁(yè)面號(hào)往棧底移,如果內(nèi)存不夠,則將棧底的頁(yè)面號(hào)移除。這樣,棧頂始終是最新被訪問(wèn)的頁(yè)面的編號(hào),而棧底則是最近最久未訪問(wèn)的頁(yè)面的頁(yè)面號(hào)。

如輸入以下序列時(shí):4,7,0,7,1,0,1,2,1,2,6

結(jié)果為:

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的一個(gè)LRU緩存,capacity為緩存容量,為0時(shí)構(gòu)造一般緩存。

function CacheLRU(capacity) {
/* 利用Buffer寫的一個(gè)LRU緩存,capacity為緩存容量,為0時(shí)不限容量。
myCache = new CacheLRU(capacity); //構(gòu)造緩存
myCache.get(key); //讀取名為key的緩存值
myCache.put(key, value); //寫入名為key的緩存值
myCache.remove(key); //刪除名為key的緩存值
myCache.removeAll(); //清空緩存
myCache.info(); //返回myCache緩存信息
LRU原理:對(duì)所有緩存數(shù)據(jù)的key構(gòu)建hash鏈表,當(dāng)對(duì)某一數(shù)據(jù)進(jìn)行g(shù)et或put操作時(shí),將其key提到鏈表前端(最新)。當(dāng)進(jìn)行put數(shù)據(jù)超出容量時(shí),刪除鏈表尾端(最舊)的緩存數(shù)據(jù)。
hash鏈表操作可直接定位key,無(wú)需歷遍整個(gè)hash對(duì)象,故讀寫極快。緩存容量不再影響讀寫速度。
*/
  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;
  }
}
// 對(duì)兩個(gè)鏈表對(duì)象建立鏈接,形成一條鏈
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算法也可以用于一些實(shí)際的應(yīng)用中,如你要做一個(gè)瀏覽器,或類似于淘寶客戶端的應(yīng)用的就要用到這個(gè)原理。大家都知道瀏覽器在瀏覽網(wǎng)頁(yè)的時(shí)候會(huì)把下載的圖片臨時(shí)保存在本機(jī)的一個(gè)文件夾里,下次再訪問(wèn)時(shí)就會(huì),直接從本機(jī)臨時(shí)文件夾里讀取。但保存圖片的臨時(shí)文件夾是有一定容量限制的,如果你瀏覽的網(wǎng)頁(yè)太多,就會(huì)一些你最不常使用的圖像刪除掉,只保留最近最久使用的一些圖片。這時(shí)就可以用到LRU算法 了,這時(shí)上面算法里的這個(gè)特殊的棧就不是保存頁(yè)面的序號(hào)了,而是每個(gè)圖片的序號(hào)或大?。凰陨厦孢@個(gè)棧的元素都用Object類來(lái)表示,這樣的話這個(gè)棧就可以保存的對(duì)像了。

希望本文所述對(duì)大家nodejs程序設(shè)計(jì)有所幫助。

相關(guān)文章

  • 淺談使用nodejs搭建web服務(wù)器的過(guò)程

    淺談使用nodejs搭建web服務(wù)器的過(guò)程

    這篇文章主要介紹了淺談使用nodejs搭建web服務(wù)器的過(guò)程,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2020-07-07
  • Nodejs 發(fā)布自己的npm包并制作成命令行工具的實(shí)例講解

    Nodejs 發(fā)布自己的npm包并制作成命令行工具的實(shí)例講解

    今天小編就為大家分享一篇Nodejs 發(fā)布自己的npm包并制作成命令行工具的實(shí)例講解,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 使用Node.js創(chuàng)建本地HTTP服務(wù)器并實(shí)現(xiàn)異地遠(yuǎn)程訪問(wèn)的方法

    使用Node.js創(chuàng)建本地HTTP服務(wù)器并實(shí)現(xiàn)異地遠(yuǎn)程訪問(wèn)的方法

    Node.js 是能夠在服務(wù)器端運(yùn)行 JavaScript 的開(kāi)放源代碼、跨平臺(tái)運(yùn)行環(huán)境,這篇文章主要介紹了如何使用Node.js快速創(chuàng)建本地HTTP服務(wù)器并實(shí)現(xiàn)異地遠(yuǎn)程訪問(wèn),需要的朋友可以參考下
    2024-01-01
  • 使用Node.js創(chuàng)建HTTP服務(wù)器并實(shí)現(xiàn)公網(wǎng)訪問(wèn)本地Server的步驟

    使用Node.js創(chuàng)建HTTP服務(wù)器并實(shí)現(xiàn)公網(wǎng)訪問(wèn)本地Server的步驟

    Node.js含有一系列內(nèi)置模塊,使得程序可以脫離 Apache HTTP Server 或 IIS,作為獨(dú)立服務(wù)器運(yùn),下面將介紹如何簡(jiǎn)單幾步實(shí)現(xiàn)遠(yuǎn)程公共網(wǎng)絡(luò)下訪問(wèn)windwos node.js的服務(wù)端,感興趣的朋友一起看看吧
    2023-11-11
  • Node.js包管理器Yarn的入門介紹與安裝

    Node.js包管理器Yarn的入門介紹與安裝

    大家都知道在yarn發(fā)布之前,所有Nodejs開(kāi)發(fā)者用的都是npm包管理工具,而npm工具存在挺多難以忍受的詬病,包括安裝速度慢、每次都要在線重新安裝等問(wèn)題,而yarn也是為了解決npm當(dāng)前所存在的問(wèn)題而出現(xiàn)的。本文給大家介紹了包管理器Yarn,以及安裝方法。下面來(lái)一起看看。
    2016-10-10
  • 詳解node.js平臺(tái)下Express的session與cookie模塊包的配置

    詳解node.js平臺(tái)下Express的session與cookie模塊包的配置

    本篇文章主要介紹了詳解node.js平臺(tái)下Express的session與cookie模塊包的配置,具有一定的參考價(jià)值,有興趣的可以了解一下。
    2017-04-04
  • Node.js如何對(duì)SQLite的async/await封裝詳解

    Node.js如何對(duì)SQLite的async/await封裝詳解

    這篇文章主要給大家介紹了關(guān)于Node.js如何對(duì)SQLite的async/await進(jìn)行封裝的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2019-02-02
  • 教你用十行node.js代碼讀取docx的文本

    教你用十行node.js代碼讀取docx的文本

    這篇文章主要給大家介紹了用十行node.js代碼讀取docx文本的相關(guān)資料,文中介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-03-03
  • 詳解nodejs微信公眾號(hào)開(kāi)發(fā)——1.接入微信公眾號(hào)

    詳解nodejs微信公眾號(hào)開(kāi)發(fā)——1.接入微信公眾號(hào)

    本篇文章主要介紹了詳解nodejs微信公眾號(hào)開(kāi)發(fā)——1.接入微信公眾號(hào),非常具有實(shí)用價(jià)值,需要的朋友可以參考下
    2017-04-04
  • nodejs不用electron實(shí)現(xiàn)打開(kāi)文件資源管理器并選擇文件

    nodejs不用electron實(shí)現(xiàn)打開(kāi)文件資源管理器并選擇文件

    最近在開(kāi)發(fā)一些小腳本,用 nodejs 實(shí)現(xiàn),其中很多功能需要選擇一個(gè)/多個(gè)文件,或者是選擇一個(gè)文件夾,這種情況下網(wǎng)上給出的解決方案都是 electron,但是我一個(gè)小腳本用 electron 屬實(shí)有點(diǎn)夸張了,后來(lái)轉(zhuǎn)念一想可以通過(guò) powershell 來(lái)實(shí)現(xiàn)類似的功能,需要的朋友可以參考下
    2024-01-01

最新評(píng)論