Comparison

util/dbuffer.lua @ 11189:0ff148362a3d 0.11

util.dbuffer: Optimize :sub() and :byte()
author Matthew Wild <mwild1@gmail.com>
date Wed, 28 Oct 2020 14:21:09 +0000
parent 11156:a8ef69f7fc35
child 11190:88ce53df44a9
comparison
equal deleted inserted replaced
11177:37dc2a6144d1 11189:0ff148362a3d
1 local queue = require "util.queue"; 1 local queue = require "util.queue";
2 2
3 local s_byte, s_sub = string.byte, string.sub;
3 local dbuffer_methods = {}; 4 local dbuffer_methods = {};
4 local dynamic_buffer_mt = { __index = dbuffer_methods }; 5 local dynamic_buffer_mt = { __index = dbuffer_methods };
5 6
6 function dbuffer_methods:write(data) 7 function dbuffer_methods:write(data)
7 if self.max_size and #data + self._length > self.max_size then 8 if self.max_size and #data + self._length > self.max_size then
99 end 100 end
100 end 101 end
101 return true; 102 return true;
102 end 103 end
103 104
104 function dbuffer_methods:sub(i, j) 105 -- Normalize i, j into absolute offsets within the
106 -- front chunk (accounting for front_consumed), and
107 -- ensure there is enough data in the first chunk
108 -- to cover any subsequent :sub() or :byte() operation
109 function dbuffer_methods:_prep_sub(i, j)
105 if j == nil then 110 if j == nil then
106 j = -1; 111 j = -1;
107 end 112 end
108 if j < 0 then 113 if j < 0 then
109 j = self._length + (j+1); 114 j = self._length + (j+1);
116 end 121 end
117 if j > self._length then 122 if j > self._length then
118 j = self._length; 123 j = self._length;
119 end 124 end
120 if i > j then 125 if i > j then
121 return ""; 126 return nil;
122 end 127 end
123 128
124 self:collapse(j); 129 self:collapse(j);
125 130
126 return self.items:peek():sub(self.front_consumed+1):sub(i, j); 131 if self.front_consumed > 0 then
132 i = i + self.front_consumed;
133 j = j + self.front_consumed;
134 end
135
136 return i, j;
137 end
138
139 function dbuffer_methods:sub(i, j)
140 i, j = self:_prep_sub(i, j);
141 if not i then
142 return "";
143 end
144 return s_sub(self.items:peek(), i, j);
127 end 145 end
128 146
129 function dbuffer_methods:byte(i, j) 147 function dbuffer_methods:byte(i, j)
130 i = i or 1; 148 i = i or 1;
131 j = j or i; 149 j = j or i;
132 return string.byte(self:sub(i, j), 1, -1); 150 i, j = self:_prep_sub(i, j);
151 if not i then
152 return;
153 end
154 return s_byte(self.items:peek(), i, j);
133 end 155 end
134 156
135 function dbuffer_methods:length() 157 function dbuffer_methods:length()
136 return self._length; 158 return self._length;
137 end 159 end