当前位置: 首页 > 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)上的命令。以下是对这段内容的解释: …...

浏览器访问 AWS ECS 上部署的 Docker 容器(监听 80 端口)

✅ 一、ECS 服务配置 Dockerfile 确保监听 80 端口 EXPOSE 80 CMD ["nginx", "-g", "daemon off;"]或 EXPOSE 80 CMD ["python3", "-m", "http.server", "80"]任务定义(Task Definition&…...

生成xcframework

打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...

质量体系的重要

质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络&#xf…...

聊一聊接口测试的意义有哪些?

目录 一、隔离性 & 早期测试 二、保障系统集成质量 三、验证业务逻辑的核心层 四、提升测试效率与覆盖度 五、系统稳定性的守护者 六、驱动团队协作与契约管理 七、性能与扩展性的前置评估 八、持续交付的核心支撑 接口测试的意义可以从四个维度展开,首…...

10-Oracle 23 ai Vector Search 概述和参数

一、Oracle AI Vector Search 概述 企业和个人都在尝试各种AI,使用客户端或是内部自己搭建集成大模型的终端,加速与大型语言模型(LLM)的结合,同时使用检索增强生成(Retrieval Augmented Generation &#…...

Rust 开发环境搭建

环境搭建 1、开发工具RustRover 或者vs code 2、Cygwin64 安装 https://cygwin.com/install.html 在工具终端执行: rustup toolchain install stable-x86_64-pc-windows-gnu rustup default stable-x86_64-pc-windows-gnu ​ 2、Hello World fn main() { println…...

rknn toolkit2搭建和推理

安装Miniconda Miniconda - Anaconda Miniconda 选择一个 新的 版本 ,不用和RKNN的python版本保持一致 使用 ./xxx.sh进行安装 下面配置一下载源 # 清华大学源(最常用) conda config --add channels https://mirrors.tuna.tsinghua.edu.cn…...

自然语言处理——文本分类

文本分类 传统机器学习方法文本表示向量空间模型 特征选择文档频率互信息信息增益(IG) 分类器设计贝叶斯理论:线性判别函数 文本分类性能评估P-R曲线ROC曲线 将文本文档或句子分类为预定义的类或类别, 有单标签多类别文本分类和多…...

CTF show 数学不及格

拿到题目先查一下壳,看一下信息 发现是一个ELF文件,64位的 ​ 用IDA Pro 64 打开这个文件 ​ 然后点击F5进行伪代码转换 可以看到有五个if判断,第一个argc ! 5这个判断并没有起太大作用,主要是下面四个if判断 ​ 根据题目…...

C++11 constexpr和字面类型:从入门到精通

文章目录 引言一、constexpr的基本概念与使用1.1 constexpr的定义与作用1.2 constexpr变量1.3 constexpr函数1.4 constexpr在类构造函数中的应用1.5 constexpr的优势 二、字面类型的基本概念与使用2.1 字面类型的定义与作用2.2 字面类型的应用场景2.2.1 常量定义2.2.2 模板参数…...