174 lines
3.5 KiB
Plaintext
174 lines
3.5 KiB
Plaintext
local ArrayPushBack = TableUtility.ArrayPushBack
|
|
local ArrayPopBack = TableUtility.ArrayPopBack
|
|
local ArrayFindIndex = TableUtility.ArrayFindIndex
|
|
local ArrayRemove = TableUtility.ArrayRemove
|
|
local tableRemove = table.remove
|
|
local CreateArray = ReusableTable.CreateArray
|
|
local DestroyAndClearArray = ReusableTable.DestroyAndClearArray
|
|
|
|
LuaLRUKeyTable = class("LuaLRUKeyTable")
|
|
-- self.args = {
|
|
-- [1] = key_limit
|
|
-- [2] = container_limit
|
|
-- [3] = key time line
|
|
-- [4] = elements
|
|
-- }
|
|
local FAST_MODE = GAME_FAST_MODE
|
|
function LuaLRUKeyTable:ctor(key_limit,container_limit)
|
|
self[1] = key_limit
|
|
self[2] = container_limit
|
|
self[3] = {}
|
|
self[4] = {}
|
|
end
|
|
|
|
local function MoveElementToLast(array,element)
|
|
local count = #array
|
|
if(array[count] == element) then
|
|
return
|
|
end
|
|
for i = count-1,1,-1 do
|
|
if(array[i] == element) then
|
|
tableRemove(array, i)
|
|
array[count] = element
|
|
return
|
|
end
|
|
end
|
|
end
|
|
|
|
function LuaLRUKeyTable:Add(key,obj)
|
|
local array = self[4][key]
|
|
local removed,removes
|
|
if(array == nil) then
|
|
array = CreateArray()
|
|
self[4][key] = array
|
|
self[3][#self[3] + 1] = key
|
|
if(#self[3] > self[1] and self[1]~=0) then
|
|
removed,removes = self:RemoveByKey(self[3][1])
|
|
end
|
|
elseif(self[1]~=0)then
|
|
MoveElementToLast(self[3],key)
|
|
end
|
|
-- LogUtility.InfoFormat("LuaLRUKeyTable 的key數量為{0},limit {1}",#self[3],self[1])
|
|
|
|
if(#array>=self[2]) then
|
|
return false,nil
|
|
end
|
|
if(FAST_MODE or ArrayFindIndex(array,obj)==0) then
|
|
ArrayPushBack(array, obj)
|
|
return true,removes
|
|
else
|
|
LogUtility.ErrorFormat("LuaLRUKeyTable already has this obj {0} {1}",tostring(key),tostring(obj))
|
|
end
|
|
end
|
|
|
|
function LuaLRUKeyTable:RemoveByKey(key)
|
|
local array = self[4][key]
|
|
if(array) then
|
|
ArrayRemove(self[3],key)
|
|
self[4][key] = nil
|
|
return true,array
|
|
end
|
|
return false,nil
|
|
end
|
|
|
|
function LuaLRUKeyTable:TryGetValue(key)
|
|
local array = self[4][key]
|
|
if(array) then
|
|
if(self[1]~=0)then
|
|
MoveElementToLast(self[3],key)
|
|
end
|
|
local element = ArrayPopBack(array)
|
|
if(#array == 0) then
|
|
local removed,removes = self:RemoveByKey(key)
|
|
if(removes~=nil) then
|
|
DestroyAndClearArray(removes)
|
|
end
|
|
end
|
|
return element
|
|
end
|
|
end
|
|
|
|
function LuaLRUKeyTable:TryGetValueNoRemove(key)
|
|
local array = self[4][key]
|
|
if(array) then
|
|
if(self[1]~=0)then
|
|
MoveElementToLast(self[3],key)
|
|
end
|
|
if(#array>0) then
|
|
return array[#array]
|
|
end
|
|
return nil
|
|
end
|
|
end
|
|
|
|
function LuaLRUKeyTable:GetKeyCount()
|
|
return #self[3]
|
|
end
|
|
|
|
function LuaLRUKeyTable:GetElementCountByKey(key)
|
|
local array = self[4][key]
|
|
if(array) then
|
|
return #array
|
|
end
|
|
return 0
|
|
end
|
|
|
|
function LuaLRUKeyTable:KeyIsFull()
|
|
return #self[3] >= self[1] and self[1]~=0
|
|
end
|
|
|
|
function LuaLRUKeyTable:GetKeyLimit()
|
|
return self[1]
|
|
end
|
|
|
|
function LuaLRUKeyTable:ElementsFull(key)
|
|
local array = self[4][key]
|
|
if(array) then
|
|
return #array >= self[2]
|
|
end
|
|
return false
|
|
end
|
|
|
|
function LuaLRUKeyTable:Clear()
|
|
TableUtility.ArrayClear(self[3])
|
|
TableUtility.TableClear(self[4])
|
|
end
|
|
|
|
--TODO 動態設定key limit
|
|
|
|
|
|
SimpleLuaLRU = class("LuaSimpleLuaLRULRU")
|
|
|
|
function SimpleLuaLRU:ctor(capacity)
|
|
self[1] = capacity
|
|
self[2] = {}
|
|
end
|
|
|
|
function SimpleLuaLRU:GetObjs()
|
|
return self[2]
|
|
end
|
|
|
|
--return removed obj
|
|
function SimpleLuaLRU:Add(obj)
|
|
if(obj~=nil) then
|
|
local array = self[2]
|
|
local index = ArrayFindIndex(array,obj)
|
|
if(index==0) then
|
|
local count = #array
|
|
array[#array+1] = obj
|
|
if(count==self[1]) then
|
|
return tableRemove(array,1)
|
|
end
|
|
else
|
|
tableRemove(array,index)
|
|
array[#array+1] = obj
|
|
end
|
|
end
|
|
return nil
|
|
end
|
|
|
|
function SimpleLuaLRU:Remove(obj)
|
|
if(obj~=nil) then
|
|
return ArrayRemove(self[2],obj)~=0
|
|
end
|
|
end |