aboutsummaryrefslogtreecommitdiffstats
path: root/erts/emulator/beam
diff options
context:
space:
mode:
Diffstat (limited to 'erts/emulator/beam')
-rw-r--r--erts/emulator/beam/erl_db_catree.c100
-rw-r--r--erts/emulator/beam/erl_db_catree.h16
2 files changed, 58 insertions, 58 deletions
diff --git a/erts/emulator/beam/erl_db_catree.c b/erts/emulator/beam/erl_db_catree.c
index f2baf50cbc..a8e48bce1b 100644
--- a/erts/emulator/beam/erl_db_catree.c
+++ b/erts/emulator/beam/erl_db_catree.c
@@ -210,7 +210,7 @@ DbTableMethod db_catree =
* Internal CA tree related helper functions and macros
*/
-#define GET_ROUTE_NODE_KEY(node) (node->u.route.key.tpl[0])
+#define GET_ROUTE_NODE_KEY(node) (node->u.route.key.term)
#define GET_BASE_NODE_LOCK(node) (&(node->u.base.lock))
#define GET_ROUTE_NODE_LOCK(node) (&(node->u.route.lock))
@@ -782,9 +782,38 @@ void unlock_route_node(DbTableCATreeNode *route_node)
}
+static ERTS_INLINE
+void copy_route_key(DbRouteKey* dst, Eterm key, Uint key_size)
+{
+ dst->size = key_size;
+ if (key_size != 0) {
+ Eterm* hp = &dst->heap[0];
+ ErlOffHeap tmp_offheap;
+ tmp_offheap.first = NULL;
+ dst->term = copy_struct(key, key_size, &hp, &tmp_offheap);
+ dst->oh = tmp_offheap.first;
+ }
+ else {
+ ASSERT(is_immed(key));
+ dst->term = key;
+ dst->oh = NULL;
+ }
+}
+
+static ERTS_INLINE
+void destroy_route_key(DbRouteKey* key)
+{
+ if (key->oh) {
+ ErlOffHeap oh;
+ oh.first = key->oh;
+ erts_cleanup_offheap(&oh);
+ }
+}
+
+
#ifdef ERTS_ENABLE_LOCK_CHECK
# define sizeof_base_node(KEY_SZ) \
- (offsetof(DbTableCATreeNode, u.base.lc.key_heap) \
+ (offsetof(DbTableCATreeNode, u.base.lc_key.heap) \
+ (KEY_SZ)*sizeof(Eterm))
# define LC_ORDER(ORDER) ORDER
#else
@@ -813,16 +842,7 @@ static DbTableCATreeNode *create_base_node(DbTableCATree *tb,
rwmtx_opt.main_spincount = erts_ets_rwmtx_spin_count;
#ifdef ERTS_ENABLE_LOCK_CHECK
- {
- Eterm* hp = &p->u.base.lc.key_heap[0];
- ErlOffHeap oh;
-
- oh.first = NULL;
- lc_key = copy_struct(lc_key, lc_key_size, &hp, &oh);
- p->u.base.lc.key = lc_key;
- p->u.base.lc.key_size = lc_key_size;
- p->u.base.lc.key_oh = oh.first;
- }
+ copy_route_key(&p->u.base.lc_key, lc_key, lc_key_size);
#endif
erts_rwmtx_init_opt(&p->u.base.lock, &rwmtx_opt,
"erl_db_catree_base_node",
@@ -849,7 +869,7 @@ DbTableCATreeNode *create_wlocked_base_node(DbTableCATree *tb,
static ERTS_INLINE Uint sizeof_route_node(Uint key_size)
{
- return (offsetof(DbTableCATreeNode, u.route.key.tpl[1])
+ return (offsetof(DbTableCATreeNode, u.route.key.heap)
+ key_size*sizeof(Eterm));
}
@@ -860,25 +880,13 @@ create_route_node(DbTableCATree *tb,
DbTerm * keyTerm,
DbTableCATreeNode* lc_parent)
{
- Eterm* top;
Eterm key = GETKEY(tb,keyTerm->tpl);
int key_size = size_object(key);
- ErlOffHeap tmp_offheap;
DbTableCATreeNode* p = erts_db_alloc(ERTS_ALC_T_DB_TABLE,
(DbTable *) tb,
sizeof_route_node(key_size));
- if (key_size != 0) {
- p->u.route.key.size = key_size;
- top = &p->u.route.key.tpl[1];
- tmp_offheap.first = NULL;
- p->u.route.key.tpl[0] = copy_struct(key, key_size, &top, &tmp_offheap);
- p->u.route.key.first_oh = tmp_offheap.first;
- } else {
- p->u.route.key.size = key_size;
- p->u.route.key.first_oh = NULL;
- p->u.route.key.tpl[0] = key;
- }
+ copy_route_key(&p->u.route.key, key, key_size);
p->is_base_node = 0;
p->u.route.is_valid = 1;
erts_atomic_init_nob(&p->u.route.left, (erts_aint_t)left);
@@ -906,11 +914,7 @@ static void do_free_base_node(void* vptr)
ASSERT(p->is_base_node);
erts_rwmtx_destroy(&p->u.base.lock);
#ifdef ERTS_ENABLE_LOCK_CHECK
- if (p->u.base.lc.key_size != 0) {
- ErlOffHeap oh;
- oh.first = p->u.base.lc.key_oh;
- erts_cleanup_offheap(&oh);
- }
+ destroy_route_key(&p->u.base.lc_key);
#endif
erts_free(ERTS_ALC_T_DB_TABLE, p);
}
@@ -918,7 +922,7 @@ static void do_free_base_node(void* vptr)
static void free_catree_base_node(DbTableCATree* tb, DbTableCATreeNode* p)
{
ASSERT(p->is_base_node);
- ERTS_DB_ALC_MEM_UPDATE_(tb, sizeof_base_node(p->u.base.lc.key_size), 0);
+ ERTS_DB_ALC_MEM_UPDATE_(tb, sizeof_base_node(p->u.base.lc_key.size), 0);
do_free_base_node(p);
}
@@ -927,11 +931,7 @@ static void do_free_route_node(void *vptr)
DbTableCATreeNode *p = (DbTableCATreeNode *)vptr;
ASSERT(!p->is_base_node);
erts_mtx_destroy(&p->u.route.lock);
- if (p->u.route.key.size != 0) {
- ErlOffHeap tmp_oh;
- tmp_oh.first = p->u.route.key.first_oh;
- erts_cleanup_offheap(&tmp_oh);
- }
+ destroy_route_key(&p->u.route.key);
erts_free(ERTS_ALC_T_DB_TABLE, p);
}
@@ -1038,7 +1038,7 @@ get_next_base_node_and_path(DbTableCATreeNode *base_node,
stack);
} else {
Eterm pkey =
- TOP_NODE(stack)->u.route.key.tpl[0]; /* pKey = key of parent */
+ TOP_NODE(stack)->u.route.key.term; /* pKey = key of parent */
POP_NODE(stack);
while (!EMPTY_NODE(stack)) {
if (TOP_NODE(stack)->u.route.is_valid &&
@@ -1239,6 +1239,7 @@ erl_db_catree_force_join_right(DbTableCATree *tb,
DbTableCATreeNode *neighbor;
DbTableCATreeNode *new_neighbor;
DbTableCATreeNode *neighbor_parent;
+ TreeDbTerm* new_root;
if (parent == NULL) {
return NULL;
@@ -1276,12 +1277,9 @@ erl_db_catree_force_join_right(DbTableCATree *tb,
unlock_route_node(gparent);
}
- {
- TreeDbTerm* new_root = join_trees(thiz->u.base.root,
- neighbor->u.base.root);
- new_neighbor = create_wlocked_base_node(tb, new_root,
- LC_ORDER(thiz->u.base.lc.key));
- }
+ new_root = join_trees(thiz->u.base.root, neighbor->u.base.root);
+ new_neighbor = create_wlocked_base_node(tb, new_root,
+ LC_ORDER(thiz->u.base.lc_key.term));
if (GET_RIGHT(parent) == neighbor) {
neighbor_parent = gparent;
@@ -1307,12 +1305,12 @@ erl_db_catree_force_join_right(DbTableCATree *tb,
do_free_base_node,
thiz,
&thiz->u.base.free_item,
- sizeof_base_node(thiz->u.base.lc.key_size));
+ sizeof_base_node(thiz->u.base.lc_key.size));
erts_schedule_db_free(&tb->common,
do_free_base_node,
neighbor,
&neighbor->u.base.free_item,
- sizeof_base_node(neighbor->u.base.lc.key_size));
+ sizeof_base_node(neighbor->u.base.lc_key.size));
*result_parent_wb = neighbor_parent;
return new_neighbor;
@@ -1417,7 +1415,7 @@ static void join_catree(DbTableCATree *tb,
TreeDbTerm* new_root = join_trees(thiz->u.base.root,
neighbor->u.base.root);
new_neighbor = create_base_node(tb, new_root,
- LC_ORDER(thiz->u.base.lc.key));
+ LC_ORDER(thiz->u.base.lc_key.term));
}
if (GET_RIGHT(parent) == neighbor) {
neighbor_parent = gparent;
@@ -1470,7 +1468,7 @@ static void join_catree(DbTableCATree *tb,
TreeDbTerm* new_root = join_trees(neighbor->u.base.root,
thiz->u.base.root);
new_neighbor = create_base_node(tb, new_root,
- LC_ORDER(thiz->u.base.lc.key));
+ LC_ORDER(thiz->u.base.lc_key.term));
}
if (GET_LEFT(parent) == neighbor) {
neighbor_parent = gparent;
@@ -1500,12 +1498,12 @@ static void join_catree(DbTableCATree *tb,
do_free_base_node,
thiz,
&thiz->u.base.free_item,
- sizeof_base_node(thiz->u.base.lc.key_size));
+ sizeof_base_node(thiz->u.base.lc_key.size));
erts_schedule_db_free(&tb->common,
do_free_base_node,
neighbor,
&neighbor->u.base.free_item,
- sizeof_base_node(neighbor->u.base.lc.key_size));
+ sizeof_base_node(neighbor->u.base.lc_key.size));
}
static void split_catree(DbTableCATree *tb,
@@ -1549,7 +1547,7 @@ static void split_catree(DbTableCATree *tb,
do_free_base_node,
base,
&base->u.base.free_item,
- sizeof_base_node(base->u.base.lc.key_size));
+ sizeof_base_node(base->u.base.lc_key.size));
}
}
diff --git a/erts/emulator/beam/erl_db_catree.h b/erts/emulator/beam/erl_db_catree.h
index 0ad921d880..f9c0784289 100644
--- a/erts/emulator/beam/erl_db_catree.h
+++ b/erts/emulator/beam/erl_db_catree.h
@@ -34,6 +34,13 @@
struct DbTableCATreeNode;
typedef struct {
+ Eterm term;
+ struct erl_off_heap_header* oh;
+ Uint size;
+ Eterm heap[1];
+} DbRouteKey;
+
+typedef struct {
erts_rwmtx_t lock; /* The lock for this base node */
Sint lock_statistics;
int is_valid; /* If this base node is still valid */
@@ -42,12 +49,7 @@ typedef struct {
struct DbTableCATreeNode * next; /* Used when gradually deleting */
#ifdef ERTS_ENABLE_LOCK_CHECK
- struct {
- Eterm key;
- struct erl_off_heap_header* key_oh;
- Uint key_size;
- Eterm key_heap[1];
- } lc;
+ DbRouteKey lc_key;
#endif
char end_of_struct__;
} DbTableCATreeBaseNode;
@@ -61,7 +63,7 @@ typedef struct {
int is_valid; /* If this route node is still valid */
erts_atomic_t left;
erts_atomic_t right;
- DbTerm key;
+ DbRouteKey key;
} DbTableCATreeRouteNode;
typedef struct DbTableCATreeNode {