-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlru.lua
121 lines (94 loc) · 2.33 KB
/
lru.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
--[[--
LRU implement in lua
local lrucache = require "lru"
local lru = lrucache:new(max_size=2,expire=3)
local function sleep(n)
os.execute("sleep " .. tonumber(n))
end
lru:set("x","a")
time.sleep(3)
lru:set("y","b")
lru:set("z","c")
lru:set("w","d")
lru.get("x") -- return nil, expired
lru.get("y") -- return nil, reach max count
lru.get("z") -- return c
]]
local LRUCache = {max_size=10000,expire=60*60}
--@max_size default max store 1000 items. if set nil,no upper limit
--@expire default 1 hours. if set nil, never expire
function LRUCache:new(max_size,expire)
local LC = {
max_size = max_size,
expire = expire,
values = {},
expire_times = {},
access_times = {},
}
setmetatable(LC,self)
self.__index = self
return LC
end
function LRUCache.get(self,key)
local t = os.time()
self:cleanup()
if self.values[key] ~= nil then
self.access_times[key] = t
return self.values[key]
else
return nil
end
end
function LRUCache.set(self,key,value)
local t = os.time()
self.values[key] = value
self.expire_times[key] = t + self.expire
self.access_times[key] = t
self:cleanup()
end
function LRUCache.remove(self,key)
self.values[key] = nil
self.expire_times[key] = nil
self.access_times[key] = nil
end
function LRUCache.cleanup(self)
-- remove expired items
if self.expire ~= nil then
for k,v in pairs(self.expire_times) do
if v < os.time() then self:remove(k) end
end
end
if self.max_size == nil then
return
end
-- sort as the access time
sorted_array = self:sort(self.access_times)
-- remove oldest item
while #self > self.max_size do
oldest = sorted_array[1]
self:remove(oldest.key)
end
end
function LRUCache.sort(self,t)
local array = {}
for k,v in pairs(t) do
table.insert(array,{key=k,access=v})
end
table.sort(array,function(a,b) return a.access<b.access end)
return array
end
function LRUCache.__tostring(self)
local s = "{"
local sep = ""
for k,_ in pairs(self.values) do
s = s .. sep .. k
sep = ","
end
return s .. "}"
end
function LRUCache.__len(self)
local count = 0
for _ in pairs(self.values) do count = count +1 end
return count
end
return LRUCache