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 retrieve method 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 retrieve of the instance to retrieve the value requested. Alternatively, it uses the value of field default as 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

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.