Skip to content

Commit 725812a

Browse files
author
wulei
committed
refactor code
1 parent ff627a5 commit 725812a

File tree

5 files changed

+106
-64
lines changed

5 files changed

+106
-64
lines changed

c_src/elmdb_nif.c

Lines changed: 35 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -304,29 +304,30 @@ typedef struct my_key_s {
304304
};
305305
} my_key_t;
306306

307-
static bool get_mykey_from(ErlNifEnv *env, const ERL_NIF_TERM kt, my_key_t *mykey) {
308-
switch (enif_term_type(env, kt)) {
309-
case ERL_NIF_TERM_TYPE_BITSTRING:
310-
if (!enif_inspect_binary(env, kt, &mykey->keyBin)) {
311-
return false;
312-
}
313-
mykey->key.mv_size = mykey->keyBin.size;
314-
mykey->key.mv_data = mykey->keyBin.data;
315-
return true;
316-
case ERL_NIF_TERM_TYPE_INTEGER:
317-
if (!enif_get_int64(env, kt, (ErlNifSInt64*)&mykey->keyInt)) {
318-
return false;
319-
}
320-
mykey->key.mv_size = sizeof(ErlNifSInt64);
321-
mykey->key.mv_data = &mykey->keyInt;
322-
mykey->type = MDB_INTEGERKEY;
323-
return true;
324-
default:
325-
ERR_LOG("unknow key type, only support int & string");
326-
return false;
307+
#define CHECKOUT_MYKEY(kt, mykey, label) \
308+
switch (enif_term_type(env, kt)) { \
309+
case ERL_NIF_TERM_TYPE_BITSTRING: \
310+
if (!enif_inspect_binary(env, kt, &mykey.keyBin)) { \
311+
break; \
312+
} \
313+
mykey.key.mv_size = mykey.keyBin.size; \
314+
mykey.key.mv_data = mykey.keyBin.data; \
315+
mykey.type = 0; \
316+
break; \
317+
case ERL_NIF_TERM_TYPE_INTEGER: \
318+
if (!enif_get_int64(env, kt, (ErlNifSInt64*)&mykey.keyInt)) {\
319+
break; \
320+
} \
321+
mykey.key.mv_size = sizeof(ErlNifSInt64); \
322+
mykey.key.mv_data = &mykey.keyInt; \
323+
mykey.type = MDB_INTEGERKEY; \
324+
break; \
325+
default: \
326+
ERR_LOG("unknow key type, only support int & string"); \
327+
err = enif_make_badarg(env); \
328+
goto label; \
327329
}
328330

329-
}
330331

331332
static ERL_NIF_TERM elmdb_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[]) {
332333
__UNUSED(argc);
@@ -344,18 +345,16 @@ static ERL_NIF_TERM elmdb_put(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
344345
return enif_make_badarg(env);
345346
}
346347

348+
ERL_NIF_TERM err;
347349
my_key_t mykey = { };
348-
if (!get_mykey_from(env, laykey[1], &mykey)) {
349-
return enif_make_badarg(env);
350-
}
350+
CHECKOUT_MYKEY(laykey[1], mykey, err3);
351351

352352
ErlNifBinary valTerm;
353353
if (!enif_inspect_binary(env, argv[2], &valTerm)) {
354354
return enif_make_badarg(env);
355355
}
356356

357357
int ret;
358-
ERL_NIF_TERM err;
359358

360359
MDB_txn *txn = NULL;
361360
CHECK(mdb_txn_begin(handle->env, NULL, 0, &txn), err2);
@@ -431,10 +430,9 @@ static ERL_NIF_TERM elmdb_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
431430
return enif_make_badarg(env);
432431
}
433432

433+
ERL_NIF_TERM err;
434434
my_key_t mykey = { };
435-
if (!get_mykey_from(env, laykey[1], &mykey)) {
436-
return enif_make_badarg(env);
437-
}
435+
CHECKOUT_MYKEY(laykey[1], mykey, err2);
438436

439437
char dbname[SUBDB_NAME_SZ] = {0};
440438
memcpy(dbname, layBin.data, layBin.size);
@@ -448,16 +446,12 @@ static ERL_NIF_TERM elmdb_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
448446
}
449447

450448
int ret;
451-
ERL_NIF_TERM err;
452449

453450
MDB_txn *txn = NULL;
454451
CHECK(mdb_txn_begin(handle->env, NULL, MDB_RDONLY, &txn), err2);
455452
MDB_dbi dbi;
456453
CHECK(mdb_dbi_open(txn, dbname, 0, &dbi), err1);
457454

458-
unsigned int ff = 0;
459-
CHECK(mdb_dbi_flags(txn, dbi, &ff), err1);
460-
461455
MDB_val val;
462456
CHECK( mdb_get(txn, dbi, &mykey.key, &val), err1);
463457
mdb_txn_abort(txn);
@@ -559,13 +553,16 @@ static ERL_NIF_TERM elmdb_del(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
559553
return enif_make_badarg(env);
560554
}
561555
ErlNifBinary layBin;
562-
ErlNifBinary keyBin;
563556
if (arity != 2 ||
564-
!enif_inspect_iolist_as_binary(env, laykey[0], &layBin) ||
565-
!enif_inspect_binary(env, laykey[1], &keyBin)) {
557+
!enif_inspect_iolist_as_binary(env, laykey[0], &layBin)) {
566558
return enif_make_badarg(env);
567559
}
568560

561+
ERL_NIF_TERM err;
562+
563+
my_key_t mykey = { };
564+
CHECKOUT_MYKEY(laykey[1], mykey, err2);
565+
569566
char dbname[SUBDB_NAME_SZ] = {0};
570567
memcpy(dbname, layBin.data, layBin.size);
571568
enif_rwlock_rlock(handle->layers_rwlock);
@@ -577,18 +574,14 @@ static ERL_NIF_TERM elmdb_del(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[
577574
}
578575

579576
int ret;
580-
ERL_NIF_TERM err;
581577

582578
MDB_txn *txn = NULL;
583579
CHECK(mdb_txn_begin(handle->env, NULL, 0, &txn), err2);
584580
MDB_dbi dbi;
585581
CHECK(mdb_dbi_open(txn, dbname, 0, &dbi), err1);
586582
DBG("open dbi: %d", dbi);
587583

588-
MDB_val key;
589-
key.mv_size = keyBin.size;
590-
key.mv_data = keyBin.data;
591-
CHECK( mdb_del(txn, dbi, &key, NULL), err1);
584+
CHECK( mdb_del(txn, dbi, &mykey.key, NULL), err1);
592585
mdb_txn_commit(txn);
593586
return argv[0];
594587

@@ -652,20 +645,14 @@ static ERL_NIF_TERM elmdb_range(ErlNifEnv* env, int argc, const ERL_NIF_TERM arg
652645
MDB_val val;
653646

654647
my_key_t mykey = { };
655-
if (!get_mykey_from(env, argv[2], &mykey)) {
656-
err = enif_raise_exception(env, enif_make_string(env, "cannot extract key", ERL_NIF_LATIN1));
657-
goto err1;
658-
}
648+
CHECKOUT_MYKEY(argv[2], mykey, err1);
659649
MDB_val iterkey;
660650
iterkey.mv_data = mykey.key.mv_data;
661651
iterkey.mv_size = mykey.key.mv_size;
662652

663653
my_key_t endkey = { };
664654
if (argc == 4) {
665-
if (!get_mykey_from(env, argv[3], &endkey)) {
666-
err = enif_raise_exception(env, enif_make_string(env, "cannot extract key", ERL_NIF_LATIN1));
667-
goto err1;
668-
}
655+
CHECKOUT_MYKEY(argv[3], endkey, err1);
669656
}
670657
else {
671658
CHECK(mdb_cursor_get(cur, &endkey.key, NULL, MDB_LAST), err1);

src/elmdb.erl

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -81,10 +81,11 @@ count(_LmdbRes, _Layer) ->
8181
put(_LmdbRes, {_Layer,_Key}, _Value) ->
8282
erlang:nif_error({not_loaded, ?MODULE}).
8383

84-
-spec get(reference(), {string(), binary()}) -> binary().
84+
-spec get(reference(), {string(), binary()|integer()}) -> binary().
8585
get(_LmdbRes, {_Layer,_Key}) ->
8686
erlang:nif_error({not_loaded, ?MODULE}).
8787

88+
-spec del(reference(), {string(), binary()|integer()}) -> reference().
8889
del(_LmdbRes, {_Layer,_Key}) ->
8990
erlang:nif_error({not_loaded, ?MODULE}).
9091

@@ -98,15 +99,13 @@ ls(_LmdbRes) ->
9899
erlang:nif_error({not_loaded, ?MODULE}).
99100

100101
foldl(LmdbRes, Layer, Acc0, Fun) ->
101-
io:format(user, "LAYER=~ts, by~p~n", [Layer, self()]),
102102
LFun = fun({Key, Value}, Acc) ->
103103
Fun({{Layer, Key}, Value}, Acc)
104104
end,
105105
Cursor = iter(LmdbRes, Layer),
106106
travel(next(Cursor), Cursor, Acc0, LFun).
107107

108108
travel(end_of_table, Cursor, Acc, _Fun) ->
109-
io:format(user, "MUST close cursor here, but NOT, TODO ~w~n", [end_of_table]),
110109
close_iter(Cursor),
111110
Acc;
112111
travel({Key, Value}, Cursor, Acc, Fun) ->

test/elmdb_empty_test.erl

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@ startup() ->
77
?debugFmt("startup.......... @dir=~ts", [Dir]),
88
filelib:ensure_dir(Dir),
99
D = elmdb:open(Dir),
10+
elmdb:put(D, {"accum-str", <<"123">>}, <<1:32/integer>>),
11+
elmdb:del(D, {"accum-str", <<"123">>}),
12+
elmdb:put(D, {"accum-int", 123}, <<1:32/integer>>),
13+
elmdb:del(D, {"accum-int", 123}),
1014
D.
1115

1216
teardown(D) ->
@@ -17,11 +21,25 @@ teardown(D) ->
1721

1822
count_db(D) ->
1923
?debugMsg("count......"),
20-
[?_assertEqual(0, lists:sum([elmdb:count(D, L) || L <- elmdb:ls(D)])),
21-
?_assertEqual(0, elmdb:count(D, "nonsense"))].
24+
?assertEqual(0, lists:sum([elmdb:count(D, L) || L <- elmdb:ls(D)])),
25+
?assertEqual(0, elmdb:count(D, "nonsense")).
26+
27+
fold_db(D) ->
28+
?debugFmt("fold_normal_db........~w", [D]),
29+
Fn = fun({K,V}, Acc) ->
30+
?debugFmt("K = ~p",[K]),
31+
<<I:32/integer>> = V,
32+
I + Acc end,
33+
?debugFmt("Fn ~w~n", [Fn]),
34+
%Res = elmdb:foldl(D, Layer, 0, Fn),
35+
?debugMsg("after fold!"),
36+
%?_assertEqual(6, Res).
37+
?assertEqual(0, elmdb:foldl(D, "accum-str", 0, Fn)),
38+
?assertEqual(0, elmdb:foldl(D, "accum-int", 0, Fn)).
2239

2340
empty_test(D) ->
24-
[count_db(D)
41+
[?_test(count_db(D)),
42+
?_test(fold_db(D))
2543
].
2644

2745
empty_test_() ->

test/elmdb_foldl_test.erl

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,32 @@ teardown(D) ->
1818
ok.
1919

2020
fold_db(D) ->
21-
{inorder,
21+
{inparallel,
2222
[?_test(fold_normal_db(D))
23-
, ?_test(fold_empty_db(D))
23+
, ?_test(fold_intkey_db(D))
2424
]
2525
}
2626
.
2727

28+
fold_intkey_db(D) ->
29+
?debugFmt("fold_intkey_db........~w", [D]),
30+
Layer = "accum-intkey",
31+
I1 = <<1:32/integer>>,
32+
I2 = <<2:32/integer>>,
33+
I3 = <<3:32/integer>>,
34+
elmdb:put(D, {Layer, 1}, I1),
35+
elmdb:put(D, {Layer, 2}, I2),
36+
elmdb:put(D, {Layer, 3}, I3),
37+
Fn = fun({K,V}, Acc) ->
38+
?debugFmt("K = ~p",[K]),
39+
<<I:32/integer>> = V,
40+
I + Acc end,
41+
?debugFmt("Fn ~w~n", [Fn]),
42+
%Res = elmdb:foldl(D, Layer, 0, Fn),
43+
?debugMsg("after fold!"),
44+
%?_assertEqual(6, Res).
45+
?assertEqual(6, elmdb:foldl(D, Layer, 0, Fn)).
46+
2847
fold_normal_db(D) ->
2948
?debugFmt("fold_normal_db........~w", [D]),
3049
Layer = "accum",
@@ -44,14 +63,6 @@ fold_normal_db(D) ->
4463
%?_assertEqual(6, Res).
4564
?assertEqual(6, elmdb:foldl(D, Layer, 0, Fn)).
4665

47-
fold_empty_db(D) ->
48-
?debugFmt("fold_empty_db........~w, by ~p~n", [D, self()]),
49-
[elmdb:drop(D, L) || L <- elmdb:ls(D)],
50-
?debugFmt("drop all... by ~p~n", [self()]),
51-
%Cnt = lists:sum(elmdb:ls(D)),
52-
%?_assertEqual(0, Cnt).
53-
?assertEqual(0, lists:sum(elmdb:ls(D))).
54-
5566
travel_test_() ->
5667
[{"Try to foldl all elements",
5768
{setup, fun startup/0, fun teardown/1, fun fold_db/1}}].

test/elmdb_prop_test.erl

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
-module(elmdb_prop_test).
2+
3+
-export([prop_em/0]).
4+
5+
-include_lib("proper/include/proper.hrl").
6+
7+
prop_em() ->
8+
Dir = "./mytestdb2/",
9+
filelib:ensure_dir(Dir),
10+
D = elmdb:open(Dir),
11+
Layer = "my-intkey",
12+
?FORALL(L, list(non_neg_integer()),
13+
begin
14+
lists:foreach(fun(I) ->
15+
elmdb:put(D, {Layer, I}, <<I:160/integer>>)
16+
end,
17+
L),
18+
Res = lists:map(fun(I) ->
19+
<<I:160/integer>> = elmdb:get(D, {Layer, I}),
20+
I
21+
end,
22+
L),
23+
Res == L
24+
end).
25+
26+
27+

0 commit comments

Comments
 (0)