Skip to content
Permalink
Browse files
Add get_next_tx_id API
This API provides a transaction ID that can be used in the 12 byte
version stamps to distinguish between version stamps created in a single
transaction. There's a limit of 65,535 transaction ids afterwhich this
function starts throwing badarg exceptions.
  • Loading branch information
davisp committed May 2, 2019
1 parent 4f331fc commit 4a2c683147d47c0eac9b1e5507e7e5e6da2a21ca
Show file tree
Hide file tree
Showing 5 changed files with 81 additions and 0 deletions.
@@ -863,6 +863,7 @@ erlfdb_database_create_transaction(
enif_self(env, &pid);
t->owner = enif_make_pid(env, &pid);

t->txid = 0;
t->read_only = true;

ret = enif_make_resource(env, t);
@@ -1761,6 +1762,8 @@ erlfdb_transaction_reset(
}

fdb_transaction_reset(t->transaction);

t->txid = 0;
t->read_only = true;

return ATOM_ok;
@@ -1870,6 +1873,42 @@ erlfdb_transaction_add_conflict_range(
}


static ERL_NIF_TERM
erlfdb_transaction_get_next_tx_id(
ErlNifEnv* env,
int argc,
const ERL_NIF_TERM argv[]
)
{
ErlFDBSt* st = (ErlFDBSt*) enif_priv_data(env);
ErlFDBTransaction* t;
void* res;

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

if(argc != 1) {
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(t->txid > 65535) {
return enif_make_badarg(env);
}

return enif_make_uint(env, t->txid++);
}


static ERL_NIF_TERM
erlfdb_transaction_is_read_only(
ErlNifEnv* env,
@@ -2015,6 +2054,7 @@ static ErlNifFunc funcs[] =
NIF_FUNC(erlfdb_transaction_reset, 1),
NIF_FUNC(erlfdb_transaction_cancel, 1),
NIF_FUNC(erlfdb_transaction_add_conflict_range, 4),
NIF_FUNC(erlfdb_transaction_get_next_tx_id, 1),
NIF_FUNC(erlfdb_transaction_is_read_only, 1),

NIF_FUNC(erlfdb_get_error, 1),
@@ -66,6 +66,7 @@ typedef struct _ErlFDBTransaction
{
FDBTransaction* transaction;
ERL_NIF_TERM owner;
unsigned int txid;
bool read_only;
} ErlFDBTransaction;

@@ -102,6 +102,7 @@
get_versionstamp/1,

% Transaction status
get_next_tx_id/1,
is_read_only/1,

% Locality
@@ -580,6 +581,13 @@ get_versionstamp(?IS_SS = SS) ->
get_versionstamp(?GET_TX(SS)).


get_next_tx_id(?IS_TX = Tx) ->
erlfdb_nif:transaction_get_next_tx_id(Tx);

get_next_tx_id(?IS_SS = SS) ->
get_next_tx_id(?GET_TX(SS)).


is_read_only(?IS_TX = Tx) ->
erlfdb_nif:transaction_is_read_only(Tx);

@@ -55,6 +55,7 @@
transaction_reset/1,
transaction_cancel/1,
transaction_add_conflict_range/4,
transaction_get_next_tx_id/1,
transaction_is_read_only/1,

get_error/1,
@@ -440,6 +441,11 @@ transaction_add_conflict_range(
erlfdb_transaction_add_conflict_range(Tx, StartKey, EndKey, ConflictType).


-spec transaction_get_next_tx_id(transaction()) -> non_neg_integer().
transaction_get_next_tx_id({erlfdb_transaction, Tx}) ->
erlfdb_transaction_get_next_tx_id(Tx).


-spec transaction_is_read_only(transaction()) -> true | false.
transaction_is_read_only({erlfdb_transaction, Tx}) ->
erlfdb_transaction_is_read_only(Tx).
@@ -587,6 +593,7 @@ erlfdb_transaction_add_conflict_range(
_EndKey,
_Type
) -> ?NOT_LOADED.
erlfdb_transaction_get_next_tx_id(_Transaction) -> ?NOT_LOADED.
erlfdb_transaction_is_read_only(_Transaction) -> ?NOT_LOADED.


@@ -0,0 +1,25 @@
% Licensed under the Apache License, Version 2.0 (the "License"); you may not
% use this file except in compliance with the License. You may obtain a copy of
% the License at
%
% http://www.apache.org/licenses/LICENSE-2.0
%
% Unless required by applicable law or agreed to in writing, software
% distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
% WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
% License for the specific language governing permissions and limitations under
% the License.

-module(erlfdb_05_get_next_tx_id_test).

-include_lib("eunit/include/eunit.hrl").


get_tx_id_test() ->
Db = erlfdb_util:get_test_db(),
erlfdb:transactional(Db, fun(Tx) ->
lists:foreach(fun(I) ->
?assertEqual(I, erlfdb:get_next_tx_id(Tx))
end, lists:seq(0, 65535)),
?assertError(badarg, erlfdb:get_next_tx_id(Tx))
end).

0 comments on commit 4a2c683

Please sign in to comment.