Software / code / prosody
Annotate
util/cache.lua @ 13801:a5d5fefb8b68 13.0
mod_tls: Enable Prosody's certificate checking for incoming s2s connections (fixes #1916) (thanks Damian, Zash)
Various options in Prosody allow control over the behaviour of the certificate
verification process For example, some deployments choose to allow falling
back to traditional "dialback" authentication (XEP-0220), while others verify
via DANE, hard-coded fingerprints, or other custom plugins.
Implementing this flexibility requires us to override OpenSSL's default
certificate verification, to allow Prosody to verify the certificate itself,
apply custom policies and make decisions based on the outcome.
To enable our custom logic, we have to suppress OpenSSL's default behaviour of
aborting the connection with a TLS alert message. With LuaSec, this can be
achieved by using the verifyext "lsec_continue" flag.
We also need to use the lsec_ignore_purpose flag, because XMPP s2s uses server
certificates as "client" certificates (for mutual TLS verification in outgoing
s2s connections).
Commit 99d2100d2918 moved these settings out of the defaults and into mod_s2s,
because we only really need these changes for s2s, and they should be opt-in,
rather than automatically applied to all TLS services we offer.
That commit was incomplete, because it only added the flags for incoming
direct TLS connections. StartTLS connections are handled by mod_tls, which was
not applying the lsec_* flags. It previously worked because they were already
in the defaults.
This resulted in incoming s2s connections with "invalid" certificates being
aborted early by OpenSSL, even if settings such as `s2s_secure_auth = false`
or DANE were present in the config.
Outgoing s2s connections inherit verify "none" from the defaults, which means
OpenSSL will receive the cert but will not terminate the connection when it is
deemed invalid. This means we don't need lsec_continue there, and we also
don't need lsec_ignore_purpose (because the remote peer is a "server").
Wondering why we can't just use verify "none" for incoming s2s? It's because
in that mode, OpenSSL won't request a certificate from the peer for incoming
connections. Setting verify "peer" is how you ask OpenSSL to request a
certificate from the client, but also what triggers its built-in verification.
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Tue, 01 Apr 2025 17:26:56 +0100 |
| 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 } |