1local ResourceCache = {}
2
3function ResourceCache:new(default_ttl)
4local self = {
5cache = {},
6default_ttl = default_ttl or 60 -- Default time-to-live in seconds
7}
8setmetatable(self, {__index = ResourceCache})
9-- Start a background cleanup process (simplified for example)
10-- In a real app, this might be a coroutine or timer-based job
11-- For this example, cleanup happens on 'get' or 'set' if a threshold is met
12self.last_cleanup_time = os.time()
13return self
14end
15
16function ResourceCache:set(key, value, ttl)
17local current_time = os.time()
18local expiry_time = current_time + (ttl or self.default_ttl)
19
20self.cache[key] = {
21value = value,
22expiry = expiry_time
23}
24
25-- Perform cleanup if it's been a while since last cleanup
26if current_time - self.last_cleanup_time > 30 then -- Cleanup every 30 seconds
27self:cleanup_expired()
28self.last_cleanup_time = current_time
29end
30end
31
32function ResourceCache:get(key)
33local entry = self.cache[key]
34if not entry then
35return nil -- Key not found
36end
37
38local current_time = os.time()
39if current_time > entry.expiry then
40-- Item has expired, remove it and return nil
41self.cache[key] = nil
42return nil
43else
44-- Item is valid, return its value
45return entry.value
46end
47end
48
49function ResourceCache:cleanup_expired()
50local current_time = os.time()
51local keys_to_remove = {}
52
53for key, entry in pairs(self.cache) do
54if current_time > entry.expiry then
55table.insert(keys_to_remove, key)
56end
57end
58
59for _, key in ipairs(keys_to_remove) do
60self.cache[key] = nil
61end
62-- print("Cleanup: Removed " .. #keys_to_remove .. " expired items.") -- Debugging
63end
64
65function ResourceCache:clear()
66self.cache = {}
67self.last_cleanup_time = os.time()
68end
69
70function ResourceCache:get_size()
71return #self.cache
72end
73
74-- Example Usage:
75-- -- Create a cache with a default TTL of 5 seconds
76-- local my_cache = ResourceCache:new(5)
77--
78-- -- Set some items
79-- my_cache:set("user_data_123", { name = "Alice", level = 10 })
80-- my_cache:set("config_settings", { volume = 0.8, music = true }, 10) -- Override TTL to 10 seconds
81--
82-- -- Get items immediately
83-- local user1 = my_cache:get("user_data_123")
84-- print("User data 123: ", user1 and user1.name or "Not found or expired")
85--
86-- local config = my_cache:get("config_settings")
87-- print("Config settings: ", config and config.volume or "Not found or expired")
88--
89-- -- Wait for expiration (simulated)
90-- print("Waiting for 6 seconds...")
91-- -- In a real scenario, you'd use a delay function like coroutine.yield(6) or a timer.
92-- -- For this example, we'll manually call cleanup or rely on the next 'get' call.
93-- -- Let's simulate waiting by advancing time conceptually.
94-- -- For demonstration, we'll just check after a delay.
95--
96-- -- Simulate waiting for 6 seconds (conceptually)
97-- -- In a real Lua environment, you'd use coroutine.yield() or a timer.
98-- -- For this script, we'll just check the state after setting.
99--
100-- -- Let's manually trigger cleanup to see effect
101-- my_cache:cleanup_expired()
102--
103-- -- Try to get expired item
104-- local user1_after_expiry = my_cache:get("user_data_123")
105-- print("User data 123 after expiry: ", user1_after_expiry and user1_after_expiry.name or "Not found or expired")
106--
107-- -- Try to get non-expired item (config should still be there if TTL was 10s)
108-- local config_after_expiry = my_cache:get("config_settings")
109-- print("Config settings after expiry check: ", config_after_expiry and config_after_expiry.volume or "Not found or expired")
110--
111-- -- Set an item with a very short TTL
112-- my_cache:set("temp_data", "some value", 1)
113-- print("Temp data set.")
114-- -- Wait 2 seconds (conceptually)
115-- my_cache:cleanup_expired() -- Force cleanup
116-- local temp = my_cache:get("temp_data")
117-- print("Temp data after 2s: ", temp or "Expired")