| 1 | % (c) 2009-2019 Lehrstuhl fuer Softwaretechnik und Programmiersprachen, | |
| 2 | % Heinrich Heine Universitaet Duesseldorf | |
| 3 | % This software is licenced under EPL 1.0 (http://www.eclipse.org/org/documents/epl-v10.html) | |
| 4 | ||
| 5 | :- module(hashing,[my_term_hash/2, efficient_index/1]). | |
| 6 | ||
| 7 | :- use_module(library(terms),[term_hash/3]). | |
| 8 | ||
| 9 | ||
| 10 | :- use_module(module_information,[module_info/2]). | |
| 11 | ||
| 12 | :- module_info(group,animator). | |
| 13 | :- module_info(description,'This module computes hash values (mainly for states) for efficient indexing.'). | |
| 14 | ||
| 15 | % -------------------------------------------- | |
| 16 | ||
| 17 | :- use_module(self_check). | |
| 18 | ||
| 19 | :- assert_must_succeed(( hashing:my_term_hash([1,2,3],X), hashing:efficient_index(X) )). | |
| 20 | :- assert_must_succeed(( hashing:my_term_hash([1,2,3],X), hashing:my_term_hash([1,2,4],Y), X\=Y )). | |
| 21 | ||
| 22 | :- if(tools:platform_is_64_bit). | |
| 23 | :- format("64-bit platform~n",[]). | |
| 24 | my_term_hash(T,Res) :- super_hash(T,Res). | |
| 25 | :- else. | |
| 26 | :- format("32-bit platform~n",[]). | |
| 27 | my_term_hash(T,Res) :- term_hash(T, | |
| 28 | [range(smallint), /* will use full 32 bit on 64 bit systems, 28 bit on 32 bit system */ | |
| 29 | algorithm(sdbm), % other options jenkins, hsieh, default | |
| 30 | depth(infinite),if_var(ignore)],Res). | |
| 31 | % collisions seem with more recent versions of SICStus to no longer be a problem !? | |
| 32 | % sdbm seems to generate less collisions | |
| 33 | :- endif. | |
| 34 | ||
| 35 | % check if a hash value is an efficient for first argument indexing | |
| 36 | efficient_index(X) :- number(X), | |
| 37 | prolog_flag(max_tagged_integer,Max), X=<Max, | |
| 38 | prolog_flag(min_tagged_integer,Min), X>=Min. | |
| 39 | ||
| 40 | % On 64-bit machines we can use the following for efficient indexing: | |
| 41 | :- public super_hash/2. | |
| 42 | super_hash(Term,Hash) :- | |
| 43 | term_hash(Term,[range(smallint),algorithm(sdbm),depth(infinite),if_var(ignore)],H1), | |
| 44 | term_hash(Term,[range(smallint32),algorithm(jenkins),depth(infinite),if_var(ignore)],H2), | |
| 45 | Hash is H1 + (H2 << 32). % should be in range 0.. 2**60 | |
| 46 | % we could still try and use negative numbers | |
| 47 |