util/queue.lua

Thu, 07 Apr 2022 18:11:33 +0100

author
Matthew Wild <mwild1@gmail.com>
date
Thu, 07 Apr 2022 18:11:33 +0100
changeset 0
89e39cd5a7cd
permissions
-rw-r--r--

Initial commit

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

mercurial