[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: [Feature Request?] __key
- From: "Soni L." <fakedme@...>
- Date: Sun, 17 Jul 2016 08:55:43 -0300
On 17/07/16 02:52 AM, Tim Hill wrote:
On Jul 16, 2016, at 5:47 PM, Soni L. <fakedme@gmail.com
<mailto:fakedme@gmail.com>> wrote:
— If two distinct userdata’s return the same type+value for __key
Lua will think they are the same value and bad things will happen
if they are put in the same table, possibly crashing Lua. Not good.
This won't crash Lua.
A hypothetical design that is not yet implemented but you know it
won’t have any problems. Hmmm. Let’s think a moment. I store normal
table item t[10] = “ten”. Then someone stores t[u] = “uten” where u
is a userdata whose __key metamethod returns 10. What happens? If
the original store was into the array part, Lua can’t continue to
use this because it has to allocate a cell to store the userdata
pointer. In fact, it needs to evict the key+value from the array
part and move to to the hash part, and then allocate THREE cells:
one for the return value of __key, one for the userdata and one for
the string value. And what about this code...?
It replaces t[10], obviously. Just like t[10.0] replaces t[10].
t[u] = nil
If __key() for u returns something other than 10, really surprising
things are going to happen.
Like what?
Like it deleting another totally unrelated key+value pair from the
table, and if you don’t find that surprising then I don’t know what to
say.
Not an unrelated key+value pair.
As has been pointed out here many times, if a proposed feature is
going to have a performance impact on the majority of users, it had
better also have a benefit for the majority of users. Adding __key
will certainly impact everyone (added logic in main code paths of
the table module, extra cells to store user-returned keys etc). Will
the majority also benefit? I don’t see that.
Added logic in the table module? Extra cells? What? We don't have
extra cells for floats and we don't have added logic to handle
floats, yet floats decay into integers if they have integral value,
so why would __key need them?
ok, I’ll explain this again. Ignoring for a moment the array part of a
table, each table entry contains two items: a key and value. Both
these are stored in “cells”, the Lua version of a typed value. Let’s
focus on the key, since we are discussing this. For a value of 100.0,
Lua first notices it’s an integral float, coerces that float value to
100 (an integer), and stores this value in the cell. So the key is a
cell with a type of integer and a value of 100 (I’m simplifying a bit
here). But when you add the __key metamethod, things are very
different. First, Lua has to store the userdata reference (as
otherwise it would be unreferenced and subject to garbage collection).
However, you ALSO have to save the “key” (from __key) .. which is
another type+value cell. So in this case the key part of the key+value
entry in the table has TWO cells, not one: one for the userdata and
one for whatever it is being indexed by; the return value of __key. So
you have new code paths and extra data for each key+value entry in a
table.
Bleh
The alternative of course is Lua calls __key every single time it
needs to compare the key for a given table entry. Good luck with
performance, And good luck if __key returns inconsistent values.
That's the sane approach, and it's not much more expensive than what we
have with floats. Remember Lua already does this for floats.
And as others have noted, a better solution to the real problem of
the OP is interning the bigint values so that two bigints are always
the same userdata, which renders __key unnecessary.
And removes interoperability with plain Lua values. The point isn't
to just access the same value from 2 different objects - this isn't
some sort of __hash mechanism. The point is to interoperate with
plain Lua values.
Which can be handled with metamethods on the userdata, such as __eq etc.
And that doesn't work for indexing random tables that you might not have
direct access to!
—Tim
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.