Fixes, improvements, and enhancements to the opal_tree class (used by
the LAMA RMAPS component, to be committed shortly). This commit was SVN r27204.
Этот коммит содержится в:
родитель
ca5bd85364
Коммит
287e47a04d
@ -1,5 +1,6 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 Oak Ridge National Labs. All rights reserved.
|
||||
* Copyright (c) 2012 The University of Tennessee and The University
|
||||
* of Tennessee Research Foundation. All rights
|
||||
* reserved.
|
||||
@ -23,21 +24,21 @@ static void opal_tree_item_construct(opal_tree_item_t*);
|
||||
static void opal_tree_item_destruct(opal_tree_item_t*);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_tree_item_t,
|
||||
opal_object_t,
|
||||
opal_tree_item_construct,
|
||||
opal_tree_item_destruct
|
||||
);
|
||||
opal_tree_item_t,
|
||||
opal_object_t,
|
||||
opal_tree_item_construct,
|
||||
opal_tree_item_destruct
|
||||
);
|
||||
|
||||
static void opal_tree_construct(opal_tree_t*);
|
||||
static void opal_tree_destruct(opal_tree_t*);
|
||||
|
||||
OBJ_CLASS_INSTANCE(
|
||||
opal_tree_t,
|
||||
opal_object_t,
|
||||
opal_tree_construct,
|
||||
opal_tree_destruct
|
||||
);
|
||||
opal_tree_t,
|
||||
opal_object_t,
|
||||
opal_tree_construct,
|
||||
opal_tree_destruct
|
||||
);
|
||||
|
||||
|
||||
/*
|
||||
@ -86,19 +87,23 @@ static void opal_tree_construct(opal_tree_t *tree)
|
||||
tree->opal_tree_sentinel.opal_tree_item_refcount = 1;
|
||||
tree->opal_tree_sentinel.opal_tree_item_belong_to = tree;
|
||||
#endif
|
||||
tree->opal_tree_sentinel.opal_tree_num_ancestors = -1;
|
||||
tree->opal_tree_sentinel.opal_tree_container = tree;
|
||||
tree->opal_tree_sentinel.opal_tree_parent=&tree->opal_tree_sentinel;
|
||||
tree->opal_tree_sentinel.opal_tree_parent = &tree->opal_tree_sentinel;
|
||||
tree->opal_tree_sentinel.opal_tree_num_ancestors = -1;
|
||||
|
||||
tree->opal_tree_sentinel.opal_tree_next_sibling =
|
||||
&tree->opal_tree_sentinel;
|
||||
tree->opal_tree_sentinel.opal_tree_prev_sibling =
|
||||
&tree->opal_tree_sentinel;
|
||||
|
||||
tree->opal_tree_sentinel.opal_tree_first_child = &tree->opal_tree_sentinel;
|
||||
tree->opal_tree_sentinel.opal_tree_last_child = &tree->opal_tree_sentinel;
|
||||
|
||||
tree->opal_tree_num_items = 0;
|
||||
tree->comp = NULL;
|
||||
tree->serialize = NULL;
|
||||
tree->deserialize = NULL;
|
||||
tree->get_key = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -115,11 +120,13 @@ static void opal_tree_destruct(opal_tree_t *tree)
|
||||
*/
|
||||
void opal_tree_init(opal_tree_t *tree, opal_tree_comp_fn_t comp,
|
||||
opal_tree_item_serialize_fn_t serialize,
|
||||
opal_tree_item_deserialize_fn_t deserialize)
|
||||
opal_tree_item_deserialize_fn_t deserialize,
|
||||
opal_tree_get_key_fn_t get_key)
|
||||
{
|
||||
tree->comp = comp;
|
||||
tree->serialize = serialize;
|
||||
tree->deserialize = deserialize;
|
||||
tree->get_key = get_key;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -174,10 +181,10 @@ void opal_tree_add_child(opal_tree_item_t *parent_item,
|
||||
opal_tree_item_t *new_item)
|
||||
{
|
||||
#if OPAL_ENABLE_DEBUG
|
||||
/* Spot check: ensure that this item is previously on no lists */
|
||||
/* Spot check: ensure that this item is previously on no lists */
|
||||
|
||||
assert(0 == new_item->opal_tree_item_refcount);
|
||||
assert( NULL == new_item->opal_tree_item_belong_to );
|
||||
assert(0 == new_item->opal_tree_item_refcount);
|
||||
assert( NULL == new_item->opal_tree_item_belong_to );
|
||||
#endif
|
||||
|
||||
new_item->opal_tree_parent = parent_item;
|
||||
@ -188,9 +195,7 @@ void opal_tree_add_child(opal_tree_item_t *parent_item,
|
||||
parent_item->opal_tree_last_child->opal_tree_next_sibling = new_item;
|
||||
} else {
|
||||
/* no children existing on parent */
|
||||
parent_item->opal_tree_first_child =
|
||||
parent_item->opal_tree_last_child =
|
||||
new_item;
|
||||
parent_item->opal_tree_first_child = new_item;
|
||||
}
|
||||
parent_item->opal_tree_last_child = new_item;
|
||||
parent_item->opal_tree_num_children++;
|
||||
@ -198,12 +203,12 @@ void opal_tree_add_child(opal_tree_item_t *parent_item,
|
||||
new_item->opal_tree_container->opal_tree_num_items++;
|
||||
|
||||
#if OPAL_ENABLE_DEBUG
|
||||
/* Spot check: ensure this item is only on the list that we just
|
||||
appended it to */
|
||||
/* Spot check: ensure this item is only on the list that we just
|
||||
appended it to */
|
||||
|
||||
OPAL_THREAD_ADD32( &(new_item->opal_tree_item_refcount), 1 );
|
||||
assert(1 == new_item->opal_tree_item_refcount);
|
||||
new_item->opal_tree_item_belong_to = new_item->opal_tree_container;
|
||||
OPAL_THREAD_ADD32( &(new_item->opal_tree_item_refcount), 1 );
|
||||
assert(1 == new_item->opal_tree_item_refcount);
|
||||
new_item->opal_tree_item_belong_to = new_item->opal_tree_container;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -237,39 +242,63 @@ static bool item_in_tree(opal_tree_item_t *item, opal_tree_item_t *search_item)
|
||||
*/
|
||||
opal_tree_item_t *opal_tree_remove_subtree(opal_tree_item_t *item)
|
||||
{
|
||||
opal_tree_item_t *parent_item = NULL;
|
||||
|
||||
#if OPAL_ENABLE_DEBUG
|
||||
/* validate that item does exist on tree */
|
||||
if (NULL != item->opal_tree_container) {
|
||||
/* we point to a container, check if we can find item in tree */
|
||||
if (!item_in_tree(opal_tree_get_root(item->opal_tree_container), item)) {
|
||||
return(NULL);
|
||||
}
|
||||
/* we point to a container, check if we can find item in tree */
|
||||
if (!item_in_tree(opal_tree_get_root(item->opal_tree_container), item)) {
|
||||
return(NULL);
|
||||
}
|
||||
} else {
|
||||
return (NULL);
|
||||
return (NULL);
|
||||
}
|
||||
#endif
|
||||
|
||||
parent_item = item->opal_tree_parent;
|
||||
|
||||
/* remove from parent */
|
||||
if (item->opal_tree_parent->opal_tree_first_child ==
|
||||
item) {
|
||||
item->opal_tree_parent->opal_tree_first_child =
|
||||
item->opal_tree_next_sibling;
|
||||
}
|
||||
if (item->opal_tree_parent->opal_tree_last_child ==
|
||||
item) {
|
||||
item->opal_tree_parent->opal_tree_last_child =
|
||||
item->opal_tree_prev_sibling;
|
||||
/* If item is the only child, set _first_child and _last_child to
|
||||
be item's _first_child and _last_child */
|
||||
if (parent_item->opal_tree_first_child == item &&
|
||||
parent_item->opal_tree_last_child == item) {
|
||||
parent_item->opal_tree_first_child = item->opal_tree_first_child;
|
||||
parent_item->opal_tree_last_child = item->opal_tree_last_child;
|
||||
} else {
|
||||
/* Otherwise, there are multiple children of this parent. If
|
||||
this item is the first or last child of this parent, then
|
||||
ensure that the parent gets a valid first / last child:
|
||||
- If I have children, then my first/last child
|
||||
- If I have no children, then my immediate sibling */
|
||||
if (item->opal_tree_parent->opal_tree_first_child == item) {
|
||||
if (item->opal_tree_num_children > 0) {
|
||||
parent_item->opal_tree_first_child =
|
||||
item->opal_tree_next_sibling;
|
||||
} else {
|
||||
parent_item->opal_tree_first_child =
|
||||
opal_tree_get_next_sibling(item);
|
||||
}
|
||||
} else if (parent_item->opal_tree_last_child == item) {
|
||||
if (item->opal_tree_num_children > 0) {
|
||||
parent_item->opal_tree_last_child =
|
||||
item->opal_tree_last_child;
|
||||
} else {
|
||||
parent_item->opal_tree_last_child =
|
||||
opal_tree_get_prev_sibling(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
item->opal_tree_parent->opal_tree_num_children--;
|
||||
|
||||
/* remove from sibling pointers */
|
||||
if (NULL != item->opal_tree_prev_sibling) {
|
||||
item->opal_tree_prev_sibling->opal_tree_next_sibling=
|
||||
item->opal_tree_next_sibling;
|
||||
item->opal_tree_prev_sibling->opal_tree_next_sibling=
|
||||
item->opal_tree_next_sibling;
|
||||
}
|
||||
if (NULL != item->opal_tree_next_sibling) {
|
||||
item->opal_tree_next_sibling->opal_tree_prev_sibling=
|
||||
item->opal_tree_prev_sibling;
|
||||
item->opal_tree_next_sibling->opal_tree_prev_sibling=
|
||||
item->opal_tree_prev_sibling;
|
||||
}
|
||||
item->opal_tree_prev_sibling = NULL;
|
||||
item->opal_tree_next_sibling = NULL;
|
||||
@ -281,6 +310,81 @@ opal_tree_item_t *opal_tree_remove_subtree(opal_tree_item_t *item)
|
||||
return(item);
|
||||
}
|
||||
|
||||
int opal_tree_remove_item(opal_tree_t *tree,
|
||||
opal_tree_item_t *item)
|
||||
{
|
||||
opal_tree_item_t *parent_item = NULL, *child = NULL;
|
||||
|
||||
parent_item = (opal_tree_item_t*)item->opal_tree_parent;
|
||||
|
||||
/*
|
||||
* Point each of my children to my parent
|
||||
*/
|
||||
for(child = opal_tree_get_first_child(item);
|
||||
child != NULL;
|
||||
child = opal_tree_get_next_sibling(child)) {
|
||||
child->opal_tree_parent = parent_item;
|
||||
child->opal_tree_num_ancestors--;
|
||||
|
||||
parent_item->opal_tree_num_children++;
|
||||
}
|
||||
|
||||
/*
|
||||
* My first child points to my 'prev' sibling
|
||||
*/
|
||||
child = opal_tree_get_first_child(item);
|
||||
if( NULL != child ) {
|
||||
child->opal_tree_prev_sibling = item->opal_tree_prev_sibling;
|
||||
}
|
||||
if( NULL != item->opal_tree_prev_sibling ) {
|
||||
(item->opal_tree_prev_sibling)->opal_tree_next_sibling = child;
|
||||
}
|
||||
|
||||
child = opal_tree_get_last_child(item);
|
||||
if( NULL != child ) {
|
||||
child->opal_tree_next_sibling = item->opal_tree_next_sibling;
|
||||
}
|
||||
if( NULL != item->opal_tree_next_sibling ) {
|
||||
(item->opal_tree_next_sibling)->opal_tree_prev_sibling = child;
|
||||
}
|
||||
|
||||
/*
|
||||
* Remove me from my parent. If I was the only child, then make
|
||||
* the first child be my first child, and make the last child be
|
||||
* my last child.
|
||||
*/
|
||||
if( parent_item->opal_tree_first_child == item &&
|
||||
parent_item->opal_tree_last_child == item ) {
|
||||
parent_item->opal_tree_first_child = opal_tree_get_first_child(item);
|
||||
parent_item->opal_tree_last_child = opal_tree_get_last_child(item);
|
||||
} else {
|
||||
/* There were multiple children. If I was the first or last,
|
||||
then ensure the parent gets a valid first or last child:
|
||||
- If I have children, then my first/last
|
||||
- If I have no childen, then my immediate sibling */
|
||||
if (parent_item->opal_tree_first_child == item) {
|
||||
if (item->opal_tree_num_children > 0) {
|
||||
parent_item->opal_tree_first_child =
|
||||
item->opal_tree_first_child;
|
||||
} else {
|
||||
parent_item->opal_tree_first_child =
|
||||
opal_tree_get_next_sibling(item);
|
||||
}
|
||||
} else if (parent_item->opal_tree_last_child == item) {
|
||||
if (item->opal_tree_num_children > 0) {
|
||||
parent_item->opal_tree_last_child =
|
||||
item->opal_tree_last_child;
|
||||
} else {
|
||||
parent_item->opal_tree_last_child =
|
||||
opal_tree_get_prev_sibling(item);
|
||||
}
|
||||
}
|
||||
}
|
||||
parent_item->opal_tree_num_children--;
|
||||
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
/* delimeter characters that mark items in a serialized stream */
|
||||
static char *start_lvl = "[";
|
||||
static char *end_lvl = "]";
|
||||
@ -292,45 +396,45 @@ static char *end_stream = "E";
|
||||
* done the last child of the tree_item and we are at depth 1.
|
||||
*/
|
||||
static int add_tree_item2buf(opal_tree_item_t *tree_item,
|
||||
opal_buffer_t *buf,
|
||||
opal_tree_item_serialize_fn_t fn,
|
||||
int depth
|
||||
)
|
||||
opal_buffer_t *buf,
|
||||
opal_tree_item_serialize_fn_t fn,
|
||||
int depth
|
||||
)
|
||||
{
|
||||
opal_tree_item_t *first_child;
|
||||
int rc;
|
||||
|
||||
do {
|
||||
/* add start delim to buffer */
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &start_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
/* add start delim to buffer */
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &start_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
/* add item to opal buffer from class creator */
|
||||
fn(tree_item, buf);
|
||||
fn(tree_item, buf);
|
||||
|
||||
if ((first_child = opal_tree_get_first_child(tree_item))) {
|
||||
/* add items for our children */
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = add_tree_item2buf(first_child, buf, fn, depth+1))){
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &end_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
(rc = add_tree_item2buf(first_child, buf, fn, depth+1))){
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &end_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
} else {
|
||||
/* end item entry */
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &end_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buf, &end_lvl, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
}
|
||||
|
||||
/* advance to next sibling, if none we'll drop out of
|
||||
* loop and return to our parent
|
||||
*/
|
||||
tree_item = opal_tree_get_next_sibling(tree_item);
|
||||
/* advance to next sibling, if none we'll drop out of
|
||||
* loop and return to our parent
|
||||
*/
|
||||
tree_item = opal_tree_get_next_sibling(tree_item);
|
||||
} while (tree_item && 1 < depth);
|
||||
|
||||
return(OPAL_SUCCESS);
|
||||
@ -344,33 +448,33 @@ int opal_tree_serialize(opal_tree_item_t *start_item, opal_buffer_t *buffer)
|
||||
int rc;
|
||||
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = add_tree_item2buf(start_item, buffer,
|
||||
start_item->opal_tree_container->serialize,
|
||||
1))){
|
||||
return(rc);
|
||||
(rc = add_tree_item2buf(start_item, buffer,
|
||||
start_item->opal_tree_container->serialize,
|
||||
1))){
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.pack(buffer, &end_stream, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
(rc = opal_dss.pack(buffer, &end_stream, 1, OPAL_STRING))){
|
||||
return(rc);
|
||||
}
|
||||
return(OPAL_SUCCESS);
|
||||
}
|
||||
|
||||
static int deserialize_add_tree_item(opal_buffer_t *data,
|
||||
opal_tree_item_t *parent_item,
|
||||
opal_tree_item_deserialize_fn_t deserialize,
|
||||
char *curr_delim,
|
||||
int depth)
|
||||
opal_tree_item_t *parent_item,
|
||||
opal_tree_item_deserialize_fn_t deserialize,
|
||||
char *curr_delim,
|
||||
int depth)
|
||||
{
|
||||
int idx = 1, rc;
|
||||
opal_tree_item_t *new_item = NULL;
|
||||
int level = 0; /* 0 - one up 1 - curr, 2 - one down */
|
||||
|
||||
if (!curr_delim) {
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.unpack(data, &curr_delim, &idx, OPAL_STRING))) {
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.unpack(data, &curr_delim, &idx, OPAL_STRING))) {
|
||||
return(rc);
|
||||
}
|
||||
}
|
||||
while(curr_delim[0] != end_stream[0]) {
|
||||
if (curr_delim[0] == start_lvl[0]) {
|
||||
@ -394,14 +498,14 @@ static int deserialize_add_tree_item(opal_buffer_t *data,
|
||||
case 2:
|
||||
/* need to add child one level down */
|
||||
deserialize_add_tree_item(data, new_item, deserialize, curr_delim,
|
||||
depth+1);
|
||||
depth+1);
|
||||
level--;
|
||||
break;
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.unpack(data, &curr_delim, &idx, OPAL_STRING))) {
|
||||
return(rc);
|
||||
}
|
||||
if (OPAL_SUCCESS !=
|
||||
(rc = opal_dss.unpack(data, &curr_delim, &idx, OPAL_STRING))) {
|
||||
return(rc);
|
||||
}
|
||||
}
|
||||
return(OPAL_SUCCESS);
|
||||
}
|
||||
@ -410,16 +514,134 @@ static int deserialize_add_tree_item(opal_buffer_t *data,
|
||||
* deserialize tree data
|
||||
*/
|
||||
int opal_tree_deserialize(opal_buffer_t *serialized_data,
|
||||
opal_tree_item_t *start_item)
|
||||
opal_tree_item_t *start_item)
|
||||
{
|
||||
deserialize_add_tree_item(serialized_data,
|
||||
start_item,
|
||||
start_item->opal_tree_container->deserialize,
|
||||
NULL,
|
||||
NULL,
|
||||
1);
|
||||
return OPAL_SUCCESS;
|
||||
}
|
||||
|
||||
void * opal_tree_get_key(opal_tree_t *tree, opal_tree_item_t *item)
|
||||
{
|
||||
return tree->get_key(item);
|
||||
}
|
||||
|
||||
int opal_tree_dup(opal_tree_t *from, opal_tree_t *to)
|
||||
{
|
||||
int ret;
|
||||
opal_buffer_t *buffer = NULL;
|
||||
|
||||
opal_tree_init(to,
|
||||
from->comp,
|
||||
from->serialize,
|
||||
from->deserialize,
|
||||
from->get_key);
|
||||
|
||||
buffer = OBJ_NEW(opal_buffer_t);
|
||||
|
||||
opal_tree_serialize(opal_tree_get_root(from), buffer);
|
||||
ret = opal_tree_deserialize(buffer, opal_tree_get_root(to));
|
||||
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int opal_tree_copy_subtree(opal_tree_t *from_tree, opal_tree_item_t *from_item,
|
||||
opal_tree_t *to_tree, opal_tree_item_t *to_parent)
|
||||
{
|
||||
int ret;
|
||||
opal_buffer_t *buffer = NULL;
|
||||
|
||||
buffer = OBJ_NEW(opal_buffer_t);
|
||||
|
||||
opal_tree_serialize(from_item, buffer);
|
||||
ret = opal_tree_deserialize(buffer, to_parent);
|
||||
|
||||
OBJ_RELEASE(buffer);
|
||||
return ret;
|
||||
}
|
||||
|
||||
opal_tree_item_t *opal_tree_dup_item(opal_tree_t *base, opal_tree_item_t *from)
|
||||
{
|
||||
int ret;
|
||||
opal_buffer_t *buffer = NULL;
|
||||
opal_tree_item_t *new_item = NULL;
|
||||
|
||||
buffer = OBJ_NEW(opal_buffer_t);
|
||||
|
||||
opal_tree_serialize(from, buffer);
|
||||
|
||||
new_item = OBJ_NEW(opal_tree_item_t);
|
||||
ret = opal_tree_deserialize(buffer, new_item);
|
||||
|
||||
OBJ_RELEASE(buffer);
|
||||
return new_item;
|
||||
}
|
||||
|
||||
int opal_tree_num_children(opal_tree_item_t *parent)
|
||||
{
|
||||
opal_tree_item_t *child = NULL;
|
||||
int i = 0;
|
||||
|
||||
for(child = opal_tree_get_first_child(parent);
|
||||
child != NULL;
|
||||
child = opal_tree_get_next_sibling(child) ) {
|
||||
++i;
|
||||
}
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int opal_tree_compare_subtrees(opal_tree_t *tree_left, opal_tree_t *tree_right,
|
||||
opal_tree_item_t *left, opal_tree_item_t *right)
|
||||
{
|
||||
int ret;
|
||||
opal_tree_item_t *left_child = NULL, *right_child = NULL;
|
||||
|
||||
/* Basecase */
|
||||
if( NULL == left && NULL == right ) {
|
||||
return 0; /* Match */
|
||||
}
|
||||
|
||||
/* Compare: Depth */
|
||||
if( NULL == left && NULL != right ) {
|
||||
return -1;
|
||||
}
|
||||
else if( NULL != left && NULL == right ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Compare: Keys */
|
||||
if( 0 != tree_left->comp(right, opal_tree_get_key(tree_left, left)) ) {
|
||||
return -2;
|
||||
}
|
||||
|
||||
/* Compare: Number of children */
|
||||
if( opal_tree_num_children(left) != opal_tree_num_children(right) ) {
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* Recursively compare all children */
|
||||
for(left_child = opal_tree_get_first_child(left), right_child = opal_tree_get_first_child(right);
|
||||
left_child != NULL && right_child != NULL;
|
||||
left_child = opal_tree_get_next_sibling(left_child), right_child = opal_tree_get_next_sibling(right_child) ) {
|
||||
/* On first difference, return the result */
|
||||
if( 0 != (ret = opal_tree_compare_subtrees(tree_left, tree_right, left_child, right_child)) ) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int opal_tree_compare(opal_tree_t *left, opal_tree_t *right)
|
||||
{
|
||||
return opal_tree_compare_subtrees(left, right, opal_tree_get_root(left), opal_tree_get_root(right));
|
||||
}
|
||||
|
||||
/*
|
||||
* search myself, descendants and siblings for item matching key
|
||||
*/
|
||||
|
@ -1,5 +1,7 @@
|
||||
/*
|
||||
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||
* Copyright (c) 2011 Oak Ridge National Labs. All rights reserved.
|
||||
*
|
||||
* $COPYRIGHT$
|
||||
*
|
||||
* Additional copyrights may follow
|
||||
@ -167,6 +169,11 @@ typedef int (*opal_tree_item_serialize_fn_t)(opal_tree_item_t *item,
|
||||
typedef int (*opal_tree_item_deserialize_fn_t)(opal_buffer_t *buffer,
|
||||
opal_tree_item_t **item);
|
||||
|
||||
/**
|
||||
* Get the 'key' associated with this item
|
||||
*/
|
||||
typedef void *(*opal_tree_get_key_fn_t)(opal_tree_item_t *item);
|
||||
|
||||
/**
|
||||
* \internal
|
||||
*
|
||||
@ -187,6 +194,8 @@ typedef struct opal_tree_t
|
||||
opal_tree_item_serialize_fn_t serialize;
|
||||
/** Function to deserialize tree item data */
|
||||
opal_tree_item_deserialize_fn_t deserialize;
|
||||
/**< Function to deserialize tree item data */
|
||||
opal_tree_get_key_fn_t get_key;
|
||||
} opal_tree_t;
|
||||
|
||||
/** Macros to access items in the tree */
|
||||
@ -347,7 +356,8 @@ OPAL_DECLSPEC size_t opal_tree_get_size(opal_tree_t* tree);
|
||||
OPAL_DECLSPEC void opal_tree_init(opal_tree_t *tree,
|
||||
opal_tree_comp_fn_t comp,
|
||||
opal_tree_item_serialize_fn_t serialize,
|
||||
opal_tree_item_deserialize_fn_t deserialize);
|
||||
opal_tree_item_deserialize_fn_t deserialize,
|
||||
opal_tree_get_key_fn_t get_key);
|
||||
|
||||
/**
|
||||
* Add new item as child to its parent item
|
||||
@ -381,6 +391,18 @@ OPAL_DECLSPEC void opal_tree_add_child(opal_tree_item_t *parent_item,
|
||||
* in the tree before doing pointer manipulation.
|
||||
*/
|
||||
OPAL_DECLSPEC opal_tree_item_t *opal_tree_remove_subtree(opal_tree_item_t *item);
|
||||
|
||||
/**
|
||||
* Remove an item, everything below inherited by parent.
|
||||
*
|
||||
* @param tree Tree from which to remove
|
||||
* @param item The item to remove
|
||||
*
|
||||
* @returns Success/Failure
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_tree_remove_item(opal_tree_t *tree,
|
||||
opal_tree_item_t *item);
|
||||
|
||||
/**
|
||||
* Serialize tree data
|
||||
*
|
||||
@ -422,6 +444,66 @@ OPAL_DECLSPEC int opal_tree_serialize(opal_tree_item_t *start_item,
|
||||
OPAL_DECLSPEC int opal_tree_deserialize(opal_buffer_t *buffer,
|
||||
opal_tree_item_t *start_item);
|
||||
|
||||
/**
|
||||
* Access the 'key' associated with the item
|
||||
*
|
||||
* @param tree Source Tree
|
||||
* @param item Item to access key of
|
||||
*
|
||||
* @returns Success/Failure
|
||||
*/
|
||||
OPAL_DECLSPEC void * opal_tree_get_key(opal_tree_t *tree, opal_tree_item_t *item);
|
||||
|
||||
/**
|
||||
* Copy/Duplicate a tree (requires serialize/deserialize)
|
||||
*
|
||||
* @param from Source tree to copy 'from'
|
||||
* @param to Destination tree to copy 'to'
|
||||
*
|
||||
* @returns Success/Failure
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_tree_dup(opal_tree_t *from, opal_tree_t *to);
|
||||
|
||||
/**
|
||||
* Copy/Duplicate a subtree (requires serialize/deserialize)
|
||||
*
|
||||
* @param base Base tree
|
||||
* @param from Source tree item to copy 'from'
|
||||
*
|
||||
* @returns Tree item copy
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_tree_copy_subtree(opal_tree_t *from_tree, opal_tree_item_t *from_item,
|
||||
opal_tree_t *to_tree, opal_tree_item_t *to_parent);
|
||||
|
||||
/**
|
||||
* Copy/Duplicate a tree item (requires serialize/deserialize)
|
||||
*
|
||||
* @param base Base tree
|
||||
* @param from Source tree item to copy 'from'
|
||||
*
|
||||
* @returns Tree item copy
|
||||
*/
|
||||
OPAL_DECLSPEC opal_tree_item_t *opal_tree_dup_item(opal_tree_t *base, opal_tree_item_t *from);
|
||||
|
||||
/**
|
||||
* Count the number of children of this parent
|
||||
*
|
||||
* @param parent A parent node in the tree
|
||||
*
|
||||
* @returns Number of children of this parent
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_tree_num_children(opal_tree_item_t *parent);
|
||||
|
||||
/**
|
||||
* Compare two trees
|
||||
*
|
||||
* @param left Tree
|
||||
* @param right Tree
|
||||
*
|
||||
* @returns 0 if identical, ow returns non-zero
|
||||
*/
|
||||
OPAL_DECLSPEC int opal_tree_compare(opal_tree_t *left, opal_tree_t *right);
|
||||
|
||||
/* Functions to search for items on tree */
|
||||
/**
|
||||
* Return the next tree item that matches key provided
|
||||
|
Загрузка…
x
Ссылка в новой задаче
Block a user