LUA implements data structure: fixed-length queue

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

Guess you like

Origin blog.csdn.net/sayWhat_sayHello/article/details/115507483