-
Notifications
You must be signed in to change notification settings - Fork 122
Support duplicate bag in insert and lookup #1718
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
switch (key_atom) { | ||
case NAMED_TABLE_ATOM: { | ||
is_named = true; | ||
break; | ||
} | ||
case PRIVATE_ATOM: { | ||
private = true; | ||
public = false; | ||
break; | ||
} | ||
case PUBLIC_ATOM: { | ||
private = false; | ||
public = true; | ||
break; | ||
} | ||
case SET_ATOM: { | ||
is_duplicate_bag = false; | ||
break; | ||
} | ||
case DUPLICATE_BAG_ATOM: { | ||
is_duplicate_bag = true; | ||
break; | ||
} | ||
case KEYPOS_ATOM: { | ||
VALIDATE_VALUE(value, term_is_integer); | ||
avm_int_t keypos = term_to_int(value); | ||
if (UNLIKELY(keypos < 1)) { | ||
RAISE_ERROR(BADARG_ATOM); | ||
} | ||
key_index = keypos - 1; | ||
break; | ||
} | ||
default: | ||
RAISE_ERROR(BADARG_ATOM); | ||
} | ||
options = term_get_list_tail(options); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was thinking about adding interop_parse_kw_opts(term kw, &opts)
but this loop relies on ability to override keys when they're repeated (e.g. [set, duplicate_bag, set]
). Maybe in the future.
} | ||
|
||
// TODO: create list elsewhere, by copying terms from orig heap, appending new copied tuple and using ets_hashtable_new_node | ||
struct HNode *ets_hashtable_new_node_from_list(term old_tuples, term tuple, size_t key_index) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This copies old tuple list from previous node's heap, copies tuple from process' heap and merges them together on the new heap. TODO is for removing this function and using utility function to do that and then just pass new heap to new_node.
@@ -248,78 +243,105 @@ static bool true_pred(struct EtsTable *table, void *data) | |||
return true; | |||
} | |||
|
|||
static void ets_delete_all_tables(struct Ets *ets, GlobalContext *global) | |||
static void delete_all_tables(struct Ets *ets, GlobalContext *global) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was constantly confusing exported functions and internal functions so I opted for rename removing prefix for internal ones (previously: ets_lookup_maybe_gc
vs ets_lookup_table_maybe_gc
, now ets_lookup_maybe_gc
vs lookup_maybe_gc
).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds a reasonable point, I will note this on the idea for the updated coding style.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The alternative we have in the fork is to use internal
prefix/suffix but it's get lengthy.
@@ -52,7 +58,7 @@ struct EtsTable | |||
term name; | |||
bool is_named; | |||
int32_t owner_process_id; | |||
size_t keypos; | |||
size_t key_index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was already using 0-based indexes but was named position
which suggests 1-based indexes. Cleaned all up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm adding a first round of comments here, I did not yet finished this review, so more comments will follow.
A rebase on latest main would defintely help, since the previous ets PR has been merged.
@@ -52,7 +58,7 @@ struct EtsTable | |||
term name; | |||
bool is_named; | |||
int32_t owner_process_id; | |||
size_t keypos; | |||
size_t key_index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
good catch.
@@ -3297,35 +3297,96 @@ static term nif_erlang_raise(Context *ctx, int argc, term argv[]) | |||
return term_invalid_term(); | |||
} | |||
|
|||
static inline term get_option_key(term option, term *maybe_value) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
it took me a moment to find the purpose of this function, so I suggest naming it extract_option_key_value()
.
Also, if you plan to make something generic (while keeping a clean and simple API) that can be used elsewhere as well, returning true
as value for atoms might be a good choice (while using undefined when no property is found).
VALIDATE_VALUE(key_atom, term_is_atom); | ||
|
||
switch (key_atom) { | ||
case NAMED_TABLE_ATOM: { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
fun fact: on OTP it is not a proplist, so ets:new(foo, [{named_table, true}]).
raises badarg, but ets:new(fiz, [named_table])
doesn't.
So I think this can be handled with a simple change:
switch (head) {
case NAMED_TABLE_ATOM:
...
default:
VALIDATE_VALUE(head, term_is_tuple);
term value;
term key_atom = get_option_key(head, &value);
VALIDATE_VALUE(key_atom, term_is_atom);
ets:new(foo, [{named_table, true}]).
also, let's make sure in tests that fails as expected.
@@ -248,78 +243,105 @@ static bool true_pred(struct EtsTable *table, void *data) | |||
return true; | |||
} | |||
|
|||
static void ets_delete_all_tables(struct Ets *ets, GlobalContext *global) | |||
static void delete_all_tables(struct Ets *ets, GlobalContext *global) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds a reasonable point, I will note this on the idea for the updated coding style.
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
ETS mixes position (1-based) with indexing (0-based). Tuple are 0-indexed so we should convert to it at earliest possible moment. This commit doesn't introduce any change in behavior. Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
ETS supports setting different key position (default: first element in tuple) in ets:new/2. Checking if updated element shouldn't be placed as first element is wrong. Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Additionally, unifies tuple arity checks (no change in behavior). Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Signed-off-by: Jakub Gonet <jakub.gonet@swmansion.com>
Merge after #1614. New code after "ets hash table: rename status enum".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