On Thu, 7 Apr 2011, Martin Stjernholm, Roxen IS @ Pike developers forum wrote:
@@ -966,6 +966,7 @@ PIKECLASS Backend return c->pos; } }
return -1; } /* Note: is_eq() may call Pike code (which we want),
but Pike code may change the hash tables...
Not safe since an array can actually work as a callable:
call_out (({lambda() {werror ("oy!\n");}}), 0);
(1) Result: ({ /* 1 element */ ({ /* 1 element */ HilfeInput()->__lambda_65794_0_line_1 }) })
start backend oy!
It should still be found in the first loop then. In both cases the pointer is used as the hash value. Its only that since my change in hash_svalue it wont anymore, since the extra mixing is only used on the function pointer. I pushed my changes for power of two hash tables using the same hashing for ids and functions again to the main git in the branch arne/pow2.
[...]
But now when I look closer at the buckets, I notice that new call outs are added to the beginning, and this function searches from the end. So if the same function is added multiple times with call out times in reverse order then (find|remove)_call_out will find the last function in the queue rather than the first one. This test program verifies that:
[...]
I'd say that's a bug, or at least it doesn't agree with the documentation. :(
Yes, I noticed that and hence assumed that the order does not matter. If it does, my optimization is bad. On the other hand, if the buckets are properly sorted, we could do both is_identical checks and either return or push if the current one is not identical to the top on the stack.
It also looks like a rehash shuffles the buckets a bit.
This is something that would be fixed by power of two hash tables, since the code only seems to increase the hash table size. And then, buckets are only split, never shuffled.