Skip to content

Commit

Permalink
feat: add the missing API fdb_transaction_get_range_split_points
Browse files Browse the repository at this point in the history
  • Loading branch information
lafirest committed Nov 20, 2023
1 parent e5a3864 commit 037bd38
Show file tree
Hide file tree
Showing 6 changed files with 113 additions and 3 deletions.
3 changes: 1 addition & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,7 @@ jobs:
runs-on: ubuntu-latest
strategy:
matrix:
#test-name: [api, directory, directory_hca, tuple]
test-name: [api]
test-name: [api, directory, directory_hca, tuple]
api-version: [710]
container:
image: ghcr.io/emqx/couchdb-erlfdb:erlang-25-fdb-7.1.43
Expand Down
87 changes: 87 additions & 0 deletions c_src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,34 @@ erlfdb_future_get_int64(ErlNifEnv* env, ErlFDBFuture* f)
return enif_make_int64(env, nif_res);
}

static inline ERL_NIF_TERM
erlfdb_future_get_key_array(ErlNifEnv* env, ErlFDBFuture* f)
{
const FDBKey* keys;
int count;
unsigned char* buf;
ERL_NIF_TERM bin;
ERL_NIF_TERM ret;
fdb_error_t err;
int i;

err = fdb_future_get_key_array(f->future, &keys, &count);
if(err != 0) {
return erlfdb_erlang_error(env, err);
}

ret = enif_make_list(env, 0);

for(i = count - 1; i >= 0; i--) {
const FDBKey key = keys[i];
buf = enif_make_new_binary(env, key.key_length, &bin);
memcpy(buf, key.key, key.key_length);
ret = enif_make_list_cell(env, bin, ret);
}

return ret;
}


static inline ERL_NIF_TERM
erlfdb_future_get_key(ErlNifEnv* env, ErlFDBFuture* f)
Expand Down Expand Up @@ -660,6 +688,8 @@ erlfdb_future_get(ErlNifEnv* env, int argc, const ERL_NIF_TERM argv[])
return erlfdb_future_get_string_array(env, f);
} else if(f->ftype == ErlFDB_FT_KEYVALUE_ARRAY) {
return erlfdb_future_get_keyvalue_array(env, f);
} else if(f->ftype == ErlFDB_FT_KEY_ARRAY) {
return erlfdb_future_get_key_array(env, f);
}

return enif_raise_exception(env, ATOM_invalid_future_type);
Expand Down Expand Up @@ -1139,6 +1169,62 @@ erlfdb_transaction_get_estimated_range_size(
}
#endif

static ERL_NIF_TERM
erlfdb_transaction_get_range_split_points(
ErlNifEnv* env,
int argc,
const ERL_NIF_TERM argv[]
)
{
ErlFDBSt* st = (ErlFDBSt*) enif_priv_data(env);
ErlFDBTransaction* t;
ErlNifBinary begin;
ErlNifBinary end;
int64_t chunkSize;
FDBFuture* future;
void* res;

if(st->lib_state != ErlFDB_CONNECTED) {
return enif_make_badarg(env);
}

if(argc != 4) {
return enif_make_badarg(env);
}

if(!enif_get_resource(env, argv[0], ErlFDBTransactionRes, &res)) {
return enif_make_badarg(env);
}
t = (ErlFDBTransaction*) res;

if(!erlfdb_transaction_is_owner(env, t)) {
return enif_make_badarg(env);
}

if(!enif_inspect_binary(env, argv[1], &begin)) {
return enif_make_badarg(env);
}

if(!enif_inspect_binary(env, argv[2], &end)) {
return enif_make_badarg(env);
}

if(!enif_get_int64(env, argv[3], &chunkSize)) {
return enif_make_badarg(env);
}

future = fdb_transaction_get_range_split_points(
t->transaction,
(uint8_t*) begin.data,
begin.size,
(uint8_t*) end.data,
end.size,
chunkSize
);

return erlfdb_create_future(env, future, ErlFDB_FT_KEY_ARRAY);
}

static ERL_NIF_TERM
erlfdb_transaction_get_key(
ErlNifEnv* env,
Expand Down Expand Up @@ -2210,6 +2296,7 @@ static ErlNifFunc funcs[] =
NIF_FUNC(erlfdb_transaction_set_read_version, 2),
NIF_FUNC(erlfdb_transaction_get_read_version, 1),
NIF_FUNC(erlfdb_transaction_get, 3),
NIF_FUNC(erlfdb_transaction_get_range_split_points, 4),
NIF_FUNC(erlfdb_transaction_get_key, 3),
NIF_FUNC(erlfdb_transaction_get_addresses_for_key, 2),
NIF_FUNC(erlfdb_transaction_get_range, 9),
Expand Down
3 changes: 2 additions & 1 deletion c_src/resources.h
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,8 @@ typedef enum _ErlFDBFutureType
ErlFDB_FT_KEY,
ErlFDB_FT_VALUE,
ErlFDB_FT_STRING_ARRAY,
ErlFDB_FT_KEYVALUE_ARRAY
ErlFDB_FT_KEYVALUE_ARRAY,
ErlFDB_FT_KEY_ARRAY
} ErlFDBFutureType;


Expand Down
9 changes: 9 additions & 0 deletions src/erlfdb.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,8 @@
get/2,
get_ss/2,

get_range_split_points/4,

get_key/2,
get_key_ss/2,

Expand Down Expand Up @@ -296,6 +298,13 @@ get_ss(?IS_TX = Tx, Key) ->
get_ss(?IS_SS = SS, Key) ->
get_ss(?GET_TX(SS), Key).

get_range_split_points(?IS_DB = Db, BeginKey, EndKey, ChunkSize) ->
transactional(Db, fun(Tx) ->
wait(get_range_split_points(Tx, BeginKey, EndKey, ChunkSize))
end);
get_range_split_points(?IS_TX = Tx, BeginKey, EndKey, ChunkSize) ->
erlfdb_nif:transaction_get_range_split_points(Tx, BeginKey, EndKey, ChunkSize).

get_key(?IS_DB = Db, Key) ->
transactional(Db, fun(Tx) ->
wait(get_key(Tx, Key))
Expand Down
8 changes: 8 additions & 0 deletions src/erlfdb_nif.erl
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
transaction_get_read_version/1,
transaction_get/3,
transaction_get_estimated_range_size/3,
transaction_get_range_split_points/4,
transaction_get_key/3,
transaction_get_addresses_for_key/2,
transaction_get_range/9,
Expand Down Expand Up @@ -284,6 +285,11 @@ transaction_get({erlfdb_transaction, Tx}, Key, Snapshot) ->
transaction_get_estimated_range_size({erlfdb_transaction, Tx}, StartKey, EndKey) ->
erlfdb_transaction_get_estimated_range_size(Tx, StartKey, EndKey).

-spec transaction_get_range_split_points(transaction(), BeginKey :: binary(), EndKey :: binary(), ChunkSize :: non_neg_integer()) ->
future().
transaction_get_range_split_points({erlfdb_transaction, Tx}, BeginKey, EndKey, ChunkSize) ->
erlfdb_transaction_get_range_split_points(Tx, BeginKey, EndKey, ChunkSize).

-spec transaction_get_key(
transaction(),
KeySelector :: key_selector(),
Expand Down Expand Up @@ -531,6 +537,8 @@ erlfdb_transaction_set_read_version(_Transaction, _Version) -> ?NOT_LOADED.
erlfdb_transaction_get_read_version(_Transaction) -> ?NOT_LOADED.
erlfdb_transaction_get(_Transaction, _Key, _Snapshot) -> ?NOT_LOADED.
erlfdb_transaction_get_estimated_range_size(_Transaction, _SKey, _EKey) -> ?NOT_LOADED.
erlfdb_transaction_get_range_split_points(_Transaction, _BeginKey, _EndKey, _ChunkSize) ->
?NOT_LOADED.
erlfdb_transaction_get_key(_Transaction, _KeySelector, _Snapshot) -> ?NOT_LOADED.
erlfdb_transaction_get_addresses_for_key(_Transaction, _Key) -> ?NOT_LOADED.
erlfdb_transaction_get_range(
Expand Down
6 changes: 6 additions & 0 deletions test/tester.es
Original file line number Diff line number Diff line change
Expand Up @@ -779,6 +779,12 @@ execute(TxObj, #st{is_directory_op = true} = St, Op) ->
NewSt
end;

execute(TxObj, St, <<"GET_RANGE_SPLIT_POINTS">>) ->
[Start, End, ChunkSize] = stack_pop(St, 3),
Result = erlfdb:get_range_split_points(TxObj, Start, End, ChunkSize),
stack_push_range(St, Result),
St;

execute(_TxObj, _St, UnknownOp) ->
erlang:error({unknown_op, UnknownOp}).

Expand Down

0 comments on commit 037bd38

Please sign in to comment.