From 0b3fe645e08dfd83e7bc56a1cae2a3860abb20dd Mon Sep 17 00:00:00 2001 From: Yves Orton Date: Tue, 28 Aug 2012 10:15:40 +0200 Subject: [PATCH] fix a very subtle hash ordering dependency in op/smartkve.t Currently our hash implementation is order dependent on insertion. When two keys collide and have to be stored in the same bucket the order in which they are inserted into the hash will govern the order in which they are fetched out by things like keys() and values(). This means that a copy of such a hash may be different. It is possible this can be fixed with a low cost, but until then you cannot rely on two hashes with the same keys having the same ordering of those keys Depending on the hash algorithm and the seed values used this test would fail. By changing it so there is one initial hash and then all tests are done on copies of that hash we avoid the problem. --- t/op/smartkve.t | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/t/op/smartkve.t b/t/op/smartkve.t index ad56e6a..7e5d67e 100644 --- a/t/op/smartkve.t +++ b/t/op/smartkve.t @@ -14,12 +14,24 @@ plan 'no_plan'; sub j { join(":",@_) } +# NOTE +# +# Hash insertion is currently unstable, in that +# %hash= %otherhash will not necessarily result in +# the same internal ordering of the data in the hash. +# For instance when keys collide the copy may not +# match the inserted order. So we declare one hash +# and then make all our copies from that, which should +# mean all the copies have the same internal structure. +our %base_hash; + BEGIN { # in BEGIN for "use constant ..." later + %base_hash= ( pi => 3.14, e => 2.72, i => -1 ); $array = [ qw(pi e i) ]; $values = [ 3.14, 2.72, -1 ]; - $hash = { pi => 3.14, e => 2.72, i => -1 } ; + $hash = { %base_hash } ; $data = { - hash => { %$hash }, + hash => { %base_hash }, array => [ @$array ], }; } @@ -27,7 +39,7 @@ BEGIN { # in BEGIN for "use constant ..." later package Foo; sub new { my $self = { - hash => {%{$main::hash} }, + hash => { %base_hash }, array => [@{$main::array}] }; bless $self, shift; @@ -58,10 +70,10 @@ use overload '@{}' => sub { $main::array }, fallback => 1; package main; -use constant CONST_HASH => { %$hash }; +use constant CONST_HASH => { %base_hash }; use constant CONST_ARRAY => [ @$array ]; -my %a_hash = %$hash; +my %a_hash = %base_hash; my @an_array = @$array; sub hash_sub { return \%a_hash; } sub array_sub { return \@an_array; } -- 1.8.3.1