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