From 2cd47e321828fcf90936b1a8c39843c5dee5eb41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Carl=20H=C3=B6rberg?= Date: Sun, 28 Jul 2024 15:52:38 +0200 Subject: [PATCH] Implement Table#hash Copy the implemenation from Hash#hash, which produces the same hash regardless of order of keys --- spec/table_spec.cr | 6 ++++++ src/amq/protocol/table.cr | 17 +++++++++++++++++ 2 files changed, 23 insertions(+) diff --git a/spec/table_spec.cr b/spec/table_spec.cr index b0ef864..1e4747d 100644 --- a/spec/table_spec.cr +++ b/spec/table_spec.cr @@ -164,6 +164,12 @@ describe AMQ::Protocol::Table do t1["x-delay"]?.should be_nil t1.to_h.should eq({"x-stream-offset" => 1i64}) end + + it "hash values for two semantically tables are the same" do + t1 = AMQ::Protocol::Table.new({a: 1, b: "foo"}) + t2 = AMQ::Protocol::Table.new({b: "foo", a: 1}) + t1.hash.should eq t2.hash + end end # Verifies bugfix for Sub-table memory corruption diff --git a/src/amq/protocol/table.cr b/src/amq/protocol/table.cr index cd22b27..ae53bdd 100644 --- a/src/amq/protocol/table.cr +++ b/src/amq/protocol/table.cr @@ -167,6 +167,23 @@ module AMQ true end + # See `Object#hash(hasher)` + def hash(hasher) + # Copied from Hash#hash + # The hash value must be the same regardless of the + # order of the keys. + result = hasher.result + + each do |key, value| + copy = hasher + copy = key.hash(copy) + copy = value.hash(copy) + result &+= copy.result + end + + result.hash(hasher) + end + def delete(key : String) ensure_writeable @io.rewind