Software /
code /
prosody
Annotate
util/cache.lua @ 13248:db433ed3135c
Merge 0.12->trunk
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 25 Jul 2023 12:35:11 +0200 |
parent | 13175:bbdaa770b955 |
rev | line source |
---|---|
6933
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 |
6945
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:
6943
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:
6943
diff
changeset
|
10 list._tail = m.prev; |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 end |
6945
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:
6943
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:
6943
diff
changeset
|
13 list._head = m.next; |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 end |
6945
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:
6943
diff
changeset
|
15 list._count = list._count - 1; |
6933
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) |
6945
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:
6943
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:
6943
diff
changeset
|
20 list._head.prev = m; |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 end |
6945
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:
6943
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:
6943
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:
6943
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:
6943
diff
changeset
|
25 list._tail = m; |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 end |
6945
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:
6943
diff
changeset
|
27 list._count = list._count + 1; |
6933
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 |
6945
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:
6943
diff
changeset
|
30 local cache_methods = {}; |
11198
c4c06fbb7d87
util.cache: Add __name to metatable
Matthew Wild <mwild1@gmail.com>
parents:
8398
diff
changeset
|
31 local cache_mt = { __name = "cache", __index = cache_methods }; |
6945
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:
6943
diff
changeset
|
32 |
6933
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) |
6945
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:
6943
diff
changeset
|
34 local m = self._data[k]; |
6933
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); |
6945
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:
6943
diff
changeset
|
45 self._data[k] = nil; |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 end |
6945
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:
6943
diff
changeset
|
47 return true; |
6933
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 |
6945
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:
6943
diff
changeset
|
51 return true; |
6933
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 |
6945
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:
6943
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:
6943
diff
changeset
|
55 local tail = self._tail; |
7290
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:
7289
diff
changeset
|
56 local on_evict, evicted_key, evicted_value = self._on_evict, tail.key, tail.value; |
13174
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11198
diff
changeset
|
57 |
13175
bbdaa770b955
util.cache: Pass cache itself to eviction callback
Kim Alvefur <zash@zash.se>
parents:
13174
diff
changeset
|
58 local do_evict = on_evict and on_evict(evicted_key, evicted_value, self); |
13174
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11198
diff
changeset
|
59 |
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11198
diff
changeset
|
60 if do_evict == false then |
7290
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:
7289
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:
7289
diff
changeset
|
62 return false; |
13174
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11198
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:
11198
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:
11198
diff
changeset
|
65 _remove(self, tail); |
8ec7b7d6556f
util.cache: Keep eviction candidate if callback resized to make room
Kim Alvefur <zash@zash.se>
parents:
11198
diff
changeset
|
66 self._data[evicted_key] = nil; |
7290
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:
7289
diff
changeset
|
67 end |
6933
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 }; |
6945
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:
6943
diff
changeset
|
71 self._data[k] = m; |
6933
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); |
6945
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:
6943
diff
changeset
|
73 return true; |
6933
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) |
6945
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:
6943
diff
changeset
|
77 local m = self._data[k]; |
6933
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() |
6945
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:
6943
diff
changeset
|
85 local m = self._head; |
6933
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 |
7354
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
96 function cache_methods:values() |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
97 local m = self._head; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
98 return function () |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
99 if not m then |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
100 return; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
101 end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
102 local v = m.value; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
103 m = m.next; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
104 return v; |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
105 end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
106 end |
8ca7f1c2c660
util.cache: Add method for iterating over values
Kim Alvefur <zash@zash.se>
parents:
7290
diff
changeset
|
107 |
6945
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:
6943
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:
6943
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:
6943
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:
6943
diff
changeset
|
111 |
7289
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
112 function cache_methods:head() |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
113 local head = self._head; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
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:
7016
diff
changeset
|
115 return head.key, head.value; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
116 end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
117 |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
118 function cache_methods:tail() |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
119 local tail = self._tail; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
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:
7016
diff
changeset
|
121 return tail.key, tail.value; |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
122 end |
42e7545d5ae3
util.cache: Add head() and tail() methods (and tests)
Matthew Wild <mwild1@gmail.com>
parents:
7016
diff
changeset
|
123 |
8397
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
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:
8396
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:
8396
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:
8396
diff
changeset
|
127 assert(new_size > 0, "cache size must be greater than zero"); |
8398
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8397
diff
changeset
|
128 local on_evict = self._on_evict; |
8397
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
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:
8396
diff
changeset
|
130 local tail = self._tail; |
8398
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8397
diff
changeset
|
131 local evicted_key, evicted_value = tail.key, tail.value; |
13175
bbdaa770b955
util.cache: Pass cache itself to eviction callback
Kim Alvefur <zash@zash.se>
parents:
13174
diff
changeset
|
132 if on_evict ~= nil and (on_evict == false or on_evict(evicted_key, evicted_value, self) == false) then |
8398
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8397
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:
8397
diff
changeset
|
134 return false; |
3eff1b60269a
util.cache: Call on-eviction callback when shrinking
Kim Alvefur <zash@zash.se>
parents:
8397
diff
changeset
|
135 end |
8397
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
136 _remove(self, tail); |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
137 self._data[evicted_key] = nil; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
138 end |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
139 self.size = new_size; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
140 return true; |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
141 end |
99d85731e3ee
util.cache: Add a method to resize the cache
Kim Alvefur <zash@zash.se>
parents:
8396
diff
changeset
|
142 |
7435
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:
7354
diff
changeset
|
143 function cache_methods:table() |
7702
9385c367e920
util.cache: Ignore unused argument [luacheck]
Kim Alvefur <zash@zash.se>
parents:
7435
diff
changeset
|
144 --luacheck: ignore 212/t |
7435
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
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:
7354
diff
changeset
|
165 |
8396
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7702
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:
7702
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:
7702
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:
7702
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:
7702
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:
7702
diff
changeset
|
171 end |
fbe1f99fb245
util.cache: Add method for removing all data (does not call eviction callback)
Kim Alvefur <zash@zash.se>
parents:
7702
diff
changeset
|
172 |
6945
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:
6943
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:
6943
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:
6943
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:
6943
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:
6943
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:
6943
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:
6943
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:
6943
diff
changeset
|
180 |
6933
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 } |