Skip to content

Instantly share code, notes, and snippets.

@abhi5658
Last active February 15, 2024 21:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save abhi5658/a02187ca33252c8b5ffd80f6960ed6db to your computer and use it in GitHub Desktop.
Save abhi5658/a02187ca33252c8b5ffd80f6960ed6db to your computer and use it in GitHub Desktop.
Implemeting LRU cache in Javascript via set and map and time complexity O(n x m) (entries x memory size) but m is constant hence complexity is O(n)
let pages = [7, 0, 1, 2, 0, 3, 0, 4, 2, 3, 0, 3, 2];
let memorySize = 4;
function lruCache1() {
let memory = new Set();
let recentUsedPageIndex = new Map();
let pageFault = 0;
for (let i = 0; i < pages.length; i++) {
const currentPage = pages[i];
const isPresentInMemory = memory.has(currentPage);
if (memory.size < memorySize) {
if (!isPresentInMemory) {
pageFault++
memory.add(currentPage);
// recentlyUsedMap.set(index, currentPage)
} else {
// present in memory
// need to update index of that page
// recentUsedPageIndex.set(currentPage,i);
}
} else { // memory is full
if (!isPresentInMemory) {
pageFault++;
// find lru
let lruIndex = Number.MAX_VALUE, lruPage = null;
for (let [page, index] of recentUsedPageIndex.entries()) {
if (index < lruIndex) {
lruIndex = index;
lruPage = page;
}
}
// remove from recentlyUsedMap
memory.delete(lruPage)
recentUsedPageIndex.delete(lruPage);
// set new recentlyUsedMap
// recentUsedPageIndex.set(currentPage,i);
memory.add(currentPage)
} else {
// present in memory
// need to update index of that page
// recentUsedPageIndex.set(currentPage,i);
}
}
// updating index once as applicable for all cases
recentUsedPageIndex.set(currentPage, i);
printCurrentStatus(pageFault, currentPage, memory, recentUsedPageIndex);
}
return pageFault;
}
/**
* Just a refactor with different code flow but using same algorithm
* @returns pageFault
*/
function lruCache2() {
let memory = new Set();
let recentUsedPageIndex = new Map();
let pageFault = 0;
for (let i = 0; i < pages.length; i++) {
const currentPage = pages[i];
const isPresentInMemory = memory.has(currentPage);
if (isPresentInMemory) {
// update index of existing page
recentUsedPageIndex.set(currentPage, i);
} else {
// not present present in memory
pageFault++;
if (memory.size < memorySize) { // add
memory.add(currentPage);
// add index of new page
recentUsedPageIndex.set(currentPage, i);
} else { // remove and add
let lruIndex = Number.MAX_VALUE; // index of least recently used page
let lruPage = null; // least recently used page
for (let [page, index] of recentUsedPageIndex.entries()) {
if (index < lruIndex) {
lruIndex = index;
lruPage = page;
}
}
// remove from memory
memory.delete(lruPage)
recentUsedPageIndex.delete(lruPage);
// add in memory
memory.add(currentPage)
// add index of new page
recentUsedPageIndex.set(currentPage, i);
}
}
printCurrentStatus(pageFault, currentPage, memory, recentUsedPageIndex);
}
return pageFault;
}
console.log('pageFault | page | memory | recentUsedPageIndex')
console.log(lruCache1()); // 6
// pageFault | page | memory | recentUsedPageIndex
// 1 7 Set(1) { 7 } [ '7->0' ]
// 2 0 Set(2) { 7, 0 } [ '7->0', '0->1' ]
// 3 1 Set(3) { 7, 0, 1 } [ '7->0', '0->1', '1->2' ]
// 4 2 Set(4) { 7, 0, 1, 2 } [ '7->0', '0->1', '1->2', '2->3' ]
// 4 0 Set(4) { 7, 0, 1, 2 } [ '7->0', '0->4', '1->2', '2->3' ]
// 5 3 Set(4) { 0, 1, 2, 3 } [ '0->4', '1->2', '2->3', '3->5' ]
// 5 0 Set(4) { 0, 1, 2, 3 } [ '0->6', '1->2', '2->3', '3->5' ]
// 6 4 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->3', '3->5', '4->7' ]
// 6 2 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->8', '3->5', '4->7' ]
// 6 3 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->8', '3->9', '4->7' ]
// 6 0 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->8', '3->9', '4->7' ]
// 6 3 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->8', '3->11', '4->7' ]
// 6 2 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->12', '3->11', '4->7' ]
console.log('=========================');
console.log('pageFault | page | memory | recentUsedPageIndex')
console.log(lruCache2()); // 6
// pageFault | page | memory | recentUsedPageIndex
// 1 7 Set(1) { 7 } [ '7->0' ]
// 2 0 Set(2) { 7, 0 } [ '7->0', '0->1' ]
// 3 1 Set(3) { 7, 0, 1 } [ '7->0', '0->1', '1->2' ]
// 4 2 Set(4) { 7, 0, 1, 2 } [ '7->0', '0->1', '1->2', '2->3' ]
// 4 0 Set(4) { 7, 0, 1, 2 } [ '7->0', '0->4', '1->2', '2->3' ]
// 5 3 Set(4) { 0, 1, 2, 3 } [ '0->4', '1->2', '2->3', '3->5' ]
// 5 0 Set(4) { 0, 1, 2, 3 } [ '0->6', '1->2', '2->3', '3->5' ]
// 6 4 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->3', '3->5', '4->7' ]
// 6 2 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->8', '3->5', '4->7' ]
// 6 3 Set(4) { 0, 2, 3, 4 } [ '0->6', '2->8', '3->9', '4->7' ]
// 6 0 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->8', '3->9', '4->7' ]
// 6 3 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->8', '3->11', '4->7' ]
// 6 2 Set(4) { 0, 2, 3, 4 } [ '0->10', '2->12', '3->11', '4->7' ]
/**
*
* @param {Number} currentPage
* @param {Number} pageFault
* @param {Set} memory
* @param {Map} recentUsedPageIndex
*/
function printCurrentStatus(pageFault, currentPage, memory, recentUsedPageIndex) {
// const memoryStatus = Array.from(memory.values()).map(p => p);
const recentUsedStatus = Array.from(recentUsedPageIndex.entries()).map(arr => { return `${arr[0]}->${arr[1]}` })
console.log(pageFault, currentPage, memory, '\t', recentUsedStatus);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment