当前位置: 首页 > news >正文

lua-lru缓存算法解析

lua-lru缓存算法解析

  • 主要功能和作用
    • 1. 缓存管理:
    • 2. 数据存储与访问:
    • 3. 迭代器:
    • 4. 容量管理:
  • 具体实现细节
  • 使用场景
  • 使用示例

lua-lru 是 Lua 语言中的一个 LRU(Least Recently Used,最近最少使用)缓存实现,是一个基于哈希表和双向链表的数据结构,用于管理缓存中的数据项,并根据访问频率自动淘汰最不常用的数据项

-- lua-lru, LRU cache in Lua
-- Copyright (c) 2015 Boris Nagaev
-- See the LICENSE file for terms of use.local lru = {}function lru.new(max_size, max_bytes)assert(max_size >= 1, "max_size must be >= 1")assert(not max_bytes or max_bytes >= 1,"max_bytes must be >= 1")-- current sizelocal size = 0local bytes_used = 0-- map is a hash map from keys to tuples-- tuple: value, prev, next, key-- prev and next are pointers to tupleslocal map = {}-- indices of tuplelocal VALUE = 1local PREV = 2local NEXT = 3local KEY = 4local BYTES = 5-- newest and oldest are ends of double-linked listlocal newest = nil  -- firstlocal oldest = nil  -- lastlocal removed_tuple -- created in del(), removed in set()-- remove a tuple from linked listlocal function cut(tuple)local tuple_prev = tuple[PREV]local tuple_next = tuple[NEXT]tuple[PREV] = niltuple[NEXT] = nilif tuple_prev and tuple_next thentuple_prev[NEXT] = tuple_nexttuple_next[PREV] = tuple_prevelseif tuple_prev then-- tuple is the oldest elementtuple_prev[NEXT] = niloldest = tuple_prevelseif tuple_next then-- tuple is the newest elementtuple_next[PREV] = nilnewest = tuple_nextelse-- tuple is the only elementnewest = niloldest = nilendend-- insert a tuple to the newest endlocal function setNewest(tuple)if not newest thennewest = tupleoldest = tupleelsetuple[NEXT] = newestnewest[PREV] = tuplenewest = tupleendendlocal function del(key, tuple)map[key] = nilcut(tuple)size = size - 1bytes_used = bytes_used - (tuple[BYTES] or 0)removed_tuple = tupleend-- removes elemenets to provide enough memory-- returns last removed element or nillocal function makeFreeSpace(bytes)while size + 1 > max_size or(max_bytes and bytes_used + bytes > max_bytes)doassert(oldest, "not enough storage for cache")del(oldest[KEY], oldest)endendlocal function get(_, key)local tuple = map[key]if not tuple thenreturn nilendcut(tuple)setNewest(tuple)return tuple[VALUE]endlocal function set(_, key, value, bytes)local tuple = map[key]if tuple thendel(key, tuple)endif value ~= nil then-- the value is not removedbytes = max_bytes and (bytes or #value) or 0makeFreeSpace(bytes)local tuple1 = removed_tuple or {}map[key] = tuple1tuple1[VALUE] = valuetuple1[KEY] = keytuple1[BYTES] = max_bytes and bytessize = size + 1bytes_used = bytes_used + bytessetNewest(tuple1)elseassert(key ~= nil, "Key may not be nil")endremoved_tuple = nilendlocal function delete(_, key)return set(_, key, nil)endlocal function mynext(_, prev_key)local tupleif prev_key thentuple = map[prev_key][NEXT]elsetuple = newestendif tuple thenreturn tuple[KEY], tuple[VALUE]elsereturn nilendend-- returns iterator for keys and valueslocal function lru_pairs()return mynext, nil, nilendlocal mt = {__index = {get = get,set = set,delete = delete,pairs = lru_pairs,},__pairs = lru_pairs,}return setmetatable({}, mt)
endreturn lru

主要功能和作用

1. 缓存管理:

  • lua-lru 可创建一个最多可以存储 max_size 个数据项的缓存,并且可以选择限制缓存的总字节数 max_bytes
  • 当缓存达到最大容量时,会自动淘汰最久未使用的数据项,以腾出空间给新数据

2. 数据存储与访问:

  • set(key, value, bytes):将数据项存储到缓存中,如果缓存中已经存在相同的 key,则会替换旧数据,如果缓存达到最大容量或字节限制,会自动淘汰最久未使用的数据项
  • get(key):从缓存中获取数据项,如果数据项存在,将其移动到链表的最新位置(即标记为最近使用)
  • delete(key):从缓存中删除指定的数据项

3. 迭代器:

  • lru_pairs():返回一个迭代器,用于遍历缓存中的所有数据项,迭代器按最近使用到最久未使用的顺序遍历

4. 容量管理:

  • makeFreeSpace(bytes):当缓存即将超出容量限制时,自动删除最久未使用的数据项,直到有足够的空间或字节数

具体实现细节

  • 双向链表:用于维护数据项的访问顺序,最近访问的数据项放在链表的前端,最久未访问的数据项放在链表的后端
  • 哈希表:用于快速查找数据项,哈希表的键是缓存的键,值是一个包含数据、链表前后指针等信息的数据结构
  • 自动淘汰:当缓存达到最大容量或字节数限制时,通过删除链表尾部的数据项来释放空间

使用场景

  • 数据缓存:适用于需要缓存数据的场景,特别是在数据访问频率高但存储空间有限的情况下
  • 限流:可以用于实现限流机制,淘汰掉长时间未使用的数据项,确保缓存中保留的是最近活跃的数据
  • 性能优化:在一些需要频繁访问数据但数据量较大的场景中,通过 LRU 缓存可以显著提高访问性能

使用示例

local lru = require("lru")local cache = lru.new(3, 100) -- 创建一个最多存储3个数据项,最大100字节的缓存cache:set("key1", "value1", 10) -- 存储数据项,占用10字节
cache:set("key2", "value2", 20) -- 存储数据项,占用20字节
cache:set("key3", "value3", 30) -- 存储数据项,占用30字节print(cache:get("key1")) -- 输出 "value1"cache:set("key4", "value4", 40) -- 存储新数据项,占用40字节,淘汰 "key1" 因为它是最近最少使用的print(cache:get("key1")) -- 输出 nil,因为 "key1" 已经被淘汰for key, value in cache:pairs() doprint(key, value) -- 按最近使用到最久未使用的顺序遍历缓存
end

相关文章:

lua-lru缓存算法解析

lua-lru缓存算法解析 主要功能和作用1. 缓存管理:2. 数据存储与访问:3. 迭代器:4. 容量管理: 具体实现细节使用场景使用示例 lua-lru 是 Lua 语言中的一个 LRU(Least Recently Used,最近最少使用&#xff0…...

Python - 初识Python;Python解释器下载安装;Python IDE(一)

一、初识Python Python 是一种高级编程语言,Python是一种面向对象的解释型计算机程序设计语言,Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆()Guido van Rossum吉多范罗苏姆()于1989 年底发明…...

鸿蒙学习基本概念

文章目录 1、当前移动应用开发中遇到的主要挑战包括:2、 新的应用生态应该具备如下特征:3、HarmonyOS 应用:使用 HarmonyOS SDK 开发的应用程序,能够在华为终端设备4、HarmonyOS 元服务:元服务是 HarmonyOS 面向万物互…...

正则表达式(补充)

定义一个正则表达式 const 变量名 /表达式/ const reg /前端/ 匹配看字符串中有无前端俩字 正则对象上的一些方法 test() 用于查看正则表达式与指定的字符串是否匹配 const reg /前端/ const res reg.test(学前端,找黑马) //匹配到返回true,匹配不到返回fa…...

第23课-C++-红黑树的插入与旋转

🌇前言 红黑树是一种自平衡的二叉搜索树,因其出色的性能,广泛应用于实际中。Linux 内核中的 CFS 调度器便是一个使用红黑树的例子,这足以说明它的重要性。红黑树的实现通过红黑两种颜色的控制来维持平衡,并在必要时使…...

【C#】C#编程入门指南:构建你的.NET开发基础

文章目录 前言:1. C# 开发环境 VS的基本熟悉2. 解决方案与项目的关系3. 编辑、编译、链接、运行4. 托管代码和CLR4.1 CLR:4.2 C# 代码第编译过程(两次编译的) 5. 命名空间6. 类的组成与分析7. C# 的数据类型7.1 值类型7.2 引用类型…...

[系统安全] PE文件知识在免杀中的应用

0x1 PE文件与免杀思路 基于PE文件结构知识的免杀技术主要用于对抗启发式扫描。 通过修改PE文件中的一些关键点来达到欺骗反病毒软件的目的。 修改区段名 1.1 移动PE文件头位置免杀 工具:PeClean SizeOfOptionalHeader字段来描述扩展头的大小,恒定值为…...

相机标定原理

相机标定原理 什么是相机标定相机畸变 什么是相机标定 为了确定空间物体表面某点的三维几何位置与其在图像中对应点之间的相互关系,需建立相机成像的几何模型,几何模型参数即为相机参数,求解相机参数的过程就是相机标定。 坐标系 **世界坐标…...

Linux基础开发工具使用

目录 1. 软件包管理器yum 1.1 概念介绍 1.2 更换镜像源(可选) 1.3 工具的搜索/查看/安装/卸载 1.4 优势 2. vim编辑器 2.1 vi和vim 2.2 三种常用模式和操作 2.3 配置vim 3. Linux编译器-gcc/g 4. Linux调试器-gdb 5. make和Makefile 6.…...

蓝牙PBAP协议及Android实现

文章目录 前言一、什么是PBAP协议?PBAP的关键功能 二、PBAP的工作流程PBAP流程 三、PBAP在Android实现关键步骤:1. 检查设备是否支持 PBAP 服务 2. 创建 PBAP 连接3. 发送 OBEX 请求4. 解析 vCard 数据数据存储与展示6. 性能优化建议7. 完整示例&#xf…...

Py之pymupdf:基于langchain框架结合pymupdf库实现输出每个PDF页面的文本内容、元数据等

Py之pymupdf:基于langchain框架结合pymupdf库实现输出每个PDF页面的文本内容、元数据等 目录 PyMuPDFLoader类 初始化 属性 方法 __init__(file_path, *, headers=None, extract_images=False, **kwargs) lazy_load() aload() alazy_load() load(**kwargs) load_and…...

LeetCode题解:17.电话号码的数字组合【Python题解超详细,回溯法、多叉树】,知识拓展:深度优先搜索与广度优先搜索

题目描述 给定一个仅包含数字 2-9 的字符串,返回所有它能表示的字母组合。答案可以按 任意顺序 返回。给出数字到字母的映射如下(与电话按键相同)。注意 1 不对应任何字母。 示例 1: 输入:digits "23" 输出…...

《JVM第10课》内存溢出(OOM)排查过程

文章目录 常用命令1. jps2. jconsole3. jstat4. jmap 工具1.jvisualvm 排查OOM的方法其实很简单很简单。 如果能找到拋OOM的日志,可以在日志里看到是哪一行抛出的OOM异常。如果找不到日志,那么处理方式是导出Java进程的内存快照,然后用工具查…...

Thinkphp6视图介绍

一.MVC MVC 软件系统分为三个基本部分:模型(Model)、视图(View)和控制器(Controller) ThinkPHP6 是一个典型的 MVC 架构 控制器—控制器,用于将用户请求转发给相应的Model进行处理&a…...

躺平成长-人工智能进行编程-(12)

躺平成长: 让每一个人在科技(开源的网络/智能科技对于生活琐事的处理)的帮助下,实现养生反卷,躺平成长。 开源竞争: 当你无法彻底掌握技术的时候,你就开源这个技术,形成技术依赖&a…...

计算机网络中的域名系统(DNS)及其优化技术

💓 博客主页:瑕疵的CSDN主页 📝 Gitee主页:瑕疵的gitee主页 ⏩ 文章专栏:《热点资讯》 计算机网络中的域名系统(DNS)及其优化技术 计算机网络中的域名系统(DNS)及其优化…...

Matplotlib库中show()函数的用法

在Matplotlib库中使用show()函数是用于显示绘制的图形的函数。它将图形显示在屏幕上或保存到文件中。show()函数通常在绘制完图形后调用。 Matplotlib是一个用于绘制2D图形的Python库,它提供了丰富的绘图工具和函数,可以用于创建各种类型的图表&#xf…...

C#中object和dynamic

在C#中,object和dynamic都是用于存储不同类型值的类型,但它们之间存在一些关键的区别: object object是C#中的基元类型之一,是所有其他类型的最终基类。当你将一个值赋给object类型的变量时,编译器会执行装箱操作&am…...

Spring Cloud Eureka 服务注册与发现

Spring Cloud Eureka 服务注册与发现 一、Eureka基础知识概述1.Eureka两个核心组件2.Eureka 服务注册与发现 二、Eureka单机搭建三、Eureka集群搭建四、心跳续约五、Eureka自我保护机制 一、Eureka基础知识概述 1.Eureka两个核心组件 Eureka Server :服务注册中心…...

【WPF】Prism学习(三)

Prism Commands 1.复合命令(Composite Commanding) 这段内容主要介绍了在应用程序中如何使用复合命令(Composite Commands)来实现多个视图模型(ViewModels)上的命令。以下是对这段内容的解释: …...

ComfyUI自定义节点开发指南:从零构建你的专属AI工具链

1. 为什么需要自定义ComfyUI节点? 第一次用ComfyUI做AI绘画时,我就被它灵活的节点式操作吸引了。但用着用着发现一个问题:官方提供的节点虽然强大,但总有些特殊需求无法满足。比如想给生成的图片自动打水印、批量处理文件夹里的图…...

别再踩坑了!手把手教你搞定vllm、nccl、cuda和python的版本匹配(附版本对照表)

深度学习环境配置避坑指南:vLLM与CUDA生态的版本兼容性实战 在部署大型语言模型推理服务时,vLLM因其高效的内存管理和推理优化成为热门选择。但许多开发者第一次接触vLLM时,往往会被复杂的依赖关系搞得焦头烂额——NCCL版本不匹配、CUDA驱动…...

Qwen2.5-VL-3B视频识别实战:从环境搭建到显存优化的踩坑记录

Qwen2.5-VL-3B视频识别实战:从环境搭建到显存优化的全流程指南 当开发者第一次尝试用Qwen2.5-VL-3B处理视频内容时,往往会遇到各种预料之外的挑战。从依赖包缺失到显存爆炸,从环境配置到参数调试,每一步都可能成为阻碍项目推进的绊…...

FedProto:跨异构客户端的原型联邦学习实践指南

1. 从零理解FedProto的核心思想 第一次听说FedProto时,我正被一个医疗影像分析项目搞得焦头烂额。五家医院的数据就像五个方言区——同样的病症在CT影像上呈现的特征分布天差地别。传统联邦学习就像让这些医院用各自的方言写报告,再强行翻译成标准语&…...

PySR社区贡献指南:如何参与这个革命性符号回归开源项目的开发

PySR社区贡献指南:如何参与这个革命性符号回归开源项目的开发 【免费下载链接】PySR High-Performance Symbolic Regression in Python and Julia 项目地址: https://gitcode.com/gh_mirrors/py/PySR 想要为高性能符号回归工具PySR做出贡献吗?这份…...

Webflux fromXXX对比

Mono.fromFuture和Mono.fromSupplier 刚开始尝试使用 Spring WebFlux 的时候,很多人都会使用 Mono.fromFuture() 将异步请求转成 Mono 对象,或者 Mono.fromSupplier() 将请求转成 MOno 对象,这两种方式在响应式编程 中都是不建议的&#xff0…...

手把手教你用EFR32BG22实现BLE串口透传(附GATT配置全流程)

EFR32BG22低功耗蓝牙串口透传开发实战指南 在物联网终端设备开发中,蓝牙串口透传是最基础也最实用的功能之一。本文将带您深入EFR32BG22芯片的蓝牙开发世界,从零开始构建一个高效的BLE串口透传服务。不同于简单的代码搬运,我们将重点关注GATT…...

SystemVerilog进阶:深入探索随机化约束的高级应用

1. 从基础到进阶:SystemVerilog随机化约束的核心价值 在芯片验证领域,随机化验证已经成为提高验证效率的黄金标准。SystemVerilog的随机化约束机制,就像给验证工程师配备了一个智能数据生成器,可以自动产生符合设计规范的测试场景…...

高分辨率路面缺陷检测数据集:道路健康状态自动监测的关键资源

路面缺陷检测数据集yolo掌握道路健康状态对于维护和规划都至关重要。 本数据集精选6100张高清图像,专门标注了道路表面的四种常见缺陷,包括鳄鱼状裂纹、横向裂纹、纵向裂纹和坑洞,旨在为道路维护和自动化检测提供强有力的数据支持。 图像集已…...

AI 模型推理框架性能分析与对比

AI模型推理框架性能分析与对比 随着人工智能技术的快速发展,AI模型推理框架成为支撑各类应用落地的核心工具。无论是计算机视觉、自然语言处理还是推荐系统,高效的推理框架直接影响模型的响应速度、资源占用和部署成本。本文将从多个维度对比主流AI推理…...