couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From kxe...@apache.org
Subject [06/43] jiffy commit: updated refs/heads/upstream to 446e284
Date Mon, 13 Jul 2015 18:45:05 GMT
Use a resource for the encoder structure

This is ground work to allow Jiffy to yield back to the scheduler.
Creating an encoder resource will allow for the necessary state to be
carried across NIF function invocations.


Project: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/commit/5ccff57a
Tree: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/tree/5ccff57a
Diff: http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/diff/5ccff57a

Branch: refs/heads/upstream
Commit: 5ccff57adec8493d72005cc9b92756f69c4e33d4
Parents: 79d24e9
Author: Paul J. Davis <paul.joseph.davis@gmail.com>
Authored: Thu Jun 12 16:58:19 2014 -0500
Committer: Paul J. Davis <paul.joseph.davis@gmail.com>
Committed: Fri Jun 13 16:56:35 2014 -0500

----------------------------------------------------------------------
 c_src/encoder.c | 113 +++++++++++++++++++++++++++++++++++----------------
 c_src/jiffy.c   |  12 +++++-
 c_src/jiffy.h   |   5 ++-
 src/jiffy.erl   |   9 ++--
 4 files changed, 100 insertions(+), 39 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/encoder.c
----------------------------------------------------------------------
diff --git a/c_src/encoder.c b/c_src/encoder.c
index c23b309..1b916b6 100644
--- a/c_src/encoder.c
+++ b/c_src/encoder.c
@@ -36,6 +36,7 @@ typedef struct {
 
     int             iolen;
     ERL_NIF_TERM    iolist;
+    ErlNifBinary    bin;
     ErlNifBinary*   curr;
 
 
@@ -60,39 +61,24 @@ static char* shifts[NUM_SHIFTS] = {
 };
 
 
-int
-enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary* bin)
+Encoder*
+enc_new(ErlNifEnv* env)
 {
-    ERL_NIF_TERM val;
+    jiffy_st* st = (jiffy_st*) enif_priv_data(env);
+    Encoder* e = enif_alloc_resource(st->res_enc, sizeof(Encoder));
 
-    e->env = env;
-    e->atoms = enif_priv_data(env);
+    e->atoms = st;
     e->uescape = 0;
     e->pretty = 0;
     e->shiftcnt = 0;
     e->count = 0;
 
-    if(!enif_is_list(env, opts)) {
-        return 0;
-    }
-
-    while(enif_get_list_cell(env, opts, &val, &opts)) {
-        if(enif_compare(val, e->atoms->atom_uescape) == 0) {
-            e->uescape = 1;
-        } else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
-            e->pretty = 1;
-        } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) {
-            // Ignore, handled in Erlang
-        } else {
-            return 0;
-        }
-    }
-
     e->iolen = 0;
-    e->iolist = enif_make_list(env, 0);
-    e->curr = bin;
+    e->curr = &(e->bin);
     if(!enif_alloc_binary(BIN_INC_SIZE, e->curr)) {
-        return 0;
+        e->curr = NULL;
+        enif_release_resource(e);
+        return NULL;
     }
 
     memset(e->curr->data, 0, e->curr->size);
@@ -101,12 +87,21 @@ enc_init(Encoder* e, ErlNifEnv* env, ERL_NIF_TERM opts, ErlNifBinary*
bin)
     e->u = (unsigned char*) e->curr->data;
     e->i = 0;
 
+    return e;
+}
+
+int
+enc_init(Encoder* e, ErlNifEnv* env)
+{
+    e->env = env;
     return 1;
 }
 
 void
-enc_destroy(Encoder* e)
+enc_destroy(ErlNifEnv* env, void* obj)
 {
+    Encoder* e = (Encoder*) obj;
+
     if(e->curr != NULL) {
         enif_release_binary(e->curr);
     }
@@ -494,13 +489,57 @@ enc_comma(Encoder* e)
 }
 
 ERL_NIF_TERM
-encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
 {
-    Encoder enc;
-    Encoder* e = &enc;
+    jiffy_st* st = (jiffy_st*) enif_priv_data(env);
+    Encoder* e;
 
-    ErlNifBinary bin;
-    ERL_NIF_TERM ret;
+    ERL_NIF_TERM opts;
+    ERL_NIF_TERM val;
+    ERL_NIF_TERM tmp_argv[3];
+
+    if(argc != 2) {
+        return enif_make_badarg(env);
+    }
+
+    e = enc_new(env);
+    if(e == NULL) {
+        return make_error(st, env, "internal_error");
+    }
+
+    tmp_argv[0] = enif_make_resource(env, e);
+    tmp_argv[1] = enif_make_list(env, 1, argv[0]);
+    tmp_argv[2] = enif_make_list(env, 0);
+
+    enif_release_resource(e);
+
+    opts = argv[1];
+    if(!enif_is_list(env, opts)) {
+        return enif_make_badarg(env);
+    }
+
+    while(enif_get_list_cell(env, opts, &val, &opts)) {
+        if(enif_compare(val, e->atoms->atom_uescape) == 0) {
+            e->uescape = 1;
+        } else if(enif_compare(val, e->atoms->atom_pretty) == 0) {
+            e->pretty = 1;
+        } else if(enif_compare(val, e->atoms->atom_force_utf8) == 0) {
+            // Ignore, handled in Erlang
+        } else {
+            return enif_make_badarg(env);
+        }
+    }
+
+    return encode_iter(env, 3, tmp_argv);
+}
+
+ERL_NIF_TERM
+encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
+{
+    Encoder* e;
+    jiffy_st* st = (jiffy_st*) enif_priv_data(env);
+
+    ERL_NIF_TERM ret = 0;
 
     ERL_NIF_TERM stack;
     ERL_NIF_TERM curr;
@@ -510,15 +549,22 @@ encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     ErlNifSInt64 lval;
     double dval;
 
-    if(argc != 2) {
+    if(argc != 3) {
+        return enif_make_badarg(env);
+    } else if(!enif_get_resource(env, argv[0], st->res_enc, (void**) &e)) {
+        return enif_make_badarg(env);
+    } else if(!enif_is_list(env, argv[1])) {
+        return enif_make_badarg(env);
+    } else if(!enif_is_list(env, argv[2])) {
         return enif_make_badarg(env);
     }
 
-    if(!enc_init(e, env, argv[1], &bin)) {
+    if(!enc_init(e, env)) {
         return enif_make_badarg(env);
     }
 
-    stack = enif_make_list(env, 1, argv[0]);
+    stack = argv[1];
+    e->iolist = argv[2];
 
     while(!enif_is_empty_list(env, stack)) {
         if(!enif_get_list_cell(env, stack, &curr, &stack)) {
@@ -704,6 +750,5 @@ encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
     }
 
 done:
-    enc_destroy(e);
     return ret;
 }

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/jiffy.c
----------------------------------------------------------------------
diff --git a/c_src/jiffy.c b/c_src/jiffy.c
index e0c1f20..0d84dcf 100644
--- a/c_src/jiffy.c
+++ b/c_src/jiffy.c
@@ -37,6 +37,15 @@ load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info)
             NULL
         );
 
+    st->res_enc = enif_open_resource_type(
+            env,
+            NULL,
+            "encoder",
+            enc_destroy,
+            ERL_NIF_RT_CREATE | ERL_NIF_RT_TAKEOVER,
+            NULL
+        );
+
     *priv = (void*) st;
 
     return 0;
@@ -65,7 +74,8 @@ static ErlNifFunc funcs[] =
 {
     {"nif_decode_init", 1, decode_init},
     {"nif_decode_iter", 4, decode_iter},
-    {"nif_encode", 2, encode}
+    {"nif_encode_init", 2, encode_init},
+    {"nif_encode_iter", 3, encode_iter}
 };
 
 ERL_NIF_INIT(jiffy, funcs, &load, &reload, &upgrade, &unload);

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/c_src/jiffy.h
----------------------------------------------------------------------
diff --git a/c_src/jiffy.h b/c_src/jiffy.h
index bfd5940..97863be 100644
--- a/c_src/jiffy.h
+++ b/c_src/jiffy.h
@@ -24,6 +24,7 @@ typedef struct {
     ERL_NIF_TERM    ref_array;
 
     ErlNifResourceType* res_dec;
+    ErlNifResourceType* res_enc;
 } jiffy_st;
 
 ERL_NIF_TERM make_atom(ErlNifEnv* env, const char* name);
@@ -32,9 +33,11 @@ ERL_NIF_TERM make_error(jiffy_st* st, ErlNifEnv* env, const char* error);
 
 ERL_NIF_TERM decode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 ERL_NIF_TERM decode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
-ERL_NIF_TERM encode(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM encode_init(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
+ERL_NIF_TERM encode_iter(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]);
 
 void dec_destroy(ErlNifEnv* env, void* obj);
+void enc_destroy(ErlNifEnv* env, void* obj);
 
 int int_from_hex(const unsigned char* p);
 int int_to_hex(int val, char* p);

http://git-wip-us.apache.org/repos/asf/couchdb-jiffy/blob/5ccff57a/src/jiffy.erl
----------------------------------------------------------------------
diff --git a/src/jiffy.erl b/src/jiffy.erl
index c9e65e4..cc756ba 100644
--- a/src/jiffy.erl
+++ b/src/jiffy.erl
@@ -26,7 +26,7 @@ encode(Data) ->
 
 encode(Data, Options) ->
     ForceUTF8 = lists:member(force_utf8, Options),
-    case nif_encode(Data, Options) of
+    case nif_encode_init(Data, Options) of
         {error, invalid_string} when ForceUTF8 == true ->
             FixedData = jiffy_utf8:fix(Data),
             encode(FixedData, Options -- [force_utf8]);
@@ -106,6 +106,9 @@ nif_decode_init(_Data) ->
 nif_decode_iter(_Data, _Decoder, _, _) ->
     ?NOT_LOADED.
 
-nif_encode(_Data, _Options) ->
-    ?NOT_LOADED.
+nif_encode_init(_Data, _Options) ->
+    ?NOT_LOADED,
+    nif_encode_iter(x, y, z).
 
+nif_encode_iter(_Encoder, _Stack, _IoList) ->
+    ?NOT_LOADED.
\ No newline at end of file


Mime
View raw message