diff options
author | Guilherme Andrade <[email protected]> | 2017-04-22 20:00:28 +0100 |
---|---|---|
committer | Guilherme Andrade <[email protected]> | 2017-04-22 20:00:28 +0100 |
commit | da9abd24a93ae8fe174cdd38fc9699bbc45fdf56 (patch) | |
tree | 7ad0766a1d5a235ebbbf92af770241e7dd035885 | |
parent | d810cd2b1ce642703d4986ba26ba50fd7949fcab (diff) | |
download | otp-da9abd24a93ae8fe174cdd38fc9699bbc45fdf56.tar.gz otp-da9abd24a93ae8fe174cdd38fc9699bbc45fdf56.tar.bz2 otp-da9abd24a93ae8fe174cdd38fc9699bbc45fdf56.zip |
erts: Allow for easier future enif_hash expansion
Allow for expanding support to 64-bit hashes without breaking the
interface.
-rw-r--r-- | erts/doc/src/erl_nif.xml | 17 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif.c | 10 | ||||
-rw-r--r-- | erts/emulator/beam/erl_nif_api_funcs.h | 2 | ||||
-rw-r--r-- | erts/emulator/test/nif_SUITE_data/nif_SUITE.c | 6 |
4 files changed, 14 insertions, 21 deletions
diff --git a/erts/doc/src/erl_nif.xml b/erts/doc/src/erl_nif.xml index 5faf1a05fc..534c90cbdc 100644 --- a/erts/doc/src/erl_nif.xml +++ b/erts/doc/src/erl_nif.xml @@ -823,13 +823,13 @@ typedef enum { <item> <p>Non-portable hash function that only guarantees the same hash for the same term within one Erlang VM instance.</p> - <p>Generated hash values within <c>0..2^32-1</c>.</p> + <p>It takes 32-bit salt values and generates hashes within <c>0..2^32-1</c>.</p> </item> <tag><c>ERL_NIF_PHASH2</c></tag> <item> <p>Portable hash function that gives the same hash for the same Erlang term regardless of machine architecture and ERTS version.</p> - <p>Generated hash values within <c>0..2^27-1</c>.</p> + <p>It takes 32-bit salt values and generates hashes within <c>0..2^27-1</c>.</p> <p>Slower than <c>ERL_NIF_INTERNAL_HASH.</c> When used with <c>salt=0</c>, it corresponds to <seealso marker="erlang#phash2-1"><c>erlang:phash2/1</c></seealso>.</p> @@ -1411,17 +1411,14 @@ typedef enum { <func> <name> - <ret>unsigned long</ret> - <nametext> - enif_hash(ErlNifHash type, ERL_NIF_TERM term, unsigned long salt) - </nametext> + <ret>ErlNifUInt64</ret> + <nametext>enif_hash(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64 salt)</nametext> </name> <fsummary>Hash terms.</fsummary> <desc> - <p>Hash <c>term</c> according to the specified - <seealso marker="#ErlNifHash"><c>ErlNifHash</c></seealso> <c>type</c> - and using the least significant 32 bits of <c>salt</c>.</p> - <p>Range of returned value depends on the hash type.</p> + <p>Hashes <c>term</c> according to the specified + <seealso marker="#ErlNifHash"><c>ErlNifHash</c></seealso> <c>type</c>.</p> + <p>Ranges of taken salt and returned value depend on the hash type.</p> </desc> </func> diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index bdfb7f3b8e..3ff6c8d3ed 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1214,17 +1214,13 @@ int enif_compare(Eterm lhs, Eterm rhs) return result; } -unsigned long enif_hash(ErlNifHash type, Eterm term, unsigned long salt) +ErlNifUInt64 enif_hash(ErlNifHash type, Eterm term, ErlNifUInt64 salt) { -#if SIZEOF_LONG < 4 -/* This *really* shouldn't happen */ -# error Incompatible long word size -#endif switch (type) { case ERL_NIF_INTERNAL_HASH: - return make_internal_hash(term, salt); + return make_internal_hash(term, (Uint32) salt); case ERL_NIF_PHASH2: - return make_hash2(term, salt) & ((1 << 27) - 1); + return make_hash2(term, (Uint32) salt) & ((1 << 27) - 1); default: return 0; } diff --git a/erts/emulator/beam/erl_nif_api_funcs.h b/erts/emulator/beam/erl_nif_api_funcs.h index 6b9f78d46b..1a91a04f32 100644 --- a/erts/emulator/beam/erl_nif_api_funcs.h +++ b/erts/emulator/beam/erl_nif_api_funcs.h @@ -47,7 +47,7 @@ ERL_NIF_API_FUNC_DECL(int,enif_get_list_cell,(ErlNifEnv* env, ERL_NIF_TERM term, ERL_NIF_API_FUNC_DECL(int,enif_get_tuple,(ErlNifEnv* env, ERL_NIF_TERM tpl, int* arity, const ERL_NIF_TERM** array)); ERL_NIF_API_FUNC_DECL(int,enif_is_identical,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)); ERL_NIF_API_FUNC_DECL(int,enif_compare,(ERL_NIF_TERM lhs, ERL_NIF_TERM rhs)); -ERL_NIF_API_FUNC_DECL(unsigned long,enif_hash,(ErlNifHash type, ERL_NIF_TERM term, unsigned long salt)); +ERL_NIF_API_FUNC_DECL(ErlNifUInt64,enif_hash,(ErlNifHash type, ERL_NIF_TERM term, ErlNifUInt64 salt)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_binary,(ErlNifEnv* env, ErlNifBinary* bin)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_badarg,(ErlNifEnv* env)); ERL_NIF_API_FUNC_DECL(ERL_NIF_TERM,enif_make_int,(ErlNifEnv* env, int i)); diff --git a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c index 2a80d48b62..a255c9f096 100644 --- a/erts/emulator/test/nif_SUITE_data/nif_SUITE.c +++ b/erts/emulator/test/nif_SUITE_data/nif_SUITE.c @@ -704,12 +704,12 @@ static ERL_NIF_TERM hash_nif(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[] return enif_make_badarg(env); } - unsigned long salt; - if (! enif_get_ulong(env, argv[2], &salt)) { + ErlNifUInt64 salt; + if (! enif_get_uint64(env, argv[2], &salt)) { return enif_make_badarg(env); } - return enif_make_ulong(env, enif_hash(type, argv[1], salt)); + return enif_make_uint64(env, enif_hash(type, argv[1], salt)); } static ERL_NIF_TERM many_args_100(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) |