util/queue.lua

changeset 0
89e39cd5a7cd
equal deleted inserted replaced
-1:000000000000 0:89e39cd5a7cd
1 -- Prosody IM
2 -- Copyright (C) 2008-2015 Matthew Wild
3 -- Copyright (C) 2008-2015 Waqas Hussain
4 --
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 -- Small ringbuffer library (i.e. an efficient FIFO queue with a size limit)
10 -- (because unbounded dynamically-growing queues are a bad thing...)
11
12 local have_utable, utable = pcall(require, "util.table"); -- For pre-allocation of table
13
14 local function new(size, allow_wrapping)
15 -- Head is next insert, tail is next read
16 local head, tail = 1, 1;
17 local items = 0; -- Number of stored items
18 local t = have_utable and utable.create(size, 0) or {}; -- Table to hold items
19 --luacheck: ignore 212/self
20 return {
21 _items = t;
22 size = size;
23 count = function (self) return items; end;
24 push = function (self, item)
25 if items >= size then
26 if allow_wrapping then
27 tail = (tail%size)+1; -- Advance to next oldest item
28 items = items - 1;
29 else
30 return nil, "queue full";
31 end
32 end
33 t[head] = item;
34 items = items + 1;
35 head = (head%size)+1;
36 return true;
37 end;
38 pop = function (self)
39 if items == 0 then
40 return nil;
41 end
42 local item;
43 item, t[tail] = t[tail], 0;
44 tail = (tail%size)+1;
45 items = items - 1;
46 return item;
47 end;
48 peek = function (self)
49 if items == 0 then
50 return nil;
51 end
52 return t[tail];
53 end;
54 replace = function (self, data)
55 if items == 0 then
56 return self:push(data);
57 end
58 t[tail] = data;
59 return true;
60 end;
61 items = function (self)
62 return function (_, pos)
63 if pos >= items then
64 return nil;
65 end
66 local read_pos = tail + pos;
67 if read_pos > self.size then
68 read_pos = (read_pos%size);
69 end
70 return pos+1, t[read_pos];
71 end, self, 0;
72 end;
73 consume = function (self)
74 return self.pop, self;
75 end;
76 };
77 end
78
79 return {
80 new = new;
81 };
82

mercurial