示例#1
0
static ERL_NIF_TERM elibart_insert(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key, value;
    art_elem_struct *elem;
    unsigned char buffer[BUFF_SIZE]; // 256Kb buffer
    unsigned char *key_copy = buffer;


    // extract arguments atr_tree, key, value
    if (argc != 3)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[2], &value))
        return enif_make_badarg(env);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        key_copy = malloc(key.size + 1);

    // TODO review -- is it possible not to copy the key just to add '\0'?
    memcpy(key_copy, key.data, key.size);
    key_copy[key.size] = '\0';

    //create art element
    elem = malloc(sizeof(art_elem_struct));

    if (elem == NULL)
        mk_error(env, "malloc_no_mem");

    elem->data = malloc(value.size);
    elem->size = value.size;
    memcpy(elem->data, value.data, value.size);

    // insert the element in the art_tree
    art_elem_struct *old_elem = art_insert(t, key_copy, key.size + 1, elem);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        free(key_copy);

    // the inserted key is new
    if (!old_elem) 
        return enif_make_tuple2(env, mk_atom(env, "ok"), mk_atom(env, "empty"));

    // the inserted key already existed, return previous value
    ErlNifBinary res;
    enif_alloc_binary(old_elem->size, &res);
    memcpy(res.data, old_elem->data, old_elem->size);

    free(old_elem->data);
    free(old_elem);

    return enif_make_tuple2(env, enif_make_atom(env, "ok"), enif_make_binary(env, &res));
}
示例#2
0
static ERL_NIF_TERM
ex_has_colors(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    if (argc != 0 )
        return enif_make_badarg(env);

    if (has_colors())
        return mk_atom(env, "true");
    else
        return mk_atom(env, "false");
}
示例#3
0
static ERL_NIF_TERM
same_term(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    assert(argc == 2 && "same_term is a 2-arity function.");
    if(enif_is_identical(argv[0], argv[1]))
    {
        return mk_atom(env, "true");
    }
    else
    {
        return  mk_atom(env, "false");
    }
}
示例#4
0
static ERL_NIF_TERM elibart_prefix_search(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key;
    callback_data cb_data;

    // extract arguments atr_tree, key
    if (argc != 4)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);

    cb_data.env = env;
    if(!enif_is_pid(env, argv[3]))
        return mk_error(env, "not_a_pid");

    if(!enif_get_local_pid(env, argv[3], &cb_data.pid))
        return mk_error(env, "not_a_local_pid");

    cb_data.caller_ref = argv[2];
   
    // TODO this should be a worker thread since it's a long opearation (?)
    if (art_iter_prefix(t, key.data, key.size, prefix_cb, &cb_data))
        return mk_error(env, "art_prefix_search");

    ErlNifEnv *msg_env = enif_alloc_env();

    if(msg_env == NULL)
        return mk_error(env, "env_alloc_error");;

    ERL_NIF_TERM caller_ref = enif_make_copy(msg_env, argv[2]);
    ERL_NIF_TERM res = enif_make_tuple2(msg_env, caller_ref, mk_atom(msg_env, "ok"));

    if (!enif_send(env, &cb_data.pid, msg_env, res))
    {
        enif_free(msg_env);

        return mk_error(env, "art_prefix_search");
    }

    enif_free(msg_env);

    return mk_atom(env, "ok");
}
示例#5
0
static ERL_NIF_TERM
cmp(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
{
    assert(argc == 2 && "cmp is a 2-arity function.");
    int c = enif_compare(argv[0], argv[1]);
    if(c < 0)
    {
        return mk_atom(env, "lesser");
    }
    else if(c == 0)
    {
        return mk_atom(env, "equal");
    }
    else
    {
        return mk_atom(env, "greater");
    }
}
示例#6
0
static ERL_NIF_TERM elibart_search(ErlNifEnv* env, int argc,
                                          const ERL_NIF_TERM argv[])
{
    art_tree* t;
    ErlNifBinary key;
    unsigned char buffer[BUFF_SIZE]; // 256K buffer
    unsigned char *key_copy = buffer;
    
    // extract arguments atr_tree, key
    if(argc != 2)
      return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);
    if (!enif_inspect_binary(env, argv[1], &key))
        return enif_make_badarg(env);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        key_copy = malloc(key.size + 1);

    // TODO review -- is it possible not to copy the key just to add '\0'?
    memcpy(key_copy, key.data, key.size);
    key_copy[key.size] = '\0';

    // search the art_tree for the given key
    art_elem_struct *value = art_search(t, key_copy, key.size + 1);

    // buffer size not enough, pay the price
    if (key.size > BUFF_SIZE)
        free(key_copy);

    // key does not exist in the art_tree
    if (!value)
        return mk_atom(env, "empty");

    // key exixts, return the associated value
    ErlNifBinary res;
    enif_alloc_binary(value->size, &res);
    memcpy(res.data, value->data, value->size);

    return enif_make_tuple2(env, mk_atom(env, "ok"), enif_make_binary(env, &res));
}
示例#7
0
static ERL_NIF_TERM
done(ErlNifEnv* env, int code)
{
    if(code == OK)
    {
        return mk_atom(env, "ok");
    }
    else
    {
        return enif_make_tuple2(env,
                                enif_make_atom(env, "error"),
                                enif_make_int(env, code));
    }
}
示例#8
0
文件: alm_main.c 项目: garazdawi/alm
int parse_args(char** cmdline, ATERM *funcname, ATERM *args,int *arg_len) {
  char *str;
  int arg;
  *arg_len = 0;
  CHK((str = strsep(cmdline,"(")) == NULL);
  mk_atom(*funcname,str,strlen(str));

  while (*arg_len < 10 &&
	  (str = strsep(cmdline, ",)")) != NULL) {
    sscanf(str,"%d",&arg);
    *(args+*arg_len) = mk_num((double)arg);
    (*arg_len)++;
  }
  return 0;
}
示例#9
0
static ERL_NIF_TERM elibart_new(ErlNifEnv* env, int argc,
                                   const ERL_NIF_TERM argv[])
{
    art_tree* t = enif_alloc_resource(elibart_RESOURCE,
                                                    sizeof(art_tree));
    
    if (init_art_tree(t) != 0)
        return mk_error(env, "init_art_tree");
    else 
    {
        ERL_NIF_TERM res = enif_make_resource(env, t);
        enif_release_resource(t);
    
        return enif_make_tuple2(env, mk_atom(env, "ok"), res);
    }
}
示例#10
0
static ERL_NIF_TERM elibart_destroy(ErlNifEnv* env, int argc,
                                   const ERL_NIF_TERM argv[])
{
    art_tree *t;

    if (argc != 1)
        return enif_make_badarg(env);
    if(!enif_get_resource(env, argv[0], elibart_RESOURCE, (void**) &t))
        return enif_make_badarg(env);

    art_iter(t, delete_cb, NULL);

    if (destroy_art_tree((art_tree*) argv[0]) != 0)
        return mk_error(env, "destroy_art_tree");

    return mk_atom(env, "ok");
}
示例#11
0
ERL_NIF_TERM
mk_error(ErlNifEnv* env, const char* mesg)
{
    return enif_make_tuple(env, mk_atom(env, "error"), mk_atom(env, mesg));
}