LRU算法的实现

目录

一,LRU算法

二,使用场景

三,LRU算法实现


一,LRU算法

LRU-least recently used-最近最少使用算法,是一种内存数据淘汰策略,使用常见是当内存不足时,需要淘汰最近最少使用的数据。LRU常用语缓存系统的淘汰策略。

二,使用场景

(1)操作系统里面用于页面置换算法,当分配的内存页不够的时候,可以选择将最近最少使用的页面剔除出去

(2)Redis中的数据淘汰策略: 假设MySQL里面有2000w数据,但redis中只能存20w的数据,如何保证redis中的数据都是热点数据?

Redis 提供 6 种数据淘汰策略:

  1. volatile-lru(least recently used):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

  2. volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

  3. volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

  4. allkeys-lru(least recently used):当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的 key(这个是最常用的)

  5. allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

  6. no-eviction:禁止驱逐数据,也就是说当内存不足以容纳新写入数据时,新写入操作会报错。这个应该没人使用吧!

三,LRU算法实现

本质是通过哈希表辅以双向链表来实现,使用一个哈希表和一个双向链表维护所有在缓存中的键值对。

  • 靠近尾部的键值对是最近使用过的,而靠近头部的是最久未使用的。
  • 哈希表即为普通的哈希映射,通过缓存数据的键映射到其在双向链表中的位置。
package com.example.lrucache;

import java.util.HashMap;
import java.util.Map;

/**
 * @Author YuLing
 * @Date 2024-04-07 8:36
 * @Description:
 * @Version 1.0
 */
public class LRUCache {//最近最少使用

    Node head;
    Node tail;
    int capacity;
    Map<Integer, Node> mp;

    public LRUCache(int capacity){
        this.capacity = capacity;
        mp = new HashMap<>();
        head = tail = null;
    }
    /**
     * 添加节点
     *
     * @param node
     */
    public void addNode(Node node) {//尾插法
        if (head == null) {//如果链表是空
            head = tail = node;
            return;
        }
        tail.next = node;
        node.prev = tail;
        node.next = null;
        tail = node;
    }

    /**
     * 移除结点
     * @param node
     */
    public void removeNode(Node node) {
        if (head == null && tail == null) {
            return;
        }
        if (node == head) {//删除头结点
            head = head.next;
            return;
        }
        if (node == tail) {//删除尾结点
            tail = tail.prev;
            return;
        }
        node.prev.next = node.next;//中间结点
        node.next.prev = node.prev;
    }


    public void put(int key, int value) {
        //如果已经存在
        if (mp.containsKey(key)) {//更新并且从链表中删除
            Node node = mp.get(key);
            node.value = value;
            removeNode(node);
            addNode(node);
        } else {
            //如果链表中不存在
            if (mp.size() >= this.capacity) {//删除头结点,然后插入
                int oldKey = head.key;
                removeNode(head);
                mp.remove(oldKey);//移除旧的
                Node node = new Node(key, value);
                addNode(node);
                mp.put(key, node);
            } else {
                Node node = new Node(key, value);//直接插入
                addNode(node);//添加新的
                mp.put(key,node);
            }
        }
    }

    public int get(int key) {
        if (mp.containsKey(key)) {
            Node node = mp.get(key);
            removeNode(node);
            addNode(node);
            return node.value;
        }
        return -1;//不存在这个元素
    }

    static class Node {
        int key;
        int value;
        Node prev;
        Node next;

        public Node() {}

        public Node(int key, int value) {
            this.key = key;
            this.value = value;
        }
    }

    public static void main(String[] args) {
        LRUCache lruCache = new LRUCache(2);
        lruCache.put(1,1);
        lruCache.put(2,2);
        System.out.println(lruCache.get(1));
        lruCache.put(3,3);
        System.out.println(lruCache.get(2));
        lruCache.put(4,4);
        System.out.println(lruCache.get(1));
        System.out.println(lruCache.get(3));
        System.out.println(lruCache.get(4));
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/530090.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Mac 安装 brew brew cask 遇到的问题以及解决办法

安装Homebrew和Homebrew Cask是在Mac上管理软件包的常用方法。虽然大多数情况下安装这两个工具是比较简单的&#xff0c;但有时候也可能遇到一些问题。下面是一些常见的问题以及解决办法&#xff1a; 问题1&#xff1a;无法安装Homebrew 解决办法&#xff1a; 1.确保你的Mac已连…

4月9日学习记录

[GXYCTF 2019]禁止套娃 涉及知识点&#xff1a;git泄露&#xff0c;无参数RCE 打开环境&#xff0c;源码什么的都没有&#xff0c;扫描后台看看 扫描发现存在git泄露 用githack下载查看得到一串源码 <?php include "flag.php"; echo "flag在哪里呢&#…

REST API实战演练之JavaScript使用Rest API

咱们前面讲了一下如何创建REST API 假期别闲着&#xff1a;REST API实战演练之创建Rest API-CSDN博客 又讲了java客户端如何使用REST API 假期别闲着&#xff1a;REST API实战演练之客户端使用Rest API-CSDN博客 接下来咱们看看JavaScript怎么使用REST API。 一、新建一个…

swiftui macOS实现加载本地html文件

import SwiftUI import WebKitstruct ContentView: View {var body: some View {VStack {Text("测试")HTMLView(htmlFileName: "localfile") // 假设你的本地 HTML 文件名为 index.html.frame(minWidth: 100, minHeight: 100) // 设置 HTMLView 的最小尺寸…

权威报道 | 百分点科技:《突发事件应急预案管理办法》解读

近日&#xff0c;百分点科技CTO刘译璟作为唯一企业界代表&#xff0c;接受应急领域权威期刊——《中国应急管理》杂志邀请&#xff0c;与中国安全生产科学研究院、中央党校、中国政法大学等单位的专家一起&#xff0c;就《突发事件应急预案管理办法》&#xff08;以下简称《办法…

CLI的使用与IOS基本命令

1、实验目的 通过本实验可以掌握&#xff1a; CLI的各种工作模式个CLI各种编辑命令“?” 和【Tab】键使用方法IOS基本命令网络设备访问限制查看设备的相关信息 2、实验拓扑 CLI的使用与IOS基本命令使用拓扑如下图所示。 3、实验步骤 &#xff08;1&#xff09;CLI模式的切…

Vue3 + Vite 构建组件库发布到 npm

你有构建完组件库后&#xff0c;因为不知道如何发布到 npm 的烦恼吗&#xff1f;本教程手把手教你用 Vite 构建组件库发布到 npm 搭建项目 这里我们使用 Vite 初始化项目&#xff0c;执行命令&#xff1a; pnpm create vite my-vue-app --template vue这里以我的项目 vue3-xm…

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之七 简单指定视频某片段快放效果

Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之七 简单指定视频某片段快放效果 目录 Python 基于 OpenCV 视觉图像处理实战 之 OpenCV 简单视频处理实战案例 之七 简单指定视频某片段快放效果 一、简单介绍 二、简单指定视频某片段快放效果实现原理…

Docker内更新Jenkins详细讲解

很多小伙伴在Docker中使用Jenkins时更新遇到困难&#xff0c;本次结合自己的实际经验&#xff0c;详细讲解。根据官网Jenkins了解以下内容&#xff1a; 一、Jenkins 是什么? Jenkins是一款开源 CI&CD 软件&#xff0c;用于自动化各种任务&#xff0c;包括构建、测…

python数据分析和可视化【4】星巴克数据分析

有一组关于全球星巴克门店的统计数据directory.csv&#xff0c;分析了在不同国家和地区以及中国不同城市的星巴克门店的数量。 要求&#xff1a; &#xff08;1&#xff09;查看星巴克旗下有哪些品牌。如果我们只关心星巴克咖啡门店&#xff0c;则只需获取星巴克中Brand的数据集…

多层磁介质让HDD容量翻倍,可超过120TB

近些年&#xff0c;尽管HDD市场收到SSD重创&#xff0c;市场占比遭遇滑坡&#xff0c;但SSD在企业存储市场的侵蚀并未显著增加&#xff0c;SSD容量出货占企业存储&#xff08;HDDSSD&#xff09;总量的比例保持在31-32%左右。然而&#xff0c;考虑到AI优化加速计算对全闪存架构…

XUbuntu22.04之Typora添加水印并输出pdf文件(二百二十七)

简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒体系统工程师系列【原创干货持续更新中……】🚀 优质视频课程:AAOS车载系统+AOSP…

科技动态人工智能应用太空探索生物科技

根据最新的科技资讯&#xff0c;以下是一些值得关注的科技动态&#xff1a; 人工智能领域 智能体热潮 &#xff1a;随着大模型的研发热潮&#xff0c;AI智能体的发展迅速&#xff0c;它们被用作认知核心&#xff0c;具备强大的学习和迁移能力。智能体的架构和交互方式也在不断进…

【保姆级讲解SQL Server的详细使用教程】

&#x1f308;个人主页: 程序员不想敲代码啊 &#x1f3c6;CSDN优质创作者&#xff0c;CSDN实力新星&#xff0c;CSDN博客专家 &#x1f44d;点赞⭐评论⭐收藏 &#x1f91d;希望本文对您有所裨益&#xff0c;如有不足之处&#xff0c;欢迎在评论区提出指正&#xff0c;让我们共…

前端入门:极简登录网页的制作(未使用JavaScript制作互动逻辑)

必备工具&#xff1a;vscode Visual Studio Code - Code Editing. Redefined 目录 前言 准备 HTML源文件的编写&#xff08;构建&#xff09; head部分 body部分 网页背景设置 网页主体构建 CSS源文件的编写&#xff08;设计&#xff09; 结果展示 前言 博主稍稍自…

【C++ 学习】 priority_queue 优先队列的学习!!

1 queue****的介绍** 队列是一种容器适配器&#xff0c;专门用于在FIFO上下文(先进先出)中操作&#xff0c;其中从容器一端插入元素&#xff0c;另一端提取元素。 队列作为容器适配器实现&#xff0c;容器适配器即将特定容器类封装作为其底层容器类&#xff0c;queue提供一组特…

Windows下编译boost库

官网&#xff1a;https://www.boost.org/ 使用git bash运行bootstrap.sh 运行b2.exe,会生成bin.v2文件夹 Cmake引入

jdk和Eclipse软件安装与配置(保姆级别教程)

目录 1、jdk的下载、安装、配置 1.1 jdk安装包的的下载地址&#xff1a;Java Archive | Oracle &#xff0c;点击进入&#xff0c;然后找到你想要的版本下载&#xff0c;如下图&#xff1a; 2.1 开始下载&#xff0c;如下图&#xff1a; 3.1 登入Oracle账号就可以立即下载了…

Java基于微信小程序的日语学习小程序,附源码

博主介绍&#xff1a;✌程序员徐师兄、7年大厂程序员经历。全网粉丝12w、csdn博客专家、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ &#x1f345;文末获取源码联系&#x1f345; &#x1f447;&#x1f3fb; 精彩专栏推荐订阅&#x1f447;…

[Java基础揉碎]StringBuffer类 StringBuild类

目录 StringBuffer类 介绍 继承图 String VS StringBuffer StringBuffer的构造器 String和StringBuffer的转换 StringBuffer类常见方法 测试题 StringBuild类 基本介绍 继承图 String、StringBuffer 和StringBuilder的比较 通过字符串拼接循环测试可以看到各自的性…