foreword
I posted a blog post about double-ended queues before. This fixed-length queue is modified based on the previous structure.
LUA implements data structure: double-ended queue
This data structure can be seen in various records in the game. For example, the lottery records will be constantly replaced, and the records generated later will replace the previous records.
The client may need to display 10 items when displaying, but you should store 20 items or the like.
the code
A fixed-length queue is actually a FIFO queue, with one end entering and one end exiting, and the size of the queue is fixed:
on the basis of the original, we added length to indicate the current length of the queue, and a max_length to indicate the maximum length of the queue.
When entering the team, it is judged whether it is greater than max_length, and if it is greater, the advanced element will be polled.
Finally, a method for obtaining the last N elements is provided.
New file name:fixed_length_queue.lua
local List = {
}
List.__index = List
function List:new(max_length)
assert(max_length)
local self = {
first = 0, last = -1, length = 0, max_length = max_length}
return setmetatable(self, List)
end
function List:push(value)
local last = self.last + 1
self.length = self.length + 1
self.last = last
self[last] = value
if self.length > self.max_length then
self:poll()
end
end
function List:poll()
local first = self.first
if first > self.last then error("list is empty") end
local value = self[first]
self[first] = nil -- to allow garbage collection
if first == self.last then
self.first = 0
self.last = -1
else
self.first = first + 1
end
self.length = self.length - 1
return value
end
-- should not change the self in func
-- func return break or not
function List:foreach(func, right_first)
if right_first then
for i = self.last, self.first, -1 do
if func(self[i]) then break end
end
else
for i = self.first, self.last do
if func(self[i]) then break end
end
end
end
function List:clear()
if not self:empty() then
for i = self.first, self.last do
self[i] = nil
end
end
self.first = 0
self.last = -1
end
function List:to_table()
local res = {
}
for i = self.first, self.last do
table.insert(res, self[i])
end
return res
end
function List:get_last_n_rcd(n)
local res = {
}
for i = 0, n - 1 do
if self.first > self.last - i then return res end
table.insert(res, self[self.last - i])
end
return res
end
return List
test code
The test code is as follows:
local List = require("fixed_length_queue")
local list = List:new(10)
for i = 1, 20 do
list:push(i)
end
list:foreach(print)
print("-----------------")
local ret = list:get_last_n_rcd(5)
for _, v in ipairs(ret) do
print(v)
end
result:
11
12
13
14
15
16
17
18
19
20
-----------------
20
19
18
17
16