local DefaultCapacity = 16 local DummyFunc = function() end local assert = assert local PoolMT = { __newindex = function() error('table pool is read-only') end } local function TablePool(createOrResetFunc, disposeFunc, capcacity, reserved, ...) local pool = {} --pool data upvalues local poolCreateOrResetFunc = createOrResetFunc or DummyFunc local poolDisposeFunc = disposeFunc or DummyFunc local poolCapcacity = capcacity or DefaultCapacity local poolTable = LuaExt.CreateTable(poolCapcacity, 0) local poolCount = 0 --for usage report local poolTryGetCount = 0 local poolRecycleCount = 0 local poolCreateCount = 0 local poolDiscardCount = 0 if reserved then for i = 1, reserved do poolTable[i] = poolCreateOrResetFunc(nil, ...) end poolCount = reserved poolCreateCount = reserved end --for performance, avoid use of table.remove and # operator function pool.TryGet(...) poolTryGetCount = poolTryGetCount + 1 if poolCount > 0 then local item = poolTable[poolCount] poolCount = poolCount - 1 return poolCreateOrResetFunc(item, ...) else poolCreateCount = poolCreateCount + 1 return poolCreateOrResetFunc(nil, ...) end end function pool.Recycle(item, ...) assert(item, "table pool recycle with nil") poolRecycleCount = poolRecycleCount + 1 poolDisposeFunc(item, ...) if poolCount < poolCapcacity then poolCount = poolCount + 1 poolTable[poolCount] = item else poolDiscardCount = poolDiscardCount + 1 end end function pool.Reset(item, ...) assert(item, "table pool reset with nil") poolDisposeFunc(item, ...) return poolCreateOrResetFunc(item, ...) end function pool.GetUsageReport(reset) local gc, rc, nc, dc = poolTryGetCount, poolRecycleCount, poolCreateCount, poolDiscardCount if reset then poolTryGetCount = 0 poolRecycleCount = 0 poolCreateCount = 0 poolDiscardCount = 0 end return poolCount, poolCapcacity, gc, rc, nc, dc end return setmetatable(pool, PoolMT) end return TablePool