Return-Path: X-Original-To: apmail-couchdb-commits-archive@www.apache.org Delivered-To: apmail-couchdb-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 15E661857E for ; Thu, 16 Jul 2015 22:36:25 +0000 (UTC) Received: (qmail 54151 invoked by uid 500); 16 Jul 2015 22:36:25 -0000 Delivered-To: apmail-couchdb-commits-archive@couchdb.apache.org Received: (qmail 54099 invoked by uid 500); 16 Jul 2015 22:36:24 -0000 Mailing-List: contact commits-help@couchdb.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@couchdb.apache.org Delivered-To: mailing list commits@couchdb.apache.org Received: (qmail 54090 invoked by uid 99); 16 Jul 2015 22:36:24 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Thu, 16 Jul 2015 22:36:24 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 8EDBFE3CA8; Thu, 16 Jul 2015 22:36:24 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: rnewson@apache.org To: commits@couchdb.apache.org Message-Id: <39a03f4f9f644e1eab3fb61398236b54@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: couchdb-khash git commit: Remove the use of make_hash2 Date: Thu, 16 Jul 2015 22:36:24 +0000 (UTC) Repository: couchdb-khash Updated Branches: refs/heads/master 6938d72be -> 265475d17 Remove the use of make_hash2 We were being rather naughty relying on the ability to resolve symbols in the executable that loads the NIF. Apparently Windows has a much different NIF loading system which prevents this from working. Given that the patch for exposing enif_phash was never merged we're solving the issue by removing the need from hashing terms in the NIF. This new approach simply hashes the term in Erlang and passes the calculated value in the NIF call. We then just store the calculated value along with the key and value as before. COUCHDB-2750 Project: http://git-wip-us.apache.org/repos/asf/couchdb-khash/repo Commit: http://git-wip-us.apache.org/repos/asf/couchdb-khash/commit/265475d1 Tree: http://git-wip-us.apache.org/repos/asf/couchdb-khash/tree/265475d1 Diff: http://git-wip-us.apache.org/repos/asf/couchdb-khash/diff/265475d1 Branch: refs/heads/master Commit: 265475d175ec9df76a2ed6ddce21184f6f83bf6e Parents: 6938d72 Author: Paul J. Davis Authored: Tue Jul 14 01:08:26 2015 -0500 Committer: Robert Newson Committed: Thu Jul 16 23:34:40 2015 +0100 ---------------------------------------------------------------------- c_src/khash.c | 72 ++++++++++++++++++++++++++++++++---------------------- src/khash.erl | 32 ++++++++++++++++++------ 2 files changed, 67 insertions(+), 37 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/couchdb-khash/blob/265475d1/c_src/khash.c ---------------------------------------------------------------------- diff --git a/c_src/khash.c b/c_src/khash.c index a2364b0..8081c3b 100644 --- a/c_src/khash.c +++ b/c_src/khash.c @@ -4,6 +4,7 @@ #include #include +#include #include "erl_nif.h" #include "hash.h" @@ -27,6 +28,7 @@ typedef struct typedef struct { + unsigned int hval; ErlNifEnv* env; ERL_NIF_TERM key; ERL_NIF_TERM val; @@ -51,13 +53,6 @@ typedef struct } khash_iter_t; -// This is actually an internal Erlang VM function that -// we're being a bit hacky to get access to. There's a -// pending patch to expose this in the NIF API in newer -// Erlangs. -unsigned int make_hash2(ERL_NIF_TERM term); - - static inline ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name) { @@ -145,7 +140,7 @@ hash_val_t khash_hash_fun(const void* obj) { khnode_t* node = (khnode_t*) obj; - return (hash_val_t) make_hash2(node->key); + return (hash_val_t) node->hval; } @@ -284,9 +279,10 @@ khash_clear(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) static inline hnode_t* -khash_lookup_int(ErlNifEnv* env, ERL_NIF_TERM key, khash_t* khash) +khash_lookup_int(ErlNifEnv* env, uint32_t hv, ERL_NIF_TERM key, khash_t* khash) { khnode_t node; + node.hval = hv; node.env = env; node.key = key; return kl_hash_lookup(khash->h, &node); @@ -298,12 +294,12 @@ khash_lookup(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { khash_priv* priv = enif_priv_data(env); khash_t* khash = NULL; - void* res = NULL; + uint32_t hval; hnode_t* entry; khnode_t* node; ERL_NIF_TERM ret; - if(argc != 2) { + if(argc != 3) { return enif_make_badarg(env); } @@ -317,7 +313,11 @@ khash_lookup(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); } - entry = khash_lookup_int(env, argv[1], khash); + if(!enif_get_uint(env, argv[1], &hval)) { + return enif_make_badarg(env); + } + + entry = khash_lookup_int(env, hval, argv[2], khash); if(entry == NULL) { ret = priv->atom_not_found; } else { @@ -335,12 +335,12 @@ khash_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { khash_priv* priv = enif_priv_data(env); khash_t* khash = NULL; - void* res = NULL; + uint32_t hval; hnode_t* entry; khnode_t* node; ERL_NIF_TERM ret; - if(argc != 3) { + if(argc != 4) { return enif_make_badarg(env); } @@ -354,9 +354,13 @@ khash_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); } - entry = khash_lookup_int(env, argv[1], khash); + if(!enif_get_uint(env, argv[1], &hval)) { + return enif_make_badarg(env); + } + + entry = khash_lookup_int(env, hval, argv[2], khash); if(entry == NULL) { - ret = argv[2]; + ret = argv[3]; } else { node = (khnode_t*) kl_hnode_getkey(entry); ret = enif_make_copy(env, node->val); @@ -371,11 +375,11 @@ khash_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) { khash_priv* priv = enif_priv_data(env); khash_t* khash = NULL; - void* res = NULL; + uint32_t hval; hnode_t* entry; khnode_t* node; - if(argc != 3) { + if(argc != 4) { return enif_make_badarg(env); } @@ -389,18 +393,23 @@ khash_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); } - entry = khash_lookup_int(env, argv[1], khash); + if(!enif_get_uint(env, argv[1], &hval)) { + return enif_make_badarg(env); + } + + entry = khash_lookup_int(env, hval, argv[2], khash); if(entry == NULL) { entry = khnode_alloc(NULL); node = (khnode_t*) kl_hnode_getkey(entry); - node->key = enif_make_copy(node->env, argv[1]); - node->val = enif_make_copy(node->env, argv[2]); + node->hval = hval; + node->key = enif_make_copy(node->env, argv[2]); + node->val = enif_make_copy(node->env, argv[3]); kl_hash_insert(khash->h, entry, node); } else { node = (khnode_t*) kl_hnode_getkey(entry); enif_clear_env(node->env); - node->key = enif_make_copy(node->env, argv[1]); - node->val = enif_make_copy(node->env, argv[2]); + node->key = enif_make_copy(node->env, argv[2]); + node->val = enif_make_copy(node->env, argv[3]); } khash->gen += 1; @@ -415,10 +424,11 @@ khash_del(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) khash_priv* priv = enif_priv_data(env); khash_t* khash = NULL; void* res = NULL; + uint32_t hval; hnode_t* entry; ERL_NIF_TERM ret; - if(argc != 2) { + if(argc != 3) { return enif_make_badarg(env); } @@ -432,7 +442,11 @@ khash_del(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) return enif_make_badarg(env); } - entry = khash_lookup_int(env, argv[1], khash); + if(!enif_get_uint(env, argv[1], &hval)) { + return enif_make_badarg(env); + } + + entry = khash_lookup_int(env, hval, argv[2], khash); if(entry == NULL) { ret = priv->atom_not_found; } else { @@ -623,10 +637,10 @@ static ErlNifFunc funcs[] = { {"new", 1, khash_new}, {"to_list", 1, khash_to_list}, {"clear", 1, khash_clear}, - {"lookup", 2, khash_lookup}, - {"get", 3, khash_get}, - {"put", 3, khash_put}, - {"del", 2, khash_del}, + {"lookup_int", 3, khash_lookup}, + {"get_int", 4, khash_get}, + {"put_int", 4, khash_put}, + {"del_int", 3, khash_del}, {"size", 1, khash_size}, {"iter", 1, khash_iter}, {"iter_next", 1, khash_iter_next} http://git-wip-us.apache.org/repos/asf/couchdb-khash/blob/265475d1/src/khash.erl ---------------------------------------------------------------------- diff --git a/src/khash.erl b/src/khash.erl index 7b474bd..daaf5ea 100644 --- a/src/khash.erl +++ b/src/khash.erl @@ -69,8 +69,8 @@ clear(_Hash) -> -spec lookup(khash(), any()) -> {value, any()} | not_found. -lookup(_Hash, _Key) -> - ?NOT_LOADED. +lookup(Hash, Key) -> + lookup_int(Hash, erlang:phash2(Key), Key). -spec get(khash(), any()) -> any(). @@ -79,18 +79,18 @@ get(Hash, Key) -> -spec get(khash(), any(), any()) -> any(). -get(_Hash, _Key, _Default) -> - ?NOT_LOADED. +get(Hash, Key, Default) -> + get_int(Hash, erlang:phash2(Key), Key, Default). -spec put(khash(), any(), any()) -> ok. -put(_Hash, _Key, _Value) -> - ?NOT_LOADED. +put(Hash, Key, Value) -> + put_int(Hash, erlang:phash2(Key), Key, Value). -spec del(khash(), any()) -> ok. -del(_Hash, _Key) -> - ?NOT_LOADED. +del(Hash, Key) -> + del_int(Hash, erlang:phash2(Key), Key). -spec size(khash()) -> non_neg_integer(). @@ -137,5 +137,21 @@ init() -> erlang:load_nif(filename:join(PrivDir, "khash"), 0). +lookup_int(_Hash, _HashValue, _Key) -> + ?NOT_LOADED. + + +get_int(_Hash, _HashValue, _Key, _Default) -> + ?NOT_LOADED. + + +put_int(_Hash, _HashValue, _Key, _Value) -> + ?NOT_LOADED. + + +del_int(_Hash, _HashValue, _Key) -> + ?NOT_LOADED. + + not_loaded(Line) -> erlang:nif_error({not_loaded, [{module, ?MODULE}, {line, Line}]}).