mirror of
https://github.com/MihailRis/voxelcore.git
synced 2026-10-13 15:01:49 +00:00
improved bytearray
This commit is contained in:
parent
77e1e29eb9
commit
27bb3015e4
1 changed files with 70 additions and 32 deletions
|
|
@ -4,6 +4,7 @@ local FFI = ffi
|
||||||
|
|
||||||
FFI.cdef[[
|
FFI.cdef[[
|
||||||
void* malloc(size_t);
|
void* malloc(size_t);
|
||||||
|
void *realloc(void *, size_t);
|
||||||
void free(void*);
|
void free(void*);
|
||||||
typedef struct {
|
typedef struct {
|
||||||
unsigned char* bytes;
|
unsigned char* bytes;
|
||||||
|
|
@ -22,12 +23,33 @@ local GC_THRESHOLD = 50 * 1024 * 1024
|
||||||
|
|
||||||
local function malloc(size)
|
local function malloc(size)
|
||||||
local raw = FFI.C.malloc(size)
|
local raw = FFI.C.malloc(size)
|
||||||
if raw == nil then
|
if not raw then
|
||||||
return nil
|
error("failed memory allocation of " .. size .. " bytes")
|
||||||
end
|
end
|
||||||
|
|
||||||
allocated_bytes = allocated_bytes + size
|
allocated_bytes = allocated_bytes + size
|
||||||
|
if allocated_bytes >= GC_THRESHOLD then
|
||||||
|
collectgarbage("step", 200)
|
||||||
|
allocated_bytes = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
return raw
|
||||||
|
end
|
||||||
|
|
||||||
|
local function realloc(buff, size, throwerror)
|
||||||
|
if throwerror == nil then throwerror = true end
|
||||||
|
|
||||||
|
if size <= 0 then
|
||||||
|
free(buff)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
|
||||||
|
local raw = FFI.C.realloc(buff, size)
|
||||||
|
if not raw and throwerror then
|
||||||
|
error("failed memory reallocation of block " .. buff .. " to new size " .. size)
|
||||||
|
end
|
||||||
|
|
||||||
|
allocated_bytes = allocated_bytes + size
|
||||||
if allocated_bytes >= GC_THRESHOLD then
|
if allocated_bytes >= GC_THRESHOLD then
|
||||||
collectgarbage("step", 200)
|
collectgarbage("step", 200)
|
||||||
allocated_bytes = 0
|
allocated_bytes = 0
|
||||||
|
|
@ -38,23 +60,17 @@ end
|
||||||
|
|
||||||
local function grow_buffer(self, elems)
|
local function grow_buffer(self, elems)
|
||||||
local new_capacity = math.ceil(self.capacity / 0.75 + elems)
|
local new_capacity = math.ceil(self.capacity / 0.75 + elems)
|
||||||
local prev = self.bytes
|
self.bytes = realloc(self.bytes, new_capacity)
|
||||||
self.bytes = malloc(new_capacity)
|
|
||||||
FFI.copy(self.bytes, prev, self.size)
|
|
||||||
self.capacity = new_capacity
|
self.capacity = new_capacity
|
||||||
free(prev)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function trim_buffer(self)
|
local function trim_buffer(self)
|
||||||
if self.size == self.capacity then
|
if self.size == self.capacity then return end
|
||||||
return
|
local new_bytes = realloc(self.bytes, self.size, false)
|
||||||
|
if new_bytes then
|
||||||
|
self.bytes = new_bytes
|
||||||
|
self.capacity = self.size
|
||||||
end
|
end
|
||||||
local size = self.size
|
|
||||||
local prev = self.bytes
|
|
||||||
self.bytes = malloc(size)
|
|
||||||
FFI.copy(self.bytes, prev, self.size)
|
|
||||||
self.capacity = size
|
|
||||||
free(prev)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function count_elements(b)
|
local function count_elements(b)
|
||||||
|
|
@ -125,15 +141,16 @@ local function clear(self)
|
||||||
self.size = 0
|
self.size = 0
|
||||||
end
|
end
|
||||||
|
|
||||||
local function reserve(self, new_capacity)
|
local function fill(self, byte)
|
||||||
if new_capacity <= self.capacity then
|
if self.size > 0 then
|
||||||
return
|
FFI.fill(self.bytes, self.size, byte)
|
||||||
end
|
end
|
||||||
local prev = self.bytes
|
end
|
||||||
self.bytes = malloc(new_capacity)
|
|
||||||
FFI.copy(self.bytes, prev, self.size)
|
local function reserve(self, new_capacity)
|
||||||
|
if new_capacity <= self.capacity then return end
|
||||||
|
self.bytes = realloc(self.bytes, new_capacity)
|
||||||
self.capacity = new_capacity
|
self.capacity = new_capacity
|
||||||
free(prev)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
local function get_capacity(self)
|
local function get_capacity(self)
|
||||||
|
|
@ -150,22 +167,43 @@ local function slice(self, offset, length)
|
||||||
length = self.size - offset + 1
|
length = self.size - offset + 1
|
||||||
end
|
end
|
||||||
local buffer = malloc(length)
|
local buffer = malloc(length)
|
||||||
if not buffer then
|
|
||||||
error("malloc(" .. length .. ") returned NULL")
|
|
||||||
end
|
|
||||||
FFI.copy(buffer, self.bytes + (offset - 1), length)
|
FFI.copy(buffer, self.bytes + (offset - 1), length)
|
||||||
return bytearray_type(buffer, length, length)
|
return bytearray_type(buffer, length, length)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
local function copy(self, srcindex, dst, dstindex, size)
|
||||||
|
if srcindex > 0 and dstindex > 0 and size > 0 and
|
||||||
|
srcindex + size - 1 <= self.size and
|
||||||
|
dstindex + size - 1 <= dst.size
|
||||||
|
then
|
||||||
|
FFI.copy(dst.bytes + dstindex - 1, self.bytes + srcindex - 1, size)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
local function move(self, fromindex, toindex, size)
|
||||||
|
if fromindex > 0 and toindex > 0 and size > 0 and
|
||||||
|
fromindex + size - 1 <= self.size and
|
||||||
|
toindex + size - 1 <= self.size
|
||||||
|
then
|
||||||
|
local buff = malloc(size)
|
||||||
|
FFI.copy(buff, self.bytes + fromindex - 1, size)
|
||||||
|
FFI.copy(self.bytes + toindex - 1, buff, size)
|
||||||
|
free(buff)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
local bytearray_methods = {
|
local bytearray_methods = {
|
||||||
append=append,
|
append = append,
|
||||||
insert=insert,
|
insert = insert,
|
||||||
remove=remove,
|
remove = remove,
|
||||||
trim=trim_buffer,
|
trim = trim_buffer,
|
||||||
clear=clear,
|
clear = clear,
|
||||||
reserve=reserve,
|
reserve = reserve,
|
||||||
get_capacity=get_capacity,
|
get_capacity = get_capacity,
|
||||||
slice=slice,
|
slice = slice,
|
||||||
|
fill = fill,
|
||||||
|
copy = copy,
|
||||||
|
move = move
|
||||||
}
|
}
|
||||||
|
|
||||||
local bytearray_mt = {
|
local bytearray_mt = {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue