Skip to content

Commit

Permalink
Add option to delete table to ets:delete
Browse files Browse the repository at this point in the history
Signed-off-by: Tomasz Sobkiewicz <[email protected]>
  • Loading branch information
TheSobkiewicz committed Jan 9, 2025
1 parent 76774f0 commit eaed2ed
Show file tree
Hide file tree
Showing 5 changed files with 56 additions and 14 deletions.
41 changes: 33 additions & 8 deletions src/libAtomVM/ets.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,23 +408,48 @@ EtsErrorCode ets_lookup_element(term name_or_ref, term key, size_t pos, term *re
return EtsOk;
}

EtsErrorCode ets_delete(term name_or_ref, term key, term *ret, Context *ctx)
static EtsErrorCode ets_table_delete(struct EtsTable *ets_table, term key, term *ret, Context *ctx)
{
struct EtsTable *ets_table = term_is_atom(name_or_ref) ? ets_get_table_by_name(&ctx->global->ets, name_or_ref, TableAccessRead) : ets_get_table_by_ref(&ctx->global->ets, term_to_ref_ticks(name_or_ref), TableAccessRead);
if (ets_table == NULL) {
return EtsTableNotFound;
}

if (ets_table->access_type != EtsAccessPublic && ets_table->owner_process_id != ctx->process_id) {
SMP_UNLOCK(ets_table);
return EtsPermissionDenied;
}

bool _res = ets_hashtable_remove(ets_table->hashtable, key, ets_table->keypos, ctx->global);
UNUSED(_res);

SMP_UNLOCK(ets_table);
*ret = TRUE_ATOM;
return EtsOk;
}

EtsErrorCode ets_drop_table(term name_or_ref, term *ret, Context *ctx)
{
struct EtsTable *ets_table = term_is_atom(name_or_ref) ? ets_get_table_by_name(&ctx->global->ets, name_or_ref, TableAccessWrite) : ets_get_table_by_ref(&ctx->global->ets, term_to_ref_ticks(name_or_ref), TableAccessWrite);
if (IS_NULL_PTR(ets_table)) {
return EtsTableNotFound;
}
if (ets_table->access_type != EtsAccessPublic && ets_table->owner_process_id != ctx->process_id) {
return EtsPermissionDenied;
}

synclist_wrlock(&ctx->global->ets.ets_tables);
SMP_UNLOCK(ets_table);
list_remove(&ets_table->head);
ets_table_destroy(ets_table, ctx->global);
synclist_unlock(&ctx->global->ets.ets_tables);

*ret = TRUE_ATOM;
return EtsOk;
}

EtsErrorCode ets_delete(term name_or_ref, term key, term *ret, Context *ctx)
{
struct EtsTable *ets_table = term_is_atom(name_or_ref) ? ets_get_table_by_name(&ctx->global->ets, name_or_ref, TableAccessRead) : ets_get_table_by_ref(&ctx->global->ets, term_to_ref_ticks(name_or_ref), TableAccessRead);
if (IS_NULL_PTR(ets_table)) {
return EtsTableNotFound;
}

EtsErrorCode res = ets_table_delete(ets_table, key, ret, ctx);

SMP_UNLOCK(ets_table);
return res;
}
1 change: 1 addition & 0 deletions src/libAtomVM/ets.h
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,7 @@ EtsErrorCode ets_insert(term ref, term entry, Context *ctx);
EtsErrorCode ets_lookup(term ref, term key, term *ret, Context *ctx);
EtsErrorCode ets_lookup_element(term ref, term key, size_t pos, term *ret, Context *ctx);
EtsErrorCode ets_delete(term ref, term key, term *ret, Context *ctx);
EtsErrorCode ets_drop_table(term ref, term *ret, Context *ctx);

#ifdef __cplusplus
}
Expand Down
14 changes: 8 additions & 6 deletions src/libAtomVM/nifs.c
Original file line number Diff line number Diff line change
Expand Up @@ -3393,15 +3393,17 @@ static term nif_ets_lookup_element(Context *ctx, int argc, term argv[])

static term nif_ets_delete(Context *ctx, int argc, term argv[])
{
UNUSED(argc);

term ref = argv[0];
VALIDATE_VALUE(ref, is_ets_table_id);

term key = argv[1];

term ret = term_invalid_term();
EtsErrorCode result = ets_delete(ref, key, &ret, ctx);
EtsErrorCode result;
if (argc == 2) {
term key = argv[1];
result = ets_delete(ref, key, &ret, ctx);
} else {
result = ets_drop_table(ref, &ret, ctx);
}

switch (result) {
case EtsOk:
return ret;
Expand Down
1 change: 1 addition & 0 deletions src/libAtomVM/nifs.gperf
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,7 @@ ets:insert/2, &ets_insert_nif
ets:lookup/2, &ets_lookup_nif
ets:lookup_element/3, &ets_lookup_element_nif
ets:delete/2, &ets_delete_nif
ets:delete/1, &ets_delete_nif
atomvm:add_avm_pack_binary/2, &atomvm_add_avm_pack_binary_nif
atomvm:add_avm_pack_file/2, &atomvm_add_avm_pack_file_nif
atomvm:close_avm_pack/2, &atomvm_close_avm_pack_nif
Expand Down
13 changes: 13 additions & 0 deletions tests/erlang_tests/test_ets.erl
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ start() ->
ok = test_public_access(),
ok = test_lookup_element(),
ok = test_insert_list(),
ok = test_delete_table(),
0.

test_basic() ->
Expand Down Expand Up @@ -362,3 +363,15 @@ test_insert_list() ->
expect_failure(fun() -> ets:insert(Tid, [{foo, tapas} | {patat, patat}]) end),
expect_failure(fun() -> ets:insert(Tid, [{}]) end),
ok.

test_delete_table() ->
Tid = ets:new(test_delete_table, []),
true = ets:insert(Tid, {foo, tapas}),
[{foo, tapas}] = ets:lookup(Tid, foo),
true = ets:delete(Tid),
ok = expect_failure(
fun() -> ets:insert(Tid, {gnu, gnat}) end
),
Ntid = ets:new(test_delete_table, []),
true = ets:delete(Ntid),
ok.

0 comments on commit eaed2ed

Please sign in to comment.