author | Kim Alvefur <zash@zash.se> |
Tue, 23 Apr 2024 20:01:41 +0200 | |
changeset 13486 | 4d697961546d |
parent 13179 | bbdaa770b955 |
permissions | -rw-r--r-- |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 |
|
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
local function _remove(list, m) |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
if m.prev then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 |
m.prev.next = m.next; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 |
if m.next then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 |
m.next.prev = m.prev; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
9 |
if list._tail == m then |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
10 |
list._tail = m.prev; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
12 |
if list._head == m then |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
13 |
list._head = m.next; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
15 |
list._count = list._count - 1; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 |
|
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 |
local function _insert(list, m) |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
19 |
if list._head then |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
20 |
list._head.prev = m; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
22 |
m.prev, m.next = nil, list._head; |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
23 |
list._head = m; |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
24 |
if not list._tail then |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
25 |
list._tail = m; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
27 |
list._count = list._count + 1; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 |
|
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
30 |
local cache_methods = {}; |
11202
c4c06fbb7d87
util.cache: Add __name to metatable
Matthew Wild <mwild1@gmail.com>
parents:
8401
diff
changeset
|
31 |
local cache_mt = { __name = "cache", __index = cache_methods }; |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
32 |
|
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 |
function cache_methods:set(k, v) |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
34 |
local m = self._data[k]; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 |
if m then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 |
-- Key already exists |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 |
if v ~= nil then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 |
-- Bump to head of list |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 |
_remove(self, m); |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 |
_insert(self, m); |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 |
m.value = v; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 |
else |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
-- Remove from list |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 |
_remove(self, m); |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
45 |
self._data[k] = nil; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 |
end |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
47 |
return true; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 |
-- New key |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 |
if v == nil then |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
51 |
return true; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 |
-- Check whether we need to remove oldest k/v |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
54 |
if self._count == self.size then |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
55 |
local tail = self._tail; |
7293
70ab13e81cf5
util.cache: Change behaviour of on_evict (and tests). Now accepts false instead of a function (never evict), or on_evict can return false to prevent eviction.
Matthew Wild <mwild1@gmail.com>
parents:
7292
diff
changeset
|
56 |
local on_evict, evicted_key, evicted_value = self._on_evict, tail.key, tail.value; |
13178
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
57 |
|
13179
bbdaa770b955
util.cache: Pass cache itself to eviction callback
Kim Alvefur <zash@zash.se>
parents:
13178
diff
changeset
|
58 |
local do_evict = on_evict and on_evict(evicted_key, evicted_value, self); |
13178
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
59 |
|
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
60 |
if do_evict == false then |
7293
70ab13e81cf5
util.cache: Change behaviour of on_evict (and tests). Now accepts false instead of a function (never evict), or on_evict can return false to prevent eviction.
Matthew Wild <mwild1@gmail.com>
parents:
7292
diff
changeset
|
61 |
-- Cache is full, and we're not allowed to evict |
70ab13e81cf5
util.cache: Change behaviour of on_evict (and tests). Now accepts false instead of a function (never evict), or on_evict can return false to prevent eviction.
Matthew Wild <mwild1@gmail.com>
parents:
7292
diff
changeset
|
62 |
return false; |
13178
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
63 |
elseif self._count == self.size then |
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
64 |
-- Cache wasn't grown |
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
65 |
_remove(self, tail); |
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11202
diff
changeset
|
66 |
self._data[evicted_key] = nil; |
7293
70ab13e81cf5
util.cache: Change behaviour of on_evict (and tests). Now accepts false instead of a function (never evict), or on_evict can return false to prevent eviction.
Matthew Wild <mwild1@gmail.com>
parents:
7292
diff
changeset
|
67 |
end |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
|
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 |
m = { key = k, value = v, prev = nil, next = nil }; |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
71 |
self._data[k] = m; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 |
_insert(self, m); |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
73 |
return true; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 |
|
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 |
function cache_methods:get(k) |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
77 |
local m = self._data[k]; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
if m then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 |
return m.value; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 |
return nil; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 |
|
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 |
function cache_methods:items() |
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
85 |
local m = self._head; |
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 |
return function () |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 |
if not m then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 |
return; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 |
local k, v = m.key, m.value; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 |
m = m.next; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 |
return k, v; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 |
end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 |
|
7357
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
96 |
function cache_methods:values() |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
97 |
local m = self._head; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
98 |
return function () |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
99 |
if not m then |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
100 |
return; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
101 |
end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
102 |
local v = m.value; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
103 |
m = m.next; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
104 |
return v; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
105 |
end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
106 |
end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7293
diff
changeset
|
107 |
|
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
108 |
function cache_methods:count() |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
109 |
return self._count; |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
110 |
end |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
111 |
|
7292
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
112 |
function cache_methods:head() |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
113 |
local head = self._head; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
114 |
if not head then return nil, nil; end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
115 |
return head.key, head.value; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
116 |
end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
117 |
|
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
118 |
function cache_methods:tail() |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
119 |
local tail = self._tail; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
120 |
if not tail then return nil, nil; end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
121 |
return tail.key, tail.value; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
122 |
end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7019
diff
changeset
|
123 |
|
8400
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
124 |
function cache_methods:resize(new_size) |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
125 |
new_size = assert(tonumber(new_size), "cache size must be a number"); |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
126 |
new_size = math.floor(new_size); |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
127 |
assert(new_size > 0, "cache size must be greater than zero"); |
8401
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8400
diff
changeset
|
128 |
local on_evict = self._on_evict; |
8400
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
129 |
while self._count > new_size do |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
130 |
local tail = self._tail; |
8401
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8400
diff
changeset
|
131 |
local evicted_key, evicted_value = tail.key, tail.value; |
13179
bbdaa770b955
util.cache: Pass cache itself to eviction callback
Kim Alvefur <zash@zash.se>
parents:
13178
diff
changeset
|
132 |
if on_evict ~= nil and (on_evict == false or on_evict(evicted_key, evicted_value, self) == false) then |
8401
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8400
diff
changeset
|
133 |
-- Cache is full, and we're not allowed to evict |
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8400
diff
changeset
|
134 |
return false; |
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8400
diff
changeset
|
135 |
end |
8400
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
136 |
_remove(self, tail); |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
137 |
self._data[evicted_key] = nil; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
138 |
end |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
139 |
self.size = new_size; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
140 |
return true; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
141 |
end |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8399
diff
changeset
|
142 |
|
7438
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
143 |
function cache_methods:table() |
7705
9385c367e920
util.cache: Ignore unused argument [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7438
diff
changeset
|
144 |
--luacheck: ignore 212/t |
7438
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
145 |
if not self.proxy_table then |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
146 |
self.proxy_table = setmetatable({}, { |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
147 |
__index = function (t, k) |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
148 |
return self:get(k); |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
149 |
end; |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
150 |
__newindex = function (t, k, v) |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
151 |
if not self:set(k, v) then |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
152 |
error("failed to insert key into cache - full"); |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
153 |
end |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
154 |
end; |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
155 |
__pairs = function (t) |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
156 |
return self:items(); |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
157 |
end; |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
158 |
__len = function (t) |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
159 |
return self:count(); |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
160 |
end; |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
161 |
}); |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
162 |
end |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
163 |
return self.proxy_table; |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
164 |
end |
8603b16e85c7
util.cache: Add support for creating a proxy table to a cache, that looks and acts (mostly) like a normal table. No tests yet.
Matthew Wild <mwild1@gmail.com>
parents:
7357
diff
changeset
|
165 |
|
8399
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
166 |
function cache_methods:clear() |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
167 |
self._data = {}; |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
168 |
self._count = 0; |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
169 |
self._head = nil; |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
170 |
self._tail = nil; |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
171 |
end |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7705
diff
changeset
|
172 |
|
6948
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
173 |
local function new(size, on_evict) |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
174 |
size = assert(tonumber(size), "cache size must be a number"); |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
175 |
size = math.floor(size); |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
176 |
assert(size > 0, "cache size must be greater than zero"); |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
177 |
local data = {}; |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
178 |
return setmetatable({ _data = data, _count = 0, size = size, _head = nil, _tail = nil, _on_evict = on_evict }, cache_mt); |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
179 |
end |
d779c55058c6
util.cache: Small update to prefix private fields with an underscore, add a :count() method (same as util.queue) and add an optional on_evict callback
Matthew Wild <mwild1@gmail.com>
parents:
6946
diff
changeset
|
180 |
|
6936
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
181 |
return { |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
182 |
new = new; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
183 |
} |