aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGuilherme Andrade <[email protected]>2017-04-22 20:00:28 +0100
committerGuilherme Andrade <[email protected]>2017-04-22 20:00:28 +0100
commitda9abd24a93ae8fe174cdd38fc9699bbc45fdf56 (patch)
tree7ad0766a1d5a235ebbbf92af770241e7dd035885
parentd810cd2b1ce642703d4986ba26ba50fd7949fcab (diff)
downloadotp-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.xml17
-rw-r--r--erts/emulator/beam/erl_nif.c10
-rw-r--r--erts/emulator/beam/erl_nif_api_funcs.h2
-rw-r--r--erts/emulator/test/nif_SUITE_data/nif_SUITE.c6
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[])