Skip to content

Commit ca3f7c7

Browse files
committed
Merge pull request atomvm#1461 from TheSobkiewicz/thesobkiewicz/nifs/ets/refactor_delete
Add `ets:delete/1`, `ets:delete` refactor See also atomvm#1509 - Added ets:delete/1. - Extracted helper functions for ets:delete that will be used in future function implementations. Based on atomvm#1405. The new helper functions can be utilized in the following ETS operations to reduce code duplication: - ets:take/2 - ets:delete_object/2 These changes are made under both the "Apache 2.0" and the "GNU Lesser General Public License 2.1 or later" license terms (dual license). SPDX-License-Identifier: Apache-2.0 OR LGPL-2.1-or-later
2 parents be43cc6 + b12195c commit ca3f7c7

File tree

7 files changed

+73
-14
lines changed

7 files changed

+73
-14
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2727
- Support for `float/1` BIF.
2828
- Added `erlang:get/0` and `erlang:erase/0`.
2929
- Added `erlang:unique_integer/0` and `erlang:unique_integer/1`
30+
- Added support for 'ets:delete/1'.
3031

3132
### Fixed
3233
- ESP32: improved sntp sync speed from a cold boot.

libs/estdlib/src/ets.erl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929
insert/2,
3030
lookup/2,
3131
lookup_element/3,
32+
delete/1,
3233
delete/2,
3334
update_counter/3,
3435
update_counter/4
@@ -141,3 +142,12 @@ update_counter(_Table, _Key, _Params) ->
141142
) -> integer().
142143
update_counter(_Table, _Key, _Params, _Default) ->
143144
erlang:nif_error(undefined).
145+
%%-----------------------------------------------------------------------------
146+
%% @param Table a reference to the ets table
147+
%% @returns true;
148+
%% @doc Delete an ets table.
149+
%% @end
150+
%%-----------------------------------------------------------------------------
151+
-spec delete(Table :: table()) -> true.
152+
delete(_Table) ->
153+
erlang:nif_error(undefined).

src/libAtomVM/ets.c

Lines changed: 38 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -426,27 +426,57 @@ EtsErrorCode ets_lookup_element_maybe_gc(term name_or_ref, term key, size_t pos,
426426
return EtsOk;
427427
}
428428

429-
EtsErrorCode ets_delete(term name_or_ref, term key, term *ret, Context *ctx)
429+
static EtsErrorCode ets_table_delete(struct EtsTable *ets_table, term key, term *ret, Context *ctx)
430430
{
431-
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);
432-
if (ets_table == NULL) {
433-
return EtsTableNotFound;
434-
}
435-
436431
if (ets_table->access_type != EtsAccessPublic && ets_table->owner_process_id != ctx->process_id) {
437-
SMP_UNLOCK(ets_table);
438432
return EtsPermissionDenied;
439433
}
440434

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

444-
SMP_UNLOCK(ets_table);
445438
*ret = TRUE_ATOM;
439+
return EtsOk;
440+
}
446441

442+
EtsErrorCode ets_drop_table(term name_or_ref, term *ret, Context *ctx)
443+
{
444+
struct EtsTable *ets_table = term_is_atom(name_or_ref)
445+
? ets_get_table_by_name(&ctx->global->ets, name_or_ref, TableAccessWrite)
446+
: ets_get_table_by_ref(&ctx->global->ets, term_to_ref_ticks(name_or_ref), TableAccessWrite);
447+
if (IS_NULL_PTR(ets_table)) {
448+
return EtsTableNotFound;
449+
}
450+
if (ets_table->access_type != EtsAccessPublic && ets_table->owner_process_id != ctx->process_id) {
451+
return EtsPermissionDenied;
452+
}
453+
454+
struct ListHead *ets_tables_list = synclist_wrlock(&ctx->global->ets.ets_tables);
455+
UNUSED(ets_tables_list);
456+
list_remove(&ets_table->head);
457+
SMP_UNLOCK(ets_table);
458+
ets_table_destroy(ets_table, ctx->global);
459+
synclist_unlock(&ctx->global->ets.ets_tables);
460+
461+
*ret = TRUE_ATOM;
447462
return EtsOk;
448463
}
449464

465+
EtsErrorCode ets_delete(term name_or_ref, term key, term *ret, Context *ctx)
466+
{
467+
struct EtsTable *ets_table = term_is_atom(name_or_ref)
468+
? ets_get_table_by_name(&ctx->global->ets, name_or_ref, TableAccessRead)
469+
: ets_get_table_by_ref(&ctx->global->ets, term_to_ref_ticks(name_or_ref), TableAccessRead);
470+
if (IS_NULL_PTR(ets_table)) {
471+
return EtsTableNotFound;
472+
}
473+
474+
EtsErrorCode res = ets_table_delete(ets_table, key, ret, ctx);
475+
476+
SMP_UNLOCK(ets_table);
477+
return res;
478+
}
479+
450480
static bool operation_to_tuple4(term operation, size_t default_pos, term *position, term *increment, term *threshold, term *set_value)
451481
{
452482
if (term_is_integer(operation)) {

src/libAtomVM/ets.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ EtsErrorCode ets_lookup_maybe_gc(term ref, term key, term *ret, Context *ctx);
7979
EtsErrorCode ets_lookup_element_maybe_gc(term ref, term key, size_t pos, term *ret, Context *ctx);
8080
EtsErrorCode ets_delete(term ref, term key, term *ret, Context *ctx);
8181
EtsErrorCode ets_update_counter_maybe_gc(term ref, term key, term value, term pos, term *ret, Context *ctx);
82+
EtsErrorCode ets_drop_table(term ref, term *ret, Context *ctx);
8283
#ifdef __cplusplus
8384
}
8485
#endif

src/libAtomVM/nifs.c

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3314,15 +3314,17 @@ static term nif_ets_lookup_element(Context *ctx, int argc, term argv[])
33143314

33153315
static term nif_ets_delete(Context *ctx, int argc, term argv[])
33163316
{
3317-
UNUSED(argc);
3318-
33193317
term ref = argv[0];
33203318
VALIDATE_VALUE(ref, is_ets_table_id);
3321-
3322-
term key = argv[1];
3323-
33243319
term ret = term_invalid_term();
3325-
EtsErrorCode result = ets_delete(ref, key, &ret, ctx);
3320+
EtsErrorCode result;
3321+
if (argc == 2) {
3322+
term key = argv[1];
3323+
result = ets_delete(ref, key, &ret, ctx);
3324+
} else {
3325+
result = ets_drop_table(ref, &ret, ctx);
3326+
}
3327+
33263328
switch (result) {
33273329
case EtsOk:
33283330
return ret;

src/libAtomVM/nifs.gperf

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,7 @@ ets:new/2, &ets_new_nif
131131
ets:insert/2, &ets_insert_nif
132132
ets:lookup/2, &ets_lookup_nif
133133
ets:lookup_element/3, &ets_lookup_element_nif
134+
ets:delete/1, &ets_delete_nif
134135
ets:delete/2, &ets_delete_nif
135136
ets:update_counter/3, &ets_update_counter_nif
136137
ets:update_counter/4, &ets_update_counter_nif

tests/erlang_tests/test_ets.erl

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ start() ->
3333
ok = test_lookup_element(),
3434
ok = test_insert_list(),
3535
ok = test_update_counter(),
36+
ok = test_delete_table(),
3637
0.
3738

3839
test_basic() ->
@@ -386,3 +387,16 @@ test_update_counter() ->
386387
10 = ets:update_counter(Tid, patatas, {3, 10, 10, 0}),
387388
0 = ets:update_counter(Tid, patatas, {3, 10, 10, 0}),
388389
ok.
390+
391+
test_delete_table() ->
392+
Tid = ets:new(test_delete_table, []),
393+
true = ets:delete(Tid),
394+
ok = expect_failure(
395+
fun() -> ets:insert(Tid, {gnu, gnat}) end
396+
),
397+
Ntid = ets:new(test_delete_table, []),
398+
true = ets:delete(Ntid),
399+
ok = expect_failure(fun() -> ets:delete(Ntid) end),
400+
ok = expect_failure(fun() -> ets:delete(Tid) end),
401+
ok = expect_failure(fun() -> ets:delete(non_existent) end),
402+
ok.

0 commit comments

Comments
 (0)