From 0835f40ae25f97360dc393928796387d3cd6b16e Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Wed, 19 Apr 2017 00:43:37 +0100 Subject: erts: Add enif_phash2 and enif_phash2_ranged These allow one to hash VM terms from NIF code. --- erts/emulator/beam/erl_nif.c | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'erts/emulator/beam/erl_nif.c') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index f86b9739fa..14abf461a3 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -55,6 +55,7 @@ #include "dtrace-wrapper.h" #include "erl_process.h" #include "erl_bif_unique.h" +#include "erl_utils.h" #undef ERTS_WANT_NFUNC_SCHED_INTERNALS__ #define ERTS_WANT_NFUNC_SCHED_INTERNALS__ #include "erl_nfunc_sched.h" @@ -1213,6 +1214,25 @@ int enif_compare(Eterm lhs, Eterm rhs) return result; } +#if SIZEOF_LONG < 4 +/* This *really* shouldn't happen */ +# error Incompatible long word size +#endif + +unsigned long enif_phash2(Eterm term) +{ + return make_hash2(term) & ((1 << 27) - 1); +} + +unsigned long enif_phash2_ranged(Eterm term, unsigned long range) +{ +#if SIZEOF_LONG > 4 + if (range > (unsigned long) UINT32_MAX) + range = 0; +#endif + return make_hash2_within_range(term, range); +} + int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array) { Eterm* ptr; -- cgit v1.2.3 From 1b37d0b010ea31b04b9d0a15d0bec9c75a013dc9 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Thu, 20 Apr 2017 21:35:54 +0100 Subject: erts: Remove enif_phash2_ranged --- erts/emulator/beam/erl_nif.c | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) (limited to 'erts/emulator/beam/erl_nif.c') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 14abf461a3..f7777c8b92 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1214,25 +1214,15 @@ int enif_compare(Eterm lhs, Eterm rhs) return result; } +unsigned long enif_phash2(Eterm term) +{ #if SIZEOF_LONG < 4 /* This *really* shouldn't happen */ # error Incompatible long word size #endif - -unsigned long enif_phash2(Eterm term) -{ return make_hash2(term) & ((1 << 27) - 1); } -unsigned long enif_phash2_ranged(Eterm term, unsigned long range) -{ -#if SIZEOF_LONG > 4 - if (range > (unsigned long) UINT32_MAX) - range = 0; -#endif - return make_hash2_within_range(term, range); -} - int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array) { Eterm* ptr; -- cgit v1.2.3 From d8756f8665a42effa2f3515369058cff4441abeb Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Thu, 20 Apr 2017 22:44:04 +0100 Subject: erts: Refactor enif_phash2 into enif_hash A more generic hashing function which can also hash terms based on `make_internal_hash'. --- erts/emulator/beam/erl_nif.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) (limited to 'erts/emulator/beam/erl_nif.c') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index f7777c8b92..3470cf3fd5 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1214,13 +1214,20 @@ int enif_compare(Eterm lhs, Eterm rhs) return result; } -unsigned long enif_phash2(Eterm term) +unsigned long enif_hash(ErlNifHash type, Eterm term) { #if SIZEOF_LONG < 4 /* This *really* shouldn't happen */ # error Incompatible long word size #endif - return make_hash2(term) & ((1 << 27) - 1); + switch (type) { + case ERL_NIF_INTERNAL_HASH: + return make_internal_hash(term); + case ERL_NIF_PHASH2: + return make_hash2(term) & ((1 << 27) - 1); + default: + return 0; + } } int enif_get_tuple(ErlNifEnv* env, Eterm tpl, int* arity, const Eterm** array) -- cgit v1.2.3 From 21e1d879faaae2278a68200fe1085d7e73791fa0 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Sat, 22 Apr 2017 17:22:32 +0100 Subject: erts: Support custom salt in enif_hash --- erts/emulator/beam/erl_nif.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'erts/emulator/beam/erl_nif.c') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 3470cf3fd5..bdfb7f3b8e 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1214,7 +1214,7 @@ int enif_compare(Eterm lhs, Eterm rhs) return result; } -unsigned long enif_hash(ErlNifHash type, Eterm term) +unsigned long enif_hash(ErlNifHash type, Eterm term, unsigned long salt) { #if SIZEOF_LONG < 4 /* This *really* shouldn't happen */ @@ -1222,9 +1222,9 @@ unsigned long enif_hash(ErlNifHash type, Eterm term) #endif switch (type) { case ERL_NIF_INTERNAL_HASH: - return make_internal_hash(term); + return make_internal_hash(term, salt); case ERL_NIF_PHASH2: - return make_hash2(term) & ((1 << 27) - 1); + return make_hash2(term, salt) & ((1 << 27) - 1); default: return 0; } -- cgit v1.2.3 From da9abd24a93ae8fe174cdd38fc9699bbc45fdf56 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Sat, 22 Apr 2017 20:00:28 +0100 Subject: erts: Allow for easier future enif_hash expansion Allow for expanding support to 64-bit hashes without breaking the interface. --- erts/emulator/beam/erl_nif.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'erts/emulator/beam/erl_nif.c') 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; } -- cgit v1.2.3 From 3d6b8e7fb68543713f1620a45b8a590ef4ed88a5 Mon Sep 17 00:00:00 2001 From: Guilherme Andrade Date: Mon, 24 Apr 2017 22:51:49 +0100 Subject: erts: Discontinue salted use of enif_hash/phash2 --- erts/emulator/beam/erl_nif.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'erts/emulator/beam/erl_nif.c') diff --git a/erts/emulator/beam/erl_nif.c b/erts/emulator/beam/erl_nif.c index 3ff6c8d3ed..e101747011 100644 --- a/erts/emulator/beam/erl_nif.c +++ b/erts/emulator/beam/erl_nif.c @@ -1220,7 +1220,11 @@ ErlNifUInt64 enif_hash(ErlNifHash type, Eterm term, ErlNifUInt64 salt) case ERL_NIF_INTERNAL_HASH: return make_internal_hash(term, (Uint32) salt); case ERL_NIF_PHASH2: - return make_hash2(term, (Uint32) salt) & ((1 << 27) - 1); + /* It appears that make_hash2 doesn't always react to seasoning + * as well as it should. Therefore, let's make it ignore the salt + * value and declare salted uses of phash2 as unsupported. + */ + return make_hash2(term) & ((1 << 27) - 1); default: return 0; } -- cgit v1.2.3