Sliding window counters are useful for maintaining information about some last n transactions. One example could be a site like pingdom storing last n ping times for a site. Cacheismo comes with a default sliding window counter example which can be modified to suit your needs. The current implementation supports new, add, getlast, getmin, getmax, getavg.
Note that these are memached get requests with special keys encoding our intent. The keys follow the following syntax:
<ObjectType>:<Method>:<ObjectKey>:<Arg1>:<Arg2>
Object type is "swcounter". Cacheismo has other object types as well and more can be added by adding new lua scripts. Methods for swcounter object are "new", "add", "getmin", "getmax","getavg", "getlast", Object key we are using is "myCounter". You would need key per counter. Number of arguments would vary depending upon the method. Here new takes 1 arg (number of values to store), add takes 1 arg (value to store). Rest all methods take no arguments.
get swcounter:new:myCounter:2
VALUE swcounter:myCounter:100 0 8
CREATED
-- Create a new counter which stores the last 2 values
get swcounter:add:myCounter:100
VALUE swcounter:add:myCounter:100 0 7
SUCCESS
--store 100 as first value
get swcounter:add:myCounter:50
VALUE swcounter:add:myCounter:50 0 7
SUCCESS
Note that these are memached get requests with special keys encoding our intent. The keys follow the following syntax:
<ObjectType>:<Method>:<ObjectKey>:<Arg1>:<Arg2>
Object type is "swcounter". Cacheismo has other object types as well and more can be added by adding new lua scripts. Methods for swcounter object are "new", "add", "getmin", "getmax","getavg", "getlast", Object key we are using is "myCounter". You would need key per counter. Number of arguments would vary depending upon the method. Here new takes 1 arg (number of values to store), add takes 1 arg (value to store). Rest all methods take no arguments.
get swcounter:new:myCounter:2
VALUE swcounter:myCounter:100 0 8
CREATED
-- Create a new counter which stores the last 2 values
get swcounter:add:myCounter:100
VALUE swcounter:add:myCounter:100 0 7
SUCCESS
--store 100 as first value
get swcounter:add:myCounter:50
VALUE swcounter:add:myCounter:50 0 7
SUCCESS
-- store 50 as second value
get swcounter:getmin:myCounter
VALUE swcounter:getmin:myCounter 0 2
50
-- get the min entry among all the stored values
get swcounter:getmax:myCounter
VALUE swcounter:getmax:myCounter 0 3
100
-- get the max entry among all the stored values
get swcounter:getavg:myCounter
VALUE swcounter:getavg:myCounter 0 2
75
-- get the average value for all the stored values
VALUE swcounter:getmin:myCounter 0 2
50
-- get the min entry among all the stored values
get swcounter:getmax:myCounter
VALUE swcounter:getmax:myCounter 0 3
100
-- get the max entry among all the stored values
get swcounter:getavg:myCounter
VALUE swcounter:getavg:myCounter 0 2
75
-- get the average value for all the stored values
The complete implementation in lua looks like this.
====================================================
-- sliding window counter
local function new(windowsize)
local object = {}
if (windowsize == nil) then
windowsize = "16"
end
object.size = tonumber(windowsize)
object.index = 0
object.values = {}
local count = 0
for count = 1,object.size do
object.values[count] = 0
end
return object
end
local function add(object, value)
object.index = object.index+1
if (object.index > object.size) then
object.index = 1
end
object.values[object.index] = tonumber (value)
end
local function getlast(object)
if (object.index ~= 0) then
return object.values[object.index]
end
return 0
end
local function getmin(object)
local count = 0
local min = math.huge
for count = 1,object.size do
if (object.values[count] < min) then
min = object.values[count]
end
end
return min
end
local function getmax(object)
local count = 0
local max = 0
for count = 1,object.size do
if (object.values[count] > max) then
max = object.values[count]
end
end
return max
end
local function getavg(object)
local count = 0
local total = 0
for count = 1, object.size do
total = total + object.values[count]
end
return (total/object.size)
end
=============================================================