
Object Cache
loop.collection.ObjectCache
Class of objects that cache values for different key values. Whenever the value of a given a key is requested, a function is used to retrieve the corresponding value that is also cached for further requests of the same key. If the key value is collected as garbage, the cache entry becomes garbage as well. This class is useful for implementing optimizations that avoid re-evaluation of complex operations or duplication of similar objects.
ObjectCache class defines the __index meta-method so that it uses the method retrieve of its instance to retrieve values for keys not already mapped by the instance. If the instance does not provide the method retrieve then it uses the value of field default as the value for keys not mapped. Anyway, the values retrieved for each key are stored in the instance with the corresponding key as index thus further requests for the same key work just like a simple table indexing.
Behavior
Fields
default: any [optional]- Default value used for missing keys. By default this field is nil and may be defined for each instance. This field is only used if no
retrievemethod is avaliable.
Methods
retrieve(key)[optional]- Method used to retrieve values for a missing key which value is provided by
key. By default this field is nil and may be defined for each instance.
Meta-Fields
__index = function- Uses the method
retrieveof the instance to retrieve the value requested. Alternatively, it uses the value of fielddefaultas the value requested. Anyway, it stores the value obtained in the object with the index provided. __mode = "k"- Defines that cached keys are weak references thus cached entries are collected if their keys becomes garbage.
Remarks
- Mapping the key
"retrieve"may lead to unexpected results. - When using the field
default, mapping the key"default"may lead to unexpected results either.
Examples
Function that prints friendly names for values
local ObjectCache = require "loop.collection.ObjectCache"
local names = ObjectCache()
function names:retrieve(value)
local type = type(value)
local id = rawget(self, type) or 0
self[type] = id + 1
local label = {}
repeat
label[#label + 1] = string.byte("A") + (id % 26)
id = math.floor(id / 26)
until id <= 0
return string.format("%s %s", type, string.char(unpack(label)))
end function print(...)
for i=1, select("#", ...) do
local value = select(i, ...)
local type = type(value)
if type == "nil" or type == "boolean" or type == "number" or type == "string" then
io.write(tostring(value))
else
io.write(names[value])
end
end
io.write("\n")
end for name, value in pairs(_G) do names[value] = name end for name, value in pairs(coroutine) do names[value] = "coroutine."..name end for name, value in pairs(package) do names[value] = "package."..name end for name, value in pairs(string) do names[value] = "string."..name end for name, value in pairs(table) do names[value] = "table."..name end for name, value in pairs(math) do names[value] = "math."..name end for name, value in pairs(io) do names[value] = "io."..name end for name, value in pairs(os) do names[value] = "os."..name end function f() end t = { 1, true, {}, f, math.sin, _G }
print("value of f is ",f)
print("value of t is ",t)
for i, value in ipairs(t) do
print(" value of t[",i,"] is ",t[i])
end
Copyright (C) 2004-2008 Tecgraf, PUC-RioThis project is currently being maintained by Tecgraf at PUC-Rio.