Documentation for this module may be created at Module:Sandbox/Artoria2e5/CacheUtils/doc

-- Cached function decorators.
-- lru
-- lfu
-- rr

local defaultsize = 128

-- An ordered dict implementation.
local orderedDict = {}

function orderedDict.create(argDict, argOrder)
	if (#dict) ~= (#order) then
		return nil
	end
	
	-- grrr, this won't work if I want (amortized) O(1) removal
	-- TODO: Use a double-linked map of the form table<key:T, node<val:T, prev:node, next:node>>
	local dict = {}
	for k, v in pairs(argDict) do
		dict[k] = { ['v'] = v }
	end
	local order = {} -- tableArray
	
	local function len(this) 
		return #dict
	end
	
	local function newindex(this, k, v)
		dict[k] = { ['v'] = v }
		table.insert(order, k)
	end
	
	local function leak()
		return dict, order
	end
	
	local ret = {}
	setmetatable(ret, {
		["__len"] = len,
		["__newindex"] = __newindex,
		-- FIXME
		["__index"] = dict,
		["__mwint__leak"] = leak,
	})
	return ret
end

-- These need to go into the metatable. They interfere with indexing.
function orderedDict:has(od, k)
	local dict, order, nils = getmetatable(od).__mwint__leak()
	return (dict[k] ~= nil) or (nils[k])
end

function orderedDict:pop(od, k)
	local dict, order, nils = getmetatable(od).__mwint__leak()
	if orderedDict:has(od, k) then
		v = dict[k]
		table.remove(dict, k)
		if v == nil then
			table.remove(nils, k)
		end
		
	else
		return nil, false
	end
end


local function lru_cache(func, size)
	size = size or defaultsize
	memo = OrderedDict.create()
	
end

return {
	["lru"] = lru_cache,
	["_"] =  {
		["orderedDict"] = orderedDict
	}
}