Comparison

util/smqueue.lua @ 12055:daced16154fa

util.smqueue: Abstract queue with acknowledgements and overflow Meant to be used in mod_smacks for XEP-0198 Meant to have a larger virtual size than actual number of items stored, on the theory that in most cases, the excess will be acked before needed for a resumption event.
author Kim Alvefur <zash@zash.se>
date Tue, 14 Dec 2021 19:58:53 +0100
child 12058:4860da718e87
comparison
equal deleted inserted replaced
12054:0116fa57f05c 12055:daced16154fa
1 local queue = require("util.queue");
2
3 local lib = { smqueue = {} }
4
5 local smqueue = lib.smqueue;
6
7 function smqueue:push(v)
8 self._head = self._head + 1;
9
10 assert(self._queue:push(v));
11 end
12
13 function smqueue:ack(h)
14 if h < self._tail then
15 return nil, "tail"
16 elseif h > self._head then
17 return nil, "head"
18 end
19
20 local acked = {};
21 self._tail = h;
22 local expect = self._head - self._tail;
23 while expect < self._queue:count() do
24 local v = self._queue:pop();
25 if not v then return nil, "pop" end
26 table.insert(acked, v);
27 end
28 return acked
29 end
30
31 function smqueue:count_unacked() return self._head - self._tail end
32
33 function smqueue:count_acked() return self._tail end
34
35 function smqueue:resumable() return self._queue:count() >= (self._head - self._tail) end
36
37 function smqueue:resume() return self._queue:items() end
38
39 function smqueue:consume() return self._queue:consume() end
40
41 local compat_mt = {}
42
43 function compat_mt:__index(i)
44 if i < self._queue._tail then return nil end
45 return self._queue._queue._items[(i + self._queue._tail) % self._queue._queue.size]
46 end
47
48 function compat_mt:__len() return self._queue:count_unacked() end
49
50 function smqueue:table() return setmetatable({ _queue = self }, compat_mt) end
51
52 local function freeze(q) return { head = q._head; tail = q._tail } end
53
54 local queue_mt = { __name = "smqueue"; __index = smqueue; __len = smqueue.count_unacked; __freeze = freeze }
55
56 function lib.new(size)
57 assert(size > 0);
58 return setmetatable({ _head = 0; _tail = 0; _queue = queue.new(size, true) }, queue_mt)
59 end
60
61 return lib