首页 > 编程语言 >lua lru算法

lua lru算法

时间:2024-03-25 10:26:46浏览次数:32  
标签:node end -- self lua 算法 lru key 节点

-- 定义一个双向链表节点
local Node = {}
Node.new = function(key, value)
    local node = {}
    node.key = key
    node.value = value
    node.prev = nil
    node.next = nil
    return node
end

-- 定义 LRU 缓存类
local LRUCache = {}
LRUCache.new = function(maxSize)
    local cache = {}
    cache.capacity = maxSize or 10 -- 缓存容量,默认为 10
    cache.size = 0 -- 当前缓存项数
    cache.head = nil -- 缓存头部节点
    cache.tail = nil -- 缓存尾部节点
	cache.map = {} -- 缓存映射表(用于快速查找)

    -- 获取缓存中指定 key 的值
    function cache:get(key)
        local node = self.map[key]
        if node then
            self:moveToHead(node) -- 如果 key 存在,将其移到链表头部
            return node.value
        end
        return nil
    end

    -- 向缓存中插入新的 key-value 对
    function cache:put(key, value)
        local node = self.map[key]
        if node then
            node.value = value -- 如果 key 存在,更新其 value,并将其移到链表头部
            self:moveToHead(node) 
        else
            node = Node.new(key, value) -- 如果 key 不存在,创建一个新的节点
            self.map[key] = node
            if self.size == self.capacity then
                self:removeTail() -- 如果缓存已满,移除尾部节点(最近最少使用的)
            else
                self.size = self.size + 1
            end
            self:addToHead(node) -- 将新节点添加到链表头部(最近使用的)
        end
    end

    -- 从缓存中移除指定 key 的节点
    function cache:remove(key)
        local node = self.map[key]
        if node then
            if node == self.head then
                self.head = node.next -- 如果要移除的节点是头部节点,将头部指针移动到下一个节点
            elseif node == self.tail then
                self.tail = node.prev -- 如果要移除的节点是尾部节点,将尾部指针移动到上一个节点
            else
                node.prev.next = node.next -- 如果要移除的节点在中间,将其前后节点连接起来
                node.next.prev = node.prev 
            end
            self.size = self.size - 1
            self.map[key] = nil
        end
    end

    -- 将节点移到链表头部
    function cache:moveToHead(node)
        if node == self.head then return end
        if node == self.tail then
            self.tail = node.prev
            node.prev = nil
        else
            node.prev.next = node.next
            node.next.prev = node.prev
        end
        node.next = self.head
        node.prev = nil
        self.head = node
        if self.tail == nil then
            self.tail = self.head
        end
    end

    -- 将节点添加到链表头部
    function cache:addToHead(node)
        node.next = self.head
        node.prev = nil
        if self.head then
            self.head.prev = node
        else
            self.tail = node
        end
        self.head = node
        if self.tail == nil then
            self.tail = self.head
        end
    end

    -- 移除尾部节点
    function cache:removeTail()
        local tail = self.tail
        if tail then
            self.tail = tail.prev
            if self.tail then
                self.tail.next = nil
            else
                self.head = nil
            end
            self.size = self.size - 1
            self.map[tail.key] = nil
        end
    end

    return cache
end

local lruCache = LRUCache.new(3)

-- 添加元素
lruCache:put(1, "value1")
lruCache:put(2, "value2")
lruCache:put(3, "value3")

-- 获取元素
print(lruCache:get(2))

-- 添加一个已存在的元素
lruCache:put(2, "newValue")

-- 获取元素
print(lruCache:get(2))

-- 添加一个新元素,超过容量限制
lruCache:put(4, "value4")

-- 获取元素
print(lruCache:get(1))

在上述代码中,我们定义了一个双向链表节点Node和一个 LRU 缓存类LRUCache。LRUCache类有capacity(容量)、size(当前项数)、head(头部节点)、tail(尾部节点)和map(用于快速查找)等属性,以及get、put、remove、moveToHead和addToHead等方法。get方法用于获取缓存中指定 key 的值,如果 key 存在,将其移到链表头部并返回 value;如果 key 不存在,则返回 nil。put方法用于向缓存中插入新的 key-value 对,如果 key 存在,更新其 value,并将其移到链表头部;如果 key 不存在,创建一个新的节点,并将其添加到链表头部。如果缓存已满,put方法还会移除尾部节点。remove方法用于从缓存中移除指定 key 的节点。moveToHead方法用于将节点移到链表头部。addToHead方法用于将节点添加到链表头部。removeTail方法用于移除尾部节点。

在测试代码中,我们首先创建一个容量为 3 的 LRU 缓存,然后依次添加三个元素,分别是1、2和3。接着,我们通过get方法获取2的值,输出其 value。然后,我们通过put方法更新2的值,并再次通过get方法获取2的值,输出其最新的 value。最后,我们通过put方法添加一个新的元素4,此时缓存已满,会移除尾部节点1,然后通过get方法获取1的值,输出为 nil。

标签:node,end,--,self,lua,算法,lru,key,节点
From: https://www.cnblogs.com/txtp/p/18093794

相关文章