”工欲善其事,必先利其器。“—孔子《论语.录灵公》
首页 > 编程 > 使用 Javascript 实现 LRU 缓存

使用 Javascript 实现 LRU 缓存

发布于2024-10-31
浏览:921

LRU Cache Implementation using Javascript

介绍

LRU 代表最近最少使用。 LRU 缓存是一种缓存,当缓存达到其容量时,最近最少使用的条目将被删除。

  • 使用LRU缓存的主要原因是为了提高访问数据的性能。从缓存访问数据通常比从主内存或远程服务器检索数据更快。
  • 通过将最近使用的数据存储在缓存中,增加了缓存命中的机会,从而提高了数据检索的速度。

供参考:

  • 映射数据结构用于模仿哈希表的行为。这允许高效的查找、插入和删除操作。
  • 实现了双链表以实现元素之间的轻松移动。这提供了双向遍历(向前和向后)并执行恒定时间插入和删除的能力。
  • 这两种数据结构的结合可以实现高效的操作,利用哈希表和双链表的优点。

以下是如何在 JavaScript 中实现 LRU 缓存的基本示例:

// Why we need this LRU
class Node {
    constructor(key, value) {
        this.key = key;
        this.value = value;
        this.next = null;
        this.prev = null;
    }
}

//Least Recently used
class LRU {
    constructor() {
     this.head = this.tail = null;
     this.map = new Map();
     this.size = 0; // Why I added size, because may be in future we can say if capacity reach to the size, we will remove the tail first and then insert.
    }

    get(key) {
        if (this.map.has(key)) {
            const node = this.map.get(key);

            if (node !== this.head) {
                this.remove(node);
                this.insert(node);
            }

            return node.value;
        }

        return -1;
    }

    update(key, value) {
        if (this.map.has(key)) {
            let node = this.map.get(key);
            node.value = value;

            if (node !== this.head) {
                this.remove(node);
                this.insert(node);
            }

            return node.value;
        } else {
            console.log('Key not found'); 
            // Here we can check for capacity if available we can call insert
            // if capacity is not available we will remove the tail and then insert.
        }
    }

    remove(node) {
        if (node === this.tail) {
            this.tail = this.tail.prev;
        }

        const prevNode = node.prev;
        const nextNode = node.next;

        prevNode.next = nextNode;
        nextNode.prev = prevNode;
    }

    insert(key, value) {
        const newNode = new Node(key, value);
        this.map.set(key, newNode);
        if (this.head === null) {
            this.head = this.tail = newNode;
            this.size = 1;
            return;
        }
        // We need to insert at the Begining
        newNode.next = this.head;
        this.head.prev = newNode;
        this.head= newNode;
        this.size  ;
        return;
    }
}

const test = new LRU();
test.insert('A', 20);
test.insert('B', 10);
test.insert('C', 5);
test.insert('D', 7);

console.log(test);
console.log('------------------');
console.log('C ---> ', test.get('C'));
console.log('D ---> ', test.get('D'));

console.log('D ---> ', test.update('B', 100));

/*
LRU {
  tail:  Node {
    key: 'A',
    value: 20,
    next: null,
    prev: Node { key: 'B', value: 10, next: [Circular *1], prev: [Node] }
  },
  head:  Node {
    key: 'D',
    value: 7,
    next: Node { key: 'C', value: 5, next: [Node], prev: [Circular *2] },
    prev: null
  },
  map: Map(4) {
    'A' =>  Node {
      key: 'A',
      value: 20,
      next: null,
      prev: [Node]
    },
    'B' => Node { key: 'B', value: 10, next: [Node], prev: [Node] },
    'C' => Node { key: 'C', value: 5, next: [Node], prev: [Node] },
    'D' =>  Node {
      key: 'D',
      value: 7,
      next: [Node],
      prev: null
    }
  },
  size: 4
}
------------------
C --->  5
D --->  7
D --->  100
B --->  100
*/

如果您有任何疑问,请随时与我联系。

版本声明 本文转载于:https://dev.to/ashutoshsarangi/lru-cache-implementation-using-javascript-48no?1如有侵犯,请联系[email protected]删除
最新教程 更多>
  • 如何修复由于 MySQL 严格模式导致 Laravel Eloquent 中的“SELECT 列表的表达式 #1 不在 GROUP BY 子句中”错误?
    如何修复由于 MySQL 严格模式导致 Laravel Eloquent 中的“SELECT 列表的表达式 #1 不在 GROUP BY 子句中”错误?
    Laravel Eloquent 中与 sql_mode=only_full_group_by 不兼容遇到错误“SELECT 列表的表达式 #1 不在 GROUP BY 子句中.. .” 当执行带有分组的 Eloquent 查询时,表明与 MySQL 的 sql_mode=only_full_gro...
    编程 发布于2024-11-08
  • 冰冷的池塘如何帮助您理解 C++ 中未定义的行为?
    冰冷的池塘如何帮助您理解 C++ 中未定义的行为?
    理解初学者的未定义行为对于新程序员来说,未定义行为是一个很难掌握的概念,特别是当他们在工作中遇到过它时实践其具体实施。为了帮助新手理解避免未定义行为的重要性,可以采用一个有效的类比。想象一个结冰的池塘,其中冰的厚度和稳定性是不可预测的。假设你走过池塘一次,它成立。这能保证每次都能安全通过吗?当然不是...
    编程 发布于2024-11-08
  • 在 Go 中使用 WebSocket 进行实时通信
    在 Go 中使用 WebSocket 进行实时通信
    构建需要实时更新的应用程序(例如聊天应用程序、实时通知或协作工具)需要一种比传统 HTTP 更快、更具交互性的通信方法。这就是 WebSockets 发挥作用的地方!今天,我们将探讨如何在 Go 中使用 WebSocket,以便您可以向应用程序添加实时功能。 在这篇文章中,我们将介绍: WebSoc...
    编程 发布于2024-11-08
  • 如何在Vue.js组件中动态加载外部JS脚本?
    如何在Vue.js组件中动态加载外部JS脚本?
    在 Vue.js 组件中动态加载外部 JS 脚本使用支付网关时,集成促进交易的外部脚本变得必要。然而,通常不希望在初始页面加载时加载这些脚本。这就是 Vue.js 提供的解决方案,用于在特定组件中动态加载外部脚本。要实现此目的,请利用 Vue.js 组件中的 Mounted() 生命周期挂钩。 Mo...
    编程 发布于2024-11-08
  • 如何使用 Foreach 循环查找 PHP 数组中的最后一个元素?
    如何使用 Foreach 循环查找 PHP 数组中的最后一个元素?
    使用 PHP 的 foreach 循环查找数组中的最后一个元素在 PHP 中,在 foreach 循环中访问数组的最后一个元素需要与 Java 相比,这是一种更细致的方法,可以直接检查数组长度。使用计数和增量要确定最后一个元素,您可以利用 count( ) 函数,返回数组中的元素数量:$numIte...
    编程 发布于2024-11-08
  • 如何解决Python中的循环依赖问题?
    如何解决Python中的循环依赖问题?
    Python 中的循环依赖解析在 Python 中,当模块相互依赖其定义时,可能会遇到循环依赖。当两个文件(node.py 和 path.py)分别定义类 Node 和 Path,并且每个文件都引用另一个文件时,就会出现这样的情况。最初,path.py 导入 node.py 来访问 Node目的。然...
    编程 发布于2024-11-08
  • rnr:适用于每个项目运行脚本的工具
    rnr:适用于每个项目运行脚本的工具
    嘿,JavaScript 和 TypeScript 开发者! ?您是否厌倦了使用不同的命令来启动各种 JS 项目?好吧,我有一些令人兴奋的消息要告诉你!我创建了一个名为 rnr(发音为“runner”)的工具,它使运行任何 JavaScript 或 TypeScript 项目变得超级容易。 ...
    编程 发布于2024-11-08
  • Java 的可选类型如何简化“Get”调用链中空值的处理?
    Java 的可选类型如何简化“Get”调用链中空值的处理?
    使用可选的“Get”调用链安全导航在 Java 编程中,经常会遇到“get”调用链,如下所示:house.getFloor(0).getWall(WEST).getDoor().getDoorknob();为了避免潜在的 NullPointerExceptions,开发人员通常采用详细的 null ...
    编程 发布于2024-11-08
  • 大泥球:理解反模式以及如何避免它
    大泥球:理解反模式以及如何避免它
    前端开发中最臭名昭著的架构反模式可能是大泥球。术语“大泥球”适用于没有明显结构或模块化组织的系统。代码库有机且混乱地增长,成为维护的噩梦。这是许多开发人员发现自己所处的情况,特别是当他们面临着按时完成任务并开发大量功能的压力时。 这就是当前文章的内容:大泥球反模式以及前端开发中的示例,为什么它如此常...
    编程 发布于2024-11-08
  • 如何正确使用带 Map 参数的“reflect.Call”函数?
    如何正确使用带 Map 参数的“reflect.Call”函数?
    解决reflect包中的.Call使用问题在reflect包中使用.Call函数时,遵守所需的参数格式至关重要。本文将指导您完成正确使用 .Call 函数并操作 in 变量以满足目标方法的过程。提供的示例代码中:params := "some map[string][]string&quo...
    编程 发布于2024-11-08
  • 如何使用 HTML 和 CSS 创建翻页卡动画
    如何使用 HTML 和 CSS 创建翻页卡动画
    在这篇文章中,我们将了解如何使用 HTML 和 CSS 以及渐变背景创建时尚的 3D 翻转卡片动画。 访问我的网站 了解结构 我们将使用卡片的两侧(正面和背面)来创建翻转效果。此效果将在悬停时使用 CSS 过渡激活。 <div class="card"> <...
    编程 发布于2024-11-08
  • Python 中的 len() 函数有多高效?
    Python 中的 len() 函数有多高效?
    Python 中 len() 函数的成本影响len() 函数是 Python 内置功能的组成部分,提供有关各种数据结构的长度的信息。具体来说,它通常与列表、元组、字符串和字典一起使用,以确定它们所包含的元素或字符的数量。与直观的感知相反,len() 函数的计算成本保持不变跨越所有上述数据类型。这意味...
    编程 发布于2024-11-08
  • 如何在 Java 中将 Long 值转换为字节数组并返回?
    如何在 Java 中将 Long 值转换为字节数组并返回?
    在 Java 中将 Long 转换为字节数组并返回在 Java 中,将 long 基本数据类型转换为字节数组 (byte[] ),反之亦然是各种操作的常见任务,例如通过 TCP 连接发送数据。下面是实现此转换的全面解决方案:Long 到 Byte Arraypublic byte[] longToB...
    编程 发布于2024-11-08
  • 如何使用 Selenium 在 Google Chrome 中模拟 Microsoft Edge Mobile?
    如何使用 Selenium 在 Google Chrome 中模拟 Microsoft Edge Mobile?
    使用 Selenium 更改 Google Chrome 中的用户代理在 Selenium 自动化脚本中,为浏览器窗口设置特定的用户代理对于模拟设备行为和确保网站渲染至关重要正如预期的那样。在这种情况下,我们的目标是将 Google Chrome 中的用户代理修改为 Microsoft Edge M...
    编程 发布于2024-11-08
  • 哪种 MySQL 获取函数适合您的 PHP 应用程序:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比较
    哪种 MySQL 获取函数适合您的 PHP 应用程序:`mysql_fetch_array`、`mysql_fetch_assoc` 和 `mysql_fetch_object` 的比较
    比较 mysql_fetch_array、mysql_fetch_assoc 和 mysql_fetch_object:综合分析mysql 函数系列在从 MySQL 查询中检索结果中起着至关重要的作用在 PHP 中。在这些函数中,mysql_fetch_array、mysql_fetch_assoc...
    编程 发布于2024-11-08

免责声明: 提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发到邮箱:[email protected] 我们会第一时间内为您处理。

Copyright© 2022 湘ICP备2022001581号-3