Mercurial > prosody-hg
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 |
| parents | a8ef69f7fc35 |
| children | 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 |
