lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


> [...]
>
> Hm, this, and the suggestion of using the index/newindex metamethods does
> not work for me either because I want the mechanism to work by default,
> however it gave me the following idea:
> 
> How about a flag on every userdata object that switches between the current
> pointer-based hashing for tables, and one that uses the actual userdata (of
> which the address and length is known) i.e. one could use the same hashing
> as for strings, and memcmp() for the equality check)?

Seems to work fine, in my case I didn't even bother to include the flag and
just made the thing compulsory for all userdata objects (because in my case
a userdata object is either immutable or double-indirect, i.e. the userdata
is a boost::shared_ptr<> to the actual, mutable, data...); changelog:

- Extract the hash method from luaS_newlstr() as luaS_hash().
- Change the order of struct Udata::uv's members so that the metatable comes
  last, because:

it seems natural to me to include the metatable pointer in the to-be-hashed
data, but to exclude the env pointer (because I don't know what that's for,
and I don't set ever set it) and the length (arbitrary decision, might as
well include it).

- Create wrapper functions that, given a "const Udata *", return the pointer
  and length of the to-be-hashed data, respectively.
- Change luaO_rawequalobj() to compare the lengths and, if equal, the to-be-
  hashed data of userdata objects, rather than just comparing the pointers.
- Change mainposition() to use the new luaS_hash() function to get a hash
  for userdata objects.

This might be too special-purpose to even consider for inclusion in Lua proper,
but perhaps it can serve as a starting point for further discussion, or there's
somebody with the same special case as I have that can use this idea...

...unless somebody points out that there's a problem with this approach that I
have so far missed (my changes compile, and a simple test case works, but that's
it).

Regards, Colin