ℹ️ Select 'Choose Exercise', or randomize 'Next Random Exercise' in selected language.

Choose Exercise:
Timer 00:00
WPM --
Score --
Acc --
Correct chars --

Resource Caching with Time-Based Eviction

Lua

Goal -- WPM

Ready
Exercise Algorithm Area
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")
Algorithm description viewbox

Resource Caching with Time-Based Eviction

Algorithm description:

This Lua code implements a resource cache with time-based eviction. It stores key-value pairs, where each value has an associated time-to-live (TTL). The `get` operation retrieves a value only if it's still within its TTL. The `set` operation adds or updates an item with a specified TTL. Expired items are automatically removed during `get` operations or periodically via a `cleanup_expired` function. This is crucial for managing frequently accessed but potentially stale data, like user session information or configuration settings.

Algorithm explanation:

The `ResourceCache` uses a Lua table (`self.cache`) to store entries. Each entry is itself a table containing the `value` and its `expiry` timestamp (calculated as `os.time() + ttl`). The `set` method adds or updates an entry, calculating the expiry time. It also includes a simple mechanism to trigger `cleanup_expired` periodically to prevent the cache from growing indefinitely with stale data. The `get` method checks if the key exists and if the current time is before the entry's expiry time. If expired, the entry is removed from the cache (`self.cache[key] = nil`). The `cleanup_expired` function iterates through all cache entries, identifies expired ones, and removes them. Time complexity for `set` is O(1) on average. `get` is O(1) on average, but can be O(N) in the worst case if `cleanup_expired` is triggered and iterates through all N items. Space complexity is O(N), where N is the number of items currently in the cache. Edge cases include setting items with `nil` TTLs (uses default), getting non-existent keys, and handling the case where `cleanup_expired` might be called frequently.

Pseudocode:

Initialize cache with a default TTL.
Set item (key, value, ttl):
  Calculate expiry time (current time + ttl).
  Store item with value and expiry time in cache.
  Periodically trigger cleanup if enough time has passed.
Get item (key):
  If key not in cache, return nil.
  Get entry from cache.
  If current time > entry.expiry:
    Remove item from cache.
    Return nil.
  Else:
    Return item.value.
Cleanup expired items:
  Iterate through all cache entries.
  If entry.expiry < current time:
    Mark entry for removal.
  Remove marked entries from cache.