2024-09-01 20:49:41 +00:00
|
|
|
local BinaryManager = CS.BinaryManager
|
2023-07-14 19:35:33 +00:00
|
|
|
local BinaryTable = {}
|
|
|
|
local tableEmpty = {}
|
|
|
|
|
|
|
|
local DefaultOfTypeNew = {
|
|
|
|
[1] = false,
|
|
|
|
[2] = nil,
|
|
|
|
[3] = fix.zero,
|
|
|
|
[4] = tableEmpty,
|
|
|
|
[5] = tableEmpty,
|
|
|
|
[6] = tableEmpty,
|
|
|
|
[7] = tableEmpty,
|
|
|
|
[8] = tableEmpty,
|
|
|
|
[9] = tableEmpty,
|
|
|
|
[10] = tableEmpty,
|
|
|
|
[11] = tableEmpty,
|
|
|
|
[12] = tableEmpty,
|
|
|
|
[13] = tableEmpty,
|
|
|
|
[14] = 0,
|
|
|
|
[15] = 0,
|
|
|
|
}
|
|
|
|
|
|
|
|
function BinaryTable.New(path)
|
|
|
|
local temp = {}
|
|
|
|
setmetatable(temp, { __index = BinaryTable })
|
|
|
|
temp:Ctor(path)
|
|
|
|
return temp
|
|
|
|
end
|
|
|
|
|
|
|
|
function BinaryTable:Ctor(path)
|
2024-09-01 20:49:41 +00:00
|
|
|
self.FilePath = path
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--读取全部
|
|
|
|
function BinaryTable.ReadAll(path, identifier)
|
2024-09-01 20:49:41 +00:00
|
|
|
local bt = BinaryTable.ReadHandle(path)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not bt then
|
|
|
|
return nil
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local tab = bt:ReadAllContent(identifier)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
bt:ReleaseFull()
|
|
|
|
bt = nil
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
return tab
|
|
|
|
end
|
|
|
|
|
|
|
|
--读取句柄
|
|
|
|
function BinaryTable.ReadHandle(path)
|
2024-09-01 20:49:41 +00:00
|
|
|
local bt = BinaryTable.New(path)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not bt or not bt:InitBinary() then
|
|
|
|
return nil
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
return bt
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:InitBinary()
|
|
|
|
self.Bytes = BinaryManager.LoadBytes(self.FilePath)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not self.Bytes then
|
|
|
|
XLog.Error(string.format("BinaryTable.InitBinary 加载文件失败 %s", self.FilePath))
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
self.Length = string.len(self.Bytes)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local result = self:Init()
|
|
|
|
return result
|
|
|
|
end
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:__ReadInt()
|
|
|
|
if self.Length < 4 then
|
|
|
|
XLog.Error(string.format("%s ReadInt Error, file might be empty", self.FilePath))
|
|
|
|
return 0
|
|
|
|
end
|
|
|
|
local b1, b2, b3, b4 = string.byte(self.Bytes, 1, 4)
|
|
|
|
return b1 | b2 << 8 | b3 << 16 | b4 << 24
|
|
|
|
end
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:__GetReader(len, offset)
|
|
|
|
offset = offset or 0
|
|
|
|
if offset + len > self.Length then
|
|
|
|
XLog.Error(string.format("%s GetReader out of range exception", self.FilePath))
|
|
|
|
return nil
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
2024-09-01 20:49:41 +00:00
|
|
|
local reader = ReaderPool.GetReader()
|
|
|
|
reader:LoadBytes(self.Bytes, len, offset + 1)
|
|
|
|
return reader
|
|
|
|
end
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:InitMetaTable()
|
|
|
|
local colType = self.colTypes
|
|
|
|
local colNames = self.colNames
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local colNameIndex = {}
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
for i = 1, #colNames do
|
|
|
|
local name = colNames[i]
|
|
|
|
colNameIndex[name] = i
|
|
|
|
end
|
|
|
|
|
|
|
|
local metaTable = {}
|
|
|
|
|
|
|
|
metaTable.__index = function(tbl, colName)
|
|
|
|
local idx = colNameIndex[colName]
|
|
|
|
|
|
|
|
if not idx or not tbl then
|
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
|
|
|
local result = rawget(tbl, idx)
|
|
|
|
|
|
|
|
if not result then
|
|
|
|
local resultType = colType[idx]
|
|
|
|
|
|
|
|
if not resultType then
|
|
|
|
XLog.Error(string.format("找不到键值 Key:%s 请检查该键值和表头是否匹配", colName))
|
|
|
|
end
|
|
|
|
|
|
|
|
result = DefaultOfTypeNew[resultType]
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
return result
|
|
|
|
end
|
|
|
|
|
|
|
|
metaTable.__newindex = function()
|
|
|
|
XLog.Error("attempt to update a readonly table")
|
|
|
|
end
|
|
|
|
|
|
|
|
metaTable.__metatable = "readonly table"
|
|
|
|
|
|
|
|
|
|
|
|
metaTable.__pairs = function(t)
|
|
|
|
local function stateless_iter(tbl, key)
|
|
|
|
local nk, v = next(tbl, key)
|
|
|
|
|
|
|
|
if nk and v then
|
|
|
|
local nv = t[v] or t[nk]
|
|
|
|
return nk, nv
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
return stateless_iter, colNameIndex, nil
|
|
|
|
end
|
|
|
|
|
|
|
|
self.MetaTable = metaTable
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
--初始化表头
|
2023-07-14 19:35:33 +00:00
|
|
|
function BinaryTable:Init()
|
2024-09-01 20:49:41 +00:00
|
|
|
local len = self:__ReadInt()
|
|
|
|
local reader = self:__GetReader(len, 4)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
self.col = reader:ReadInt()
|
|
|
|
self.infoTrunkLen = len
|
|
|
|
|
|
|
|
self.colTypes = {}
|
|
|
|
self.colNames = {}
|
|
|
|
for i = 1, self.col do
|
|
|
|
table.insert(self.colTypes, reader:ReadInt())
|
|
|
|
local name = reader:ReadString()
|
|
|
|
table.insert(self.colNames, name)
|
|
|
|
end
|
|
|
|
|
|
|
|
local hasPrimarykey = reader:ReadBool()
|
|
|
|
self.primarykeyCount = 0
|
|
|
|
|
|
|
|
if hasPrimarykey then
|
|
|
|
self.primarykeyCount = 1
|
|
|
|
self.primarykey = reader:ReadString()
|
|
|
|
self.primarykeyLen = reader:ReadInt()
|
|
|
|
end
|
|
|
|
|
|
|
|
for i = 1, #self.colNames do
|
|
|
|
local name = self.colNames[i]
|
|
|
|
if self.primarykey == name then
|
|
|
|
self.primarykeyType = self.colTypes[i]
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
self.rowTrunkLen = reader:ReadInt()
|
|
|
|
self.row = reader:ReadInt()
|
|
|
|
self.contentTrunkLen = reader:ReadInt()
|
|
|
|
|
|
|
|
if not self.contentTrunkLen then
|
|
|
|
if XMain.IsDebug then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Warning(string.format("BinaryTable:InitBinary,%s, 空表", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
2024-09-01 20:49:41 +00:00
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
self:InitMetaTable()
|
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
self.caches = {}
|
|
|
|
self.cachesCount = 0
|
|
|
|
|
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
--获取内容块
|
|
|
|
function BinaryTable:GetContentTrunkReader()
|
2024-09-01 20:49:41 +00:00
|
|
|
local position = self:GetContentTrunkPosition()
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
if position < 0 then
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local reader = self:__GetReader(self.contentTrunkLen, position)
|
2023-07-14 19:35:33 +00:00
|
|
|
return reader
|
|
|
|
end
|
|
|
|
|
|
|
|
--获取内容块位置
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:GetContentTrunkPosition()
|
2023-07-14 19:35:33 +00:00
|
|
|
local position = self.infoTrunkLen + 4
|
|
|
|
local count = self.primarykeyCount
|
|
|
|
|
|
|
|
if count > 0 then
|
|
|
|
position = position + self.primarykeyLen
|
|
|
|
end
|
|
|
|
|
|
|
|
position = position + self.rowTrunkLen
|
|
|
|
return position
|
|
|
|
end
|
|
|
|
|
|
|
|
function BinaryTable:ReadAllContent(identifier)
|
2024-09-01 20:49:41 +00:00
|
|
|
--if self.Bytes == nil then
|
|
|
|
-- XLog.Error("Re Open All")
|
|
|
|
-- self:InitBinary()
|
|
|
|
-- if self.Bytes == nil then
|
|
|
|
-- return tableEmpty
|
|
|
|
-- end
|
|
|
|
--end
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
local reader = self:GetContentTrunkReader()
|
|
|
|
|
|
|
|
if not reader then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Error(string.format("可能是空表 路径:%s 请检查", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
return tableEmpty
|
|
|
|
end
|
|
|
|
|
|
|
|
local row = self.row
|
|
|
|
local col = self.col
|
|
|
|
local colType = self.colTypes
|
|
|
|
local colNames = self.colNames
|
|
|
|
|
|
|
|
local index = 0
|
|
|
|
for i = 1, #colNames do
|
|
|
|
local name = colNames[i]
|
|
|
|
if name == identifier then
|
|
|
|
index = i
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
if index <= 0 then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Warning(string.format("找不到键值 Key:%s 请检查该键值和表头是否匹配", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
local tab = {}
|
|
|
|
for i = 1, row do
|
|
|
|
local temp = {}
|
|
|
|
local keyValue = nil
|
|
|
|
for j = 1, col do
|
|
|
|
local type = colType[j]
|
|
|
|
local value = reader:Read(type)
|
|
|
|
temp[j] = value
|
|
|
|
if index > 0 and j == index then
|
|
|
|
keyValue = value or 0
|
|
|
|
end
|
|
|
|
|
|
|
|
end
|
|
|
|
|
|
|
|
if index == 0 then
|
|
|
|
keyValue = i
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
setmetatable(temp, self.MetaTable)
|
2023-07-14 19:35:33 +00:00
|
|
|
tab[keyValue] = temp
|
|
|
|
|
|
|
|
self.caches[keyValue] = temp
|
|
|
|
end
|
|
|
|
|
|
|
|
self.cachesCount = self.row
|
2024-09-01 20:49:41 +00:00
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
return tab
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:__CloseReader(reader)
|
|
|
|
ReaderPool.ReleaseReader(reader)
|
|
|
|
end
|
|
|
|
|
|
|
|
function BinaryTable:GetRowCount()
|
2023-07-14 19:35:33 +00:00
|
|
|
return self.row
|
|
|
|
end
|
|
|
|
|
|
|
|
function BinaryTable:Get(key)
|
|
|
|
local v = self.caches[key]
|
|
|
|
if v then
|
|
|
|
return v
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
--if self.Bytes == nil then
|
|
|
|
-- XLog.Error("Re Open Get")
|
|
|
|
-- self:InitBinary()
|
|
|
|
-- if self.Bytes == nil then
|
|
|
|
-- return nil
|
|
|
|
-- end
|
|
|
|
--end
|
|
|
|
|
2023-07-14 19:35:33 +00:00
|
|
|
local t = self:ReadElement(key)
|
2024-09-01 20:49:41 +00:00
|
|
|
|
2023-07-14 19:35:33 +00:00
|
|
|
self.caches[key] = t
|
2024-09-01 20:49:41 +00:00
|
|
|
|
2023-07-14 19:35:33 +00:00
|
|
|
if t ~= nil then
|
|
|
|
self.cachesCount = self.cachesCount + 1
|
|
|
|
end
|
|
|
|
|
|
|
|
return t
|
|
|
|
end
|
|
|
|
|
|
|
|
--读取索引块
|
|
|
|
function BinaryTable:ReadIndexTrunk()
|
|
|
|
|
|
|
|
local len = self.primarykeyLen
|
|
|
|
local position = self.infoTrunkLen + 4
|
|
|
|
|
|
|
|
if len <= 0 or position < 0 then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Error(string.format("%s,读取索引块失败!! primarykey = %s", self.FilePath, self.primarykey))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
self.primaryKeyList = {}
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local reader = self:__GetReader(len, position)
|
2023-07-14 19:35:33 +00:00
|
|
|
for i = 1, self.row do
|
|
|
|
local temp = reader:Read(self.primarykeyType) or 0
|
2024-09-01 20:49:41 +00:00
|
|
|
self.primaryKeyList[temp] = i
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
return true
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
-- 读取每行的位置和长度
|
|
|
|
function BinaryTable:ReadRowInfoTrunk()
|
|
|
|
|
|
|
|
local len = self.rowTrunkLen
|
|
|
|
local position = self.infoTrunkLen + 4
|
|
|
|
|
|
|
|
if self.primarykeyCount > 0 then
|
|
|
|
position = position + self.primarykeyLen
|
|
|
|
end
|
|
|
|
|
|
|
|
if len <= 0 or position < 0 then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Error(string.format("%s,BinaryTable:ReadRowInfoTrunk 读取行位置块失败!", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
self.rowInfoStartArray = {}
|
|
|
|
self.rowInfoTailArray = {}
|
|
|
|
local reader = self:__GetReader(len, position)
|
|
|
|
for _ = 1, self.row do
|
|
|
|
table.insert(self.rowInfoStartArray, reader:ReadInt() or 0)
|
|
|
|
table.insert(self.rowInfoTailArray, reader:ReadInt() or 0)
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
2024-09-01 20:49:41 +00:00
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
--获取某一行信息
|
|
|
|
function BinaryTable:TryGetRowInfo(index)
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not self.rowInfoStartArray then
|
2023-07-14 19:35:33 +00:00
|
|
|
self:ReadRowInfoTrunk()
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not self.rowInfoStartArray or #self.rowInfoStartArray <= 0 then
|
|
|
|
XLog.Error(string.format("%s,BinaryTable:TryGetRowInfo 读取行位置数据失败", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if index > #self.rowInfoStartArray then
|
|
|
|
XLog.Error(string.format("%s,BinaryTable:TryGetRowInfo 超出总行数长度 : %s 查询长度 : %s", self.FilePath, #self.rowInfoStartArray, index))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
return self.rowInfoStartArray[index], self.rowInfoTailArray[index]
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
--读取条目
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:ReadElement(key)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
|
|
|
if not self.primarykey then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Error(string.format("%s,主键未初始化 ", self.FilePath))
|
2023-07-14 19:35:33 +00:00
|
|
|
return nil
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if not self.primaryKeyList then
|
2023-07-14 19:35:33 +00:00
|
|
|
self:ReadIndexTrunk()
|
|
|
|
end
|
|
|
|
|
|
|
|
local element = nil
|
2024-09-01 20:49:41 +00:00
|
|
|
local index = self.primaryKeyList[key]
|
2023-07-14 19:35:33 +00:00
|
|
|
if index then
|
2024-09-01 20:49:41 +00:00
|
|
|
local start, tail = self:TryGetRowInfo(index)
|
|
|
|
element = self:ReadElementInner(start, tail, index, key)
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
if not element then
|
|
|
|
-- XLog.Warning(string.format("%s,BinaryTable:ReadElement,查询失败,未找到条目 %s = %s", self.filePath, self.primarykey, value))
|
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
return element
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:ReadRow(start, tail, offset)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
if start < 0 or tail <= 0 then
|
|
|
|
XLog.Error(string.format("%s,BinaryTable:ReadRow,行数据异常 %s = %s", self.FilePath, start, tail))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local len = tail - start
|
|
|
|
local startIndex = offset + start
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local reader = self:__GetReader(len, startIndex)
|
2023-07-14 19:35:33 +00:00
|
|
|
return reader
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:ReadElementInner(start, tail, index, keyName)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
local position = self:GetContentTrunkPosition()
|
|
|
|
local reader = self:ReadRow(start, tail, position)
|
2023-07-14 19:35:33 +00:00
|
|
|
if not reader then
|
2024-09-01 20:49:41 +00:00
|
|
|
XLog.Warning(string.format("%s,BinaryTable:ReadElementInner,查询数据失败 %s = %s", self.FilePath, self.primarykey, keyName))
|
2023-07-14 19:35:33 +00:00
|
|
|
return
|
|
|
|
end
|
|
|
|
|
|
|
|
local colType = self.colTypes
|
|
|
|
|
|
|
|
local temp = {}
|
|
|
|
|
|
|
|
for j = 1, self.col do
|
|
|
|
local type = colType[j]
|
|
|
|
local value = reader:Read(type)
|
|
|
|
temp[j] = value
|
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
setmetatable(temp, self.MetaTable)
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
self:__CloseReader(reader)
|
2023-07-14 19:35:33 +00:00
|
|
|
return temp
|
|
|
|
end
|
|
|
|
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:ReleaseCache()
|
|
|
|
self.caches = {}
|
|
|
|
self.cachesCount = 0
|
|
|
|
end
|
2023-07-14 19:35:33 +00:00
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
function BinaryTable:ReleaseFull()
|
2023-07-14 19:35:33 +00:00
|
|
|
self.caches = {}
|
2024-09-01 20:49:41 +00:00
|
|
|
self.Bytes = nil
|
2023-07-14 19:35:33 +00:00
|
|
|
self.cachesCount = 0
|
|
|
|
end
|
|
|
|
|
|
|
|
|
|
|
|
function BinaryTable:Close()
|
2024-09-01 20:49:41 +00:00
|
|
|
|
2023-07-14 19:35:33 +00:00
|
|
|
end
|
|
|
|
|
2024-09-01 20:49:41 +00:00
|
|
|
return BinaryTable
|