Software /
code /
prosody
Annotate
util/dbuffer.lua @ 10973:39991e40d1dc
util.dbuffer: dynamic string buffer
Similar to util.ringbuffer (and shares almost identical API). Differences:
- size limit is optional and dynamic
- does not allocate a fixed buffer of max_size bytes
- focus on simply storing references to existing string objects where possible,
avoiding unnecessary allocations
- references are still stored in a ring buffer to enable use as a fast FIFO
Optional second parameter to new() provides the number of ring buffer segments. On
Lua 5.2 on my laptop, a segment is ~19 bytes. If the ring buffer fills up, the next
write will compact all strings into a single item.
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Fri, 26 Jun 2020 16:41:31 +0100 |
child | 10980:eaee72c7afbd |
rev | line source |
---|---|
10973
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
1 local queue = require "util.queue"; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
2 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
3 local dbuffer_methods = {}; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
4 local dynamic_buffer_mt = { __index = dbuffer_methods }; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
5 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
6 function dbuffer_methods:write(data) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
7 if self.max_size and #data + self._length > self.max_size then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
8 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
9 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
10 local ok = self.items:push(data); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
11 if not ok then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
12 self:collapse(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
13 ok = self.items:push(data); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
14 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
15 if not ok then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
16 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
17 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
18 self._length = self._length + #data; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
19 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
20 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
21 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
22 function dbuffer_methods:read_chunk(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
23 local chunk, consumed = self.items:peek(), self.front_consumed; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
24 if not chunk then return; end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
25 local chunk_length = #chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
26 local remaining_chunk_length = chunk_length - consumed; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
27 if remaining_chunk_length <= requested_bytes then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
28 self.front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
29 self._length = self._length - remaining_chunk_length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
30 self.items:pop(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
31 assert(#chunk:sub(consumed + 1, -1) == remaining_chunk_length); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
32 return chunk:sub(consumed + 1, -1), remaining_chunk_length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
33 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
34 local end_pos = consumed + requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
35 self.front_consumed = end_pos; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
36 self._length = self._length - requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
37 assert(#chunk:sub(consumed + 1, end_pos) == requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
38 return chunk:sub(consumed + 1, end_pos), requested_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
39 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
40 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
41 function dbuffer_methods:read(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
42 local chunks; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
43 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
44 if requested_bytes > self._length then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
45 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
46 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
47 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
48 local chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
49 if chunk then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
50 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
51 if requested_bytes == 0 then -- Already read everything we need |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
52 return chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
53 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
54 chunks = {}; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
55 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
56 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
57 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
58 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
59 -- Need to keep reading more chunks |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
60 while chunk do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
61 table.insert(chunks, chunk); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
62 if requested_bytes > 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
63 chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
64 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
65 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
66 break; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
67 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
68 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
69 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
70 return table.concat(chunks); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
71 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
72 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
73 function dbuffer_methods:discard(requested_bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
74 if requested_bytes > self._length then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
75 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
76 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
77 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
78 local chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
79 if chunk then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
80 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
81 if requested_bytes == 0 then -- Already read everything we need |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
82 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
83 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
84 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
85 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
86 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
87 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
88 while chunk do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
89 if requested_bytes > 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
90 chunk, read_bytes = self:read_chunk(requested_bytes); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
91 requested_bytes = requested_bytes - read_bytes; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
92 else |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
93 break; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
94 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
95 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
96 return true; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
97 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
98 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
99 function dbuffer_methods:sub(i, j) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
100 if j == nil then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
101 j = -1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
102 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
103 if j < 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
104 j = self._length + (j+1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
105 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
106 if i < 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
107 i = self._length + (i+1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
108 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
109 if i < 1 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
110 i = 1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
111 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
112 if j > self._length then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
113 j = self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
114 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
115 if i > j then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
116 return ""; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
117 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
118 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
119 self:collapse(j); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
120 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
121 return self.items:peek():sub(i, j); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
122 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
123 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
124 function dbuffer_methods:byte(i, j) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
125 i = i or 1; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
126 j = j or i; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
127 return string.byte(self:sub(i, j), 1, -1); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
128 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
129 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
130 function dbuffer_methods:length() |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
131 return self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
132 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
133 dynamic_buffer_mt.__len = dbuffer_methods.length; -- support # operator |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
134 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
135 function dbuffer_methods:collapse(bytes) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
136 bytes = bytes or self._length; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
137 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
138 local front_chunk = self.items:peek(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
139 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
140 if #front_chunk - self.front_consumed >= bytes then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
141 return; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
142 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
143 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
144 local front_chunks = { front_chunk:sub(self.front_consumed+1) }; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
145 local front_bytes = #front_chunks[1]; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
146 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
147 while front_bytes < bytes do |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
148 self.items:pop(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
149 local chunk = self.items:peek(); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
150 front_bytes = front_bytes + #chunk; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
151 table.insert(front_chunks, chunk); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
152 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
153 self.items:replace(table.concat(front_chunks)); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
154 self.front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
155 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
156 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
157 local function new(max_size, max_chunks) |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
158 if max_size and max_size <= 0 then |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
159 return nil; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
160 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
161 return setmetatable({ |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
162 front_consumed = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
163 _length = 0; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
164 max_size = max_size; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
165 items = queue.new(max_chunks or 32); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
166 }, dynamic_buffer_mt); |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
167 end |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
168 |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
169 return { |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
170 new = new; |
39991e40d1dc
util.dbuffer: dynamic string buffer
Matthew Wild <mwild1@gmail.com>
parents:
diff
changeset
|
171 }; |