Skip to content

Commit

Permalink
Merge branch 'ets_next_object' OTP-18923
Browse files Browse the repository at this point in the history
  • Loading branch information
sverker committed Jan 10, 2024
2 parents 53275ec + d947948 commit 3d6a5b1
Show file tree
Hide file tree
Showing 14 changed files with 700 additions and 90 deletions.
4 changes: 4 additions & 0 deletions erts/emulator/beam/bif.tab
Original file line number Diff line number Diff line change
Expand Up @@ -357,13 +357,15 @@ bif ets:delete/1
bif ets:delete/2
bif ets:delete_object/2
bif ets:first/1
bif ets:first_lookup/1
bif ets:is_compiled_ms/1
bif ets:lookup/2
bif ets:lookup_element/3
bif ets:lookup_element/4
bif ets:info/1
bif ets:info/2
bif ets:last/1
bif ets:last_lookup/1
bif ets:match/1
bif ets:match/2
bif ets:match/3
Expand All @@ -372,7 +374,9 @@ bif ets:match_object/2
bif ets:match_object/3
bif ets:member/2
bif ets:next/2
bif ets:next_lookup/2
bif ets:prev/2
bif ets:prev_lookup/2
bif ets:insert/2
bif ets:insert_new/2
bif ets:rename/2
Expand Down
93 changes: 93 additions & 0 deletions erts/emulator/beam/erl_db.c
Original file line number Diff line number Diff line change
Expand Up @@ -1115,6 +1115,29 @@ BIF_RETTYPE ets_first_1(BIF_ALIST_1)
BIF_RET(ret);
}

/*
** Returns the first {key, object(s)} in a table
*/
BIF_RETTYPE ets_first_lookup_1(BIF_ALIST_1)
{
DbTable* tb;
int cret;
Eterm ret;

CHECK_TABLES();

DB_BIF_GET_TABLE(tb, DB_READ, LCK_READ, BIF_ets_first_lookup_1);

cret = tb->common.meth->db_first_lookup(BIF_P, tb, &ret);

db_unlock(tb, LCK_READ);

if (cret != DB_ERROR_NONE) {
BIF_ERROR(BIF_P, BADARG);
}
BIF_RET(ret);
}

/*
** The next BIF, given a key, return the "next" key
*/
Expand All @@ -1138,6 +1161,30 @@ BIF_RETTYPE ets_next_2(BIF_ALIST_2)
BIF_RET(ret);
}


/*
** The next_lookup BIF, given a key, return the "next" {key, object(s)}
*/
BIF_RETTYPE ets_next_lookup_2(BIF_ALIST_2)
{
DbTable* tb;
int cret;
Eterm ret;

CHECK_TABLES();

DB_BIF_GET_TABLE(tb, DB_READ, LCK_READ, BIF_ets_next_lookup_2);

cret = tb->common.meth->db_next_lookup(BIF_P, tb, BIF_ARG_2, &ret);

db_unlock(tb, LCK_READ);

if (cret != DB_ERROR_NONE) {
BIF_ERROR(BIF_P, BADARG);
}
BIF_RET(ret);
}

/*
** Returns the last Key in a table
*/
Expand All @@ -1161,6 +1208,29 @@ BIF_RETTYPE ets_last_1(BIF_ALIST_1)
BIF_RET(ret);
}

/*
** Returns the last {key, object(s)} in a table
*/
BIF_RETTYPE ets_last_lookup_1(BIF_ALIST_1)
{
DbTable* tb;
int cret;
Eterm ret;

CHECK_TABLES();

DB_BIF_GET_TABLE(tb, DB_READ, LCK_READ, BIF_ets_last_lookup_1);

cret = tb->common.meth->db_last_lookup(BIF_P, tb, &ret);

db_unlock(tb, LCK_READ);

if (cret != DB_ERROR_NONE) {
BIF_ERROR(BIF_P, BADARG);
}
BIF_RET(ret);
}

/*
** The prev BIF, given a key, return the "previous" key
*/
Expand All @@ -1184,6 +1254,29 @@ BIF_RETTYPE ets_prev_2(BIF_ALIST_2)
BIF_RET(ret);
}

/*
** The prev_lookup BIF, given a key, return the "previous" {key, object(s)}
*/
BIF_RETTYPE ets_prev_lookup_2(BIF_ALIST_2)
{
DbTable* tb;
int cret;
Eterm ret;

CHECK_TABLES();

DB_BIF_GET_TABLE(tb, DB_READ, LCK_READ, BIF_ets_prev_lookup_2);

cret = tb->common.meth->db_prev_lookup(BIF_P, tb, BIF_ARG_2, &ret);

db_unlock(tb, LCK_READ);

if (cret != DB_ERROR_NONE) {
BIF_ERROR(BIF_P, BADARG);
}
BIF_RET(ret);
}

/*
** take(Tab, Key)
*/
Expand Down
71 changes: 62 additions & 9 deletions erts/emulator/beam/erl_db_catree.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,13 +98,22 @@ static SWord do_delete_base_node_cont(DbTableCATree *tb,
/* Method interface functions */
static int db_first_catree(Process *p, DbTable *tbl,
Eterm *ret);
static int db_first_lookup_catree(Process *p, DbTable *tbl,
Eterm *ret);
static int db_next_catree(Process *p, DbTable *tbl,
Eterm key, Eterm *ret);
static int db_next_lookup_catree(Process *p, DbTable *tbl,
Eterm key, Eterm *ret);
static int db_last_catree(Process *p, DbTable *tbl,
Eterm *ret);
static int db_last_lookup_catree(Process *p, DbTable *tbl,
Eterm *ret);
static int db_prev_catree(Process *p, DbTable *tbl,
Eterm key,
Eterm *ret);
static int db_prev_lookup_catree(Process *p, DbTable *tbl,
Eterm key,
Eterm *ret);
static int db_put_catree(DbTable *tbl, Eterm obj, int key_clash_fail,
SWord *consumed_reds_p);
static int db_get_catree(Process *p, DbTable *tbl,
Expand Down Expand Up @@ -227,7 +236,11 @@ DbTableMethod db_catree =
db_get_dbterm_key_tree_common,
db_get_binary_info_catree,
db_first_catree, /* raw_first same as first */
db_next_catree /* raw_next same as next */
db_next_catree, /* raw_next same as next */
db_first_lookup_catree,
db_next_lookup_catree,
db_last_lookup_catree,
db_prev_lookup_catree
};

/*
Expand Down Expand Up @@ -1567,7 +1580,7 @@ int db_create_catree(Process *p, DbTable *tbl)
return DB_ERROR_NONE;
}

static int db_first_catree(Process *p, DbTable *tbl, Eterm *ret)
static int db_first_catree_common(Process *p, DbTable *tbl, Eterm *ret, Eterm (*func)(Process *, DbTable *, TreeDbTerm *))
{
TreeDbTerm *root;
CATreeRootIterator iter;
Expand All @@ -1580,13 +1593,23 @@ static int db_first_catree(Process *p, DbTable *tbl, Eterm *ret)
root = pp ? *pp : NULL;
}

result = db_first_tree_common(p, tbl, root, ret, NULL);
result = db_first_tree_common(p, tbl, root, ret, NULL, func);

destroy_root_iterator(&iter);
return result;
}

static int db_next_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
static int db_first_catree(Process *p, DbTable *tbl, Eterm *ret)
{
return db_first_catree_common(p, tbl, ret, db_copy_key_tree);
}

static int db_first_lookup_catree(Process *p, DbTable *tbl, Eterm *ret)
{
return db_first_catree_common(p, tbl, ret, db_copy_key_and_object_tree);
}

static int db_next_catree_common(Process *p, DbTable *tbl, Eterm key, Eterm *ret, Eterm (*func)(Process *, DbTable *, TreeDbTerm *))
{
DbTreeStack stack;
TreeDbTerm * stack_array[STACK_NEED];
Expand All @@ -1600,7 +1623,7 @@ static int db_next_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)

do {
init_tree_stack(&stack, stack_array, 0);
result = db_next_tree_common(p, tbl, (rootp ? *rootp : NULL), key, ret, &stack);
result = db_next_tree_common(p, tbl, (rootp ? *rootp : NULL), key, ret, &stack, func);
if (result != DB_ERROR_NONE || *ret != am_EOT)
break;

Expand All @@ -1611,7 +1634,17 @@ static int db_next_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
return result;
}

static int db_last_catree(Process *p, DbTable *tbl, Eterm *ret)
static int db_next_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
return db_next_catree_common(p, tbl, key, ret, db_copy_key_tree);
}

static int db_next_lookup_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
return db_next_catree_common(p, tbl, key, ret, db_copy_key_and_object_tree);
}

static int db_last_catree_common(Process *p, DbTable *tbl, Eterm *ret, Eterm (*func)(Process *, DbTable *, TreeDbTerm *))
{
TreeDbTerm *root;
CATreeRootIterator iter;
Expand All @@ -1624,13 +1657,23 @@ static int db_last_catree(Process *p, DbTable *tbl, Eterm *ret)
root = pp ? *pp : NULL;
}

result = db_last_tree_common(p, tbl, root, ret, NULL);
result = db_last_tree_common(p, tbl, root, ret, NULL, func);

destroy_root_iterator(&iter);
return result;
}

static int db_prev_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
static int db_last_catree(Process *p, DbTable *tbl, Eterm *ret)
{
return db_last_catree_common(p, tbl, ret, db_copy_key_tree);
}

static int db_last_lookup_catree(Process *p, DbTable *tbl, Eterm *ret)
{
return db_last_catree_common(p, tbl, ret, db_copy_key_and_object_tree);
}

static int db_prev_catree_common(Process *p, DbTable *tbl, Eterm key, Eterm *ret, Eterm (*func)(Process *, DbTable *, TreeDbTerm *))
{
DbTreeStack stack;
TreeDbTerm * stack_array[STACK_NEED];
Expand All @@ -1645,7 +1688,7 @@ static int db_prev_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
do {
init_tree_stack(&stack, stack_array, 0);
result = db_prev_tree_common(p, tbl, (rootp ? *rootp : NULL), key, ret,
&stack);
&stack, func);
if (result != DB_ERROR_NONE || *ret != am_EOT)
break;
rootp = catree_find_prev_root(&iter, NULL);
Expand All @@ -1655,6 +1698,16 @@ static int db_prev_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
return result;
}

static int db_prev_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
return db_prev_catree_common(p, tbl, key, ret, db_copy_key_tree);
}

static int db_prev_lookup_catree(Process *p, DbTable *tbl, Eterm key, Eterm *ret)
{
return db_prev_catree_common(p, tbl, key, ret, db_copy_key_and_object_tree);
}

static int db_put_dbterm_catree(DbTable* tbl,
void* obj,
int key_clash_fail,
Expand Down
Loading

0 comments on commit 3d6a5b1

Please sign in to comment.