www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to get hash value of an object?

reply panmengh <panmengh gmail.com> writes:
How to get hash value of an object?

Use hashOf? or typeid(T).getHash(&o)?

I test with the following code:

System:
windows 10

dmd --version
DMD32 D Compiler v2.072.0 (official download version)

ldc2 --version
LDC - the LLVM D compiler (1.1.0git-62a2252) (the latest git 
master version)
   based on DMD v2.071.2 and LLVM 3.9.1git

import std.stdio;

void main()
{
     string[string] a;
     string[string] b0;

     writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), 
"\t\t\t",
         b0.hashOf(), "\t\t",typeid(typeof(b0)).getHash(&b0), "  
", a,);

     a["1"] = "1";
     string[string] b1 = ["1":"1"];
     writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), 
"\t\t",
         b1.hashOf(), "\t\t",typeid(typeof(b1)).getHash(&b1), "  
", a,);

     a["9"] = "9";
     string[string] b2 = ["1":"1", "9":"9"];
     writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), 
"\t\t\t",
         b2.hashOf(), "\t\t",typeid(typeof(b2)).getHash(&b2), "  
", a,);

     a["3"] = "3";
     string[string] b3 = ["1":"1", "9":"9", "3":"3"];
     writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), 
"\t\t",
         b3.hashOf(), "\t\t",typeid(typeof(b3)).getHash(&b3), "  
", a,);

     a.remove("1");
     a["1"] = "1";
     string[string] b4 = ["1":"1", "9":"9", "3":"3"];
     writeln(a.hashOf(), "\t\t",typeid(typeof(a)).getHash(&a), 
"\t\t",
         b3.hashOf(), "\t\t",typeid(typeof(b4)).getHash(&b4), "  
", a,);
}

Output:
dub --compiler=dmd -a=x86_64
Running .\test2.exe
1669671676      0           1669671676  0           []
732702303       2197205690  683765274   3388425732  ["1":"1"]
732702303       0           912895782   0           ["1":"1", 
"9":"9"]
732702303       2197205690  4139255736  3388425732  ["3":"3", 
"1":"1", "9":"9"]
732702303       2197205690  4139255736  3388425732  ["3":"3", 
"1":"1", "9":"9"]

test2.exe (second run)
1669671676      0           1669671676  0           []
1608602074      122060002   2487796584  31054674    ["1":"1"]
1608602074      0           3256818953  0           ["1":"1", 
"9":"9"]
1608602074      122060002   667025292   31054674    ["3":"3", 
"1":"1", "9":"9"]
1608602074      122060002   667025292   31054674    ["3":"3", 
"1":"1", "9":"9"]

dub --compiler=ldc2 -a=x86_64
Running .\test2.exe
593689054       0           593689054   0           []
1747365348      1899073920  1747365348  1899073920  ["1":"1"]
3252326176      0           3252326176  0           ["1":"1", 
"9":"9"]
492636279       1899073920  492636279   1899073920  ["3":"3", 
"1":"1", "9":"9"]
492636279       1899073920  492636279   1899073920  ["3":"3", 
"1":"1", "9":"9"]

test2.exe (second run)
593689054       0           593689054   0           []
1747365348      2353409518  1747365348  2353409518  ["1":"1"]
3252326176      0           3252326176  0           ["1":"1", 
"9":"9"]
492636279       2353409518  492636279   2353409518  ["3":"3", 
"1":"1", "9":"9"]
492636279       2353409518  492636279   2353409518  ["3":"3", 
"1":"1", "9":"9"]

Does only hashOf with ldc2 return the right value?
Nov 26 2016
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
On 11/27/16 2:10 AM, panmengh wrote:
 How to get hash value of an object?

 Use hashOf? or typeid(T).getHash(&o)?
hashOf is kind of this horrible hacky thing that nobody should be using. It literally takes whatever you pass it and hashes the local bytes. It doesn't care about opHash or if any of those bytes are actually references to the things you want hashed. In fact, for class references, it just hashes the bytes that point at the class. Useless. Long story short, use typeid(T).getHash(&o).
 Does only hashOf with ldc2 return the right value?
If it does, that's a coincidence. Happened to allocate in the same place. -Steve
Nov 28 2016
parent reply Era Scarecrow <rtcvb32 yahoo.com> writes:
On Tuesday, 29 November 2016 at 00:05:31 UTC, Steven 
Schveighoffer wrote:
 hashOf is kind of this horrible hacky thing that nobody should 
 be using. It literally takes whatever you pass it and hashes 
 the local bytes.
Ugg... Anything with pointers, classes or arrays will have huge problems with consistency; While anything with fixed static arrays or pure value-types will result in proper values. I'd almost prefer an option to get hashOf all inner object types and then xor them all together. Although this could make for a very complex hashOf depending on implementation of the object.
 Long story short, use typeid(T).getHash(&o).
Hmmm maybe make any struct have hashOf disabled if it includes any pointers or dynamic arrays or inner objects that can't get a proper hash of it. While it will break things, at least you know what can't be hashed when you try to use it. Or maybe have that as a compiler option for those wanting to make use of that.
Dec 04 2016
parent Seb <seb wilzba.ch> writes:
On Sunday, 4 December 2016 at 13:17:09 UTC, Era Scarecrow wrote:
 On Tuesday, 29 November 2016 at 00:05:31 UTC, Steven 
 Schveighoffer wrote:
 hashOf is kind of this horrible hacky thing that nobody should 
 be using. It literally takes whatever you pass it and hashes 
 the local bytes.
Ugg... Anything with pointers, classes or arrays will have huge problems with consistency; While anything with fixed static arrays or pure value-types will result in proper values.
For the record: it was a regression and has been fixed with https://github.com/dlang/druntime/pull/1707 and thus should be part of the next point release.
Dec 11 2016