A simple circular buffer with reverse iterator (Lua)
Posted: Wed Nov 23, 2016 10:22 pm
This is just a small code snippet showing a simple circular buffer with reverse iterator that I've coded up for my forthcoming IoT NodeMcu-based project. Its purpose is to provide fixed and efficient storage for data coming from sensors, so in my case it basically represents history of N most recent values with additional convenience of the reverse iterator for easy FIFO access. I haven't coded in Lua for some time, so it was quite refreshing to come up with this. I especially like how iterators can make use of closures for tracking state, which makes the implementation pretty simple end easy to read. What I don't like about Lua that much is the infamous 1-based indexing, which feels unnatural to me, especially when dealing with modular arithmetic for index wrapping.
Code: Select all
--[CODE BY FIPS @ 4FIPS.COM, (c) 2016 FILIP STOKLAS, MIT-LICENSED]
History = {}
function History.new(max_size)
local hist = { __index = History }
setmetatable(hist, hist)
hist.max_size = max_size
hist.size = 0
hist.cursor = 1
return hist
end
function History:push(value)
if self.size < self.max_size then
table.insert(self, value)
self.size = self.size + 1
else
self[self.cursor] = value
self.cursor = self.cursor % self.max_size + 1
end
end
function History:iterator()
local i = 0
return function()
i = i + 1
if i <= self.size then
return self[(self.cursor - i - 1) % self.size + 1]
end
end
end
hist = History.new(5)
hist:push(10)
hist:push(20)
hist:push(30)
hist:push(40)
hist:push(50)
hist:push(60)
hist:push(70)
print("Raw (wrapped) values:")
for i, v in ipairs(hist) do
print(v)
end
print("")
print("History values:")
for v in hist:iterator() do
print(v)
end
--[[
output:
Raw (wrapped) values:
60
70
30
40
50
History values:
70
60
50
40
30
--]]