[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Self-deleting weak tables?
- From: Mark Hamburg <mark@...>
- Date: Sun, 1 Nov 2009 11:08:37 -0800
For Lua-based objects note that you can add essentially arbitrary keys
to the object. You can even keep these moderately private by using
tables rather than strings as keys. The "moderate" part stems from the
fact that you can discover them via iteration. In fact, as long as the
objects aren't used with the pairs iterator (or next), it should
generally be safe to add the extra fields.
For userdata, you would need to add support for storing arbitrary
references presumably using the environment table.
But the key point is that so long as the objects don't need to be
iterable, it actually isn't all that hard to store extra links into
them.
Mark
-----
-- WARNING: Untested. Not even compiled.
local kLevel1Key = { }
local kLevel2Key = { }
-- cacheRoot auto constructs the succeeding levels
-- Base tables will simply be fully weak
local kFullyWeak = { __mode = 'kv' }
local function makeBase()
return setmetatable( {}, kFullyWeak )
end
-- Given a constructor function, we want an __index function that runs
the constructor and
-- stores the result.
local function makeConstructingIndex( constructor )
return function( t, k )
local v = constructor()
t[ k ] = v
return v
end
end
-- Given a constructor function, we want a metatable for tables that
auto-populate.
local function makeConstructingMetatable( constructor )
return { __mode = 'kv', _index = makeConstructingIndex( constructor ) }
end
-- Given the constructor for the next level in the cache, create a
constructor for this level.
local function makeConstructor( nextLevelConstructor )
local mt = makeConstructingMetatable( nextLevelConstructor )
return function()
return setmetatable( {}, mt )
end
end
-- For a three level cache, we do one round of wrapping
local cacheRoot = setmetatable( { },
makeConstructingMetatable( -- Constructs first level
makeConstructor( -- Constructs second level
makeBase ) ) ) -- Constructs leaves
function storeCachedObject( object, key1, key )
local t1 = cacheRoot[ key1 ]
local t2 = t1[ key2 ]
t2[ key3 ] = object
object[ kLevel1Key ] = t1
object[ kLevel2Key ] = t2
return object
end
-- BONUS POINTS: The cache could actually auto construct the object
but then it needs to have back links to
-- find the path through the cache. This could be done using private
links in the cache tables. If doing that,
-- we might try to arrange for a strong back chain via an extra level
of indirection in the cache tables. Logic
-- to do so not evaluated here.