-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathRingBuffer.lua
More file actions
65 lines (56 loc) · 1.68 KB
/
RingBuffer.lua
File metadata and controls
65 lines (56 loc) · 1.68 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
local M = {}
local RingBuffer = {}
RingBuffer.__index = RingBuffer
function M.new(maxSize)
assert(maxSize and maxSize > 0, "maxSize must be positive.")
local self = {
maxSize = maxSize,
data = {},
head = 1, -- 指向【下一个】要写入的位置
tail = 1, -- 指向【最早一个】元素的位置
count = 0,
}
return setmetatable(self, RingBuffer)
end
function RingBuffer:add(element)
self.data[self.head] = element
self.head = (self.head % self.maxSize) + 1
if self.count == self.maxSize then
self.tail = (self.tail % self.maxSize) + 1
else
self.count = self.count + 1
end
end
function RingBuffer:get(idx)
if idx < 1 or idx > self.count then
return nil -- 索引越界
end
-- 2. 计算物理索引
-- (self.tail - 1) -- 将 1-based 的 tail 转为 0-based
-- (idx - 1) -- 将 1-based 的逻辑索引转为 0-based 偏移
-- (...) % self.max_size -- 计算 0-based 的物理索引 (处理环绕)
-- ... + 1 -- 将结果转回 1-based 供 table 使用
local physicalIndex = ((self.tail - 1) + (idx - 1)) % self.maxSize + 1
return self.data[physicalIndex]
end
function RingBuffer:getAll()
local result = {}
local currentIndex = self.tail
for i = 1, self.count do
result[i] = self.data[currentIndex]
currentIndex = (currentIndex % self.maxSize) + 1
end
return result
end
function RingBuffer:size()
return self.count
end
function RingBuffer:isFull()
return self.count == self.maxSize
end
function RingBuffer:clear()
self.head = 1
self.tail = 1
self.count = 0
end
return M