Some checks failed
Detach Plugins / check (FlyGrep.vim) (push) Has been cancelled
Detach Plugins / check (GitHub.vim) (push) Has been cancelled
Detach Plugins / check (JavaUnit.vim) (push) Has been cancelled
Detach Plugins / check (SourceCounter.vim) (push) Has been cancelled
Detach Plugins / check (cpicker.nvim) (push) Has been cancelled
Detach Plugins / check (dein-ui.vim) (push) Has been cancelled
Detach Plugins / check (git.vim) (push) Has been cancelled
Detach Plugins / check (iedit.vim) (push) Has been cancelled
Detach Plugins / check (scrollbar.vim) (push) Has been cancelled
Detach Plugins / check (vim-chat) (push) Has been cancelled
Detach Plugins / check (vim-cheat) (push) Has been cancelled
Detach Plugins / check (vim-todo) (push) Has been cancelled
Detach Plugins / check (xmake.vim) (push) Has been cancelled
test / Linux (nvim, nightly) (push) Has been cancelled
test / Linux (nvim, v0.3.8) (push) Has been cancelled
test / Linux (nvim, v0.4.0) (push) Has been cancelled
test / Linux (nvim, v0.4.2) (push) Has been cancelled
test / Linux (nvim, v0.4.3) (push) Has been cancelled
test / Linux (nvim, v0.4.4) (push) Has been cancelled
test / Linux (nvim, v0.5.0) (push) Has been cancelled
test / Linux (nvim, v0.5.1) (push) Has been cancelled
test / Linux (nvim, v0.6.0) (push) Has been cancelled
test / Linux (nvim, v0.6.1) (push) Has been cancelled
test / Linux (nvim, v0.7.0) (push) Has been cancelled
test / Linux (nvim, v0.7.2) (push) Has been cancelled
test / Linux (nvim, v0.8.0) (push) Has been cancelled
test / Linux (nvim, v0.8.1) (push) Has been cancelled
test / Linux (nvim, v0.8.2) (push) Has been cancelled
test / Linux (nvim, v0.8.3) (push) Has been cancelled
test / Linux (nvim, v0.9.0) (push) Has been cancelled
test / Linux (nvim, v0.9.1) (push) Has been cancelled
test / Linux (true, vim, v7.4.052) (push) Has been cancelled
test / Linux (true, vim, v7.4.1689) (push) Has been cancelled
test / Linux (true, vim, v7.4.629) (push) Has been cancelled
test / Linux (true, vim, v8.0.0027) (push) Has been cancelled
test / Linux (true, vim, v8.0.0183) (push) Has been cancelled
test / Linux (vim, nightly) (push) Has been cancelled
test / Linux (vim, v8.0.0184) (push) Has been cancelled
test / Linux (vim, v8.0.1453) (push) Has been cancelled
test / Linux (vim, v8.1.2269) (push) Has been cancelled
test / Linux (vim, v8.2.2434) (push) Has been cancelled
test / Linux (vim, v8.2.3995) (push) Has been cancelled
test / Windows (nvim, nightly) (push) Has been cancelled
test / Windows (nvim, v0.3.8) (push) Has been cancelled
test / Windows (nvim, v0.4.2) (push) Has been cancelled
test / Windows (nvim, v0.4.3) (push) Has been cancelled
test / Windows (nvim, v0.4.4) (push) Has been cancelled
test / Windows (nvim, v0.5.0) (push) Has been cancelled
test / Windows (nvim, v0.5.1) (push) Has been cancelled
test / Windows (nvim, v0.6.0) (push) Has been cancelled
test / Windows (nvim, v0.6.1) (push) Has been cancelled
test / Windows (nvim, v0.7.0) (push) Has been cancelled
test / Windows (nvim, v0.7.2) (push) Has been cancelled
test / Windows (nvim, v0.8.0) (push) Has been cancelled
test / Windows (nvim, v0.8.1) (push) Has been cancelled
test / Windows (nvim, v0.8.2) (push) Has been cancelled
test / Windows (nvim, v0.8.3) (push) Has been cancelled
test / Windows (nvim, v0.9.0) (push) Has been cancelled
test / Windows (nvim, v0.9.1) (push) Has been cancelled
test / Windows (vim, nightly) (push) Has been cancelled
test / Windows (vim, v7.4.1185) (push) Has been cancelled
test / Windows (vim, v7.4.1689) (push) Has been cancelled
test / Windows (vim, v8.0.0027) (push) Has been cancelled
test / Windows (vim, v8.0.1453) (push) Has been cancelled
test / Windows (vim, v8.1.2269) (push) Has been cancelled
test / Windows (vim, v8.2.2434) (push) Has been cancelled
test / Windows (vim, v8.2.3995) (push) Has been cancelled
docker / docker (push) Has been cancelled
mirror / check (coding) (push) Has been cancelled
mirror / check (gitee) (push) Has been cancelled
mirror / check (gitlab) (push) Has been cancelled
133 lines
3.0 KiB
Lua
133 lines
3.0 KiB
Lua
---@class CacheNode
|
|
---@field key integer
|
|
---@field value integer
|
|
---@field freq integer
|
|
---@field prev CacheNode
|
|
---@field next CacheNode
|
|
local CacheNode = {}
|
|
|
|
---Initialize the cache node
|
|
---@param key any
|
|
---@param value any
|
|
---@return CacheNode
|
|
function CacheNode.init(key, value)
|
|
return {
|
|
key = key,
|
|
value = value,
|
|
freq = 1,
|
|
prev = nil,
|
|
next = nil,
|
|
}
|
|
end
|
|
|
|
---@class LinkedList
|
|
---@field head CacheNode
|
|
---@field tail CacheNode
|
|
---@field length integer
|
|
local LinkedList = {}
|
|
|
|
---Initialize the linked list
|
|
---@return LinkedList
|
|
function LinkedList.init()
|
|
local self = {}
|
|
self.head = CacheNode.init(0, 0) -- dummy
|
|
self.tail = CacheNode.init(0, 0) -- dummy
|
|
self.head.next = self.tail
|
|
self.tail.prev = self.head
|
|
self.length = 0
|
|
return setmetatable(self, { __index = LinkedList })
|
|
end
|
|
|
|
---Add node
|
|
---@param node CacheNode
|
|
function LinkedList:add(node)
|
|
node.prev = self.head
|
|
node.next = self.head.next
|
|
self.head.next = node
|
|
node.next.prev = node
|
|
self.length = self.length + 1
|
|
end
|
|
|
|
---Remove node
|
|
---@param node CacheNode
|
|
function LinkedList:remove(node)
|
|
node.prev.next = node.next
|
|
node.next.prev = node.prev
|
|
self.length = self.length - 1
|
|
end
|
|
|
|
---@class LfuCache
|
|
---@field capacity integer
|
|
---@field key2node table<any, CacheNode>
|
|
---@field list_map table<integer, LinkedList>
|
|
---@field total_size integer
|
|
---@field min_freq integer
|
|
local LfuCache = {}
|
|
|
|
---Initialize the cache
|
|
---@param capacity integer
|
|
---@return LfuCache
|
|
function LfuCache.init(capacity)
|
|
local self = {}
|
|
self.capacity = capacity
|
|
self.key2node = {}
|
|
self.list_map = { LinkedList.init() }
|
|
self.total_size = 0
|
|
self.min_freq = 0
|
|
return setmetatable(self, { __index = LfuCache })
|
|
end
|
|
|
|
---Add a data to the cache
|
|
---@param key any
|
|
---@param value any
|
|
function LfuCache:set(key, value)
|
|
if self.key2node[key] then
|
|
local node = self.key2node[key]
|
|
node.value = value
|
|
self:_update(node)
|
|
else
|
|
if self.total_size == self.capacity then
|
|
local last_node = self.list_map[self.min_freq].tail.prev
|
|
self.key2node[last_node.key] = nil
|
|
self.list_map[self.min_freq]:remove(last_node)
|
|
self.total_size = self.total_size - 1
|
|
end
|
|
|
|
local new_node = CacheNode.init(key, value)
|
|
self.key2node[key] = new_node
|
|
self.list_map[1]:add(new_node)
|
|
self.min_freq = 1
|
|
self.total_size = self.total_size + 1
|
|
end
|
|
end
|
|
|
|
---Fetching a data from the cache
|
|
---@param key any
|
|
---@return any
|
|
function LfuCache:get(key)
|
|
if self.key2node[key] then
|
|
local node = self.key2node[key]
|
|
self:_update(node)
|
|
return node.value
|
|
end
|
|
end
|
|
|
|
---Update the number of accesses to a node
|
|
---@param node CacheNode
|
|
function LfuCache:_update(node)
|
|
local cur_freq = node.freq
|
|
self.list_map[cur_freq]:remove(node)
|
|
|
|
node.freq = cur_freq + 1
|
|
if not self.list_map[node.freq] then
|
|
self.list_map[node.freq] = LinkedList.init()
|
|
end
|
|
self.list_map[node.freq]:add(node)
|
|
|
|
if self.list_map[self.min_freq].length == 0 then
|
|
self.min_freq = cur_freq + 1
|
|
end
|
|
end
|
|
|
|
return LfuCache
|