Software /
code /
prosody
Annotate
util/cache.lua @ 13238:26327eac56dc
util.datamanager: Always reset index after list shift
Shifting the index does not work reliably yet, better to rebuild it from
scratch. Since there is minimal parsing involved in that, it should be
more efficient anyway.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 22 Jul 2023 14:02:01 +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 } |