Software /
code /
prosody
Annotate
util/cache.lua @ 6943:0a31ec3193f0
util.cache: Make sure cache size is specified as an integer
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Wed, 25 Nov 2015 20:49:41 +0100 |
parent | 6933:d636815d81c3 |
child | 6945:d779c55058c6 |
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 local cache_methods = {}; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 local cache_mt = { __index = cache_methods }; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local function new(size) |
6943
0a31ec3193f0
util.cache: Make sure cache size is specified as an integer
Kim Alvefur <zash@zash.se>
parents:
6933
diff
changeset
|
5 size = assert(tonumber(size), "cache size must be a number"); |
0a31ec3193f0
util.cache: Make sure cache size is specified as an integer
Kim Alvefur <zash@zash.se>
parents:
6933
diff
changeset
|
6 size = math.floor(size); |
6933
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 assert(size > 0, "cache size must be greater than zero"); |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 local data = {}; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 return setmetatable({ data = data, count = 0, size = size, head = nil, tail = nil }, cache_mt); |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 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
|
13 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
|
14 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
|
15 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 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
|
17 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
|
18 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 if list.tail == m then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 list.tail = m.prev; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 if list.head == m then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 list.head = m.next; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 list.count = list.count - 1; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 local function _insert(list, m) |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 if list.head then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 list.head.prev = m; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 m.prev, m.next = nil, list.head; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 list.head = m; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 if not list.tail then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 list.tail = m; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 list.count = list.count + 1; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 function cache_methods:set(k, v) |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 local m = self.data[k]; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 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
|
43 -- 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
|
44 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
|
45 -- 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
|
46 _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
|
47 _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
|
48 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
|
49 else |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 -- 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
|
51 _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
|
52 self.data[k] = nil; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 return; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 -- New key |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 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
|
58 return; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 -- Check whether we need to remove oldest k/v |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 if self.count == self.size then |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 self.data[self.tail.key] = nil; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 _remove(self, self.tail); |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 m = { key = k, value = v, prev = nil, next = nil }; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 self.data[k] = m; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 _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
|
69 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 function cache_methods:get(k) |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 local m = self.data[k]; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 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
|
74 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
|
75 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 return nil; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 function cache_methods:items() |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 local m = self.head; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 return function () |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 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
|
83 return; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 end |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 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
|
86 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
|
87 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
|
88 end |
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 |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 return { |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 new = new; |
d636815d81c3
util.cache: Ordered key->value data structure, with size limit (same as pubsub)
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 } |