Skip to content

Commit

Permalink
add contiguous_data_ptr() method to Node
Browse files Browse the repository at this point in the history
if a Node is contiguous, contiguous_data_ptr() returns the start
address of the data of the node. If a Node is not contiguous,
returns contiguous_data_ptr() NULL.
  • Loading branch information
cyrush committed May 23, 2017
1 parent 5d32623 commit 61b406e
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 0 deletions.
56 changes: 56 additions & 0 deletions src/libs/conduit/conduit_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13391,6 +13391,62 @@ Node::contiguous_with(uint8 *start_addy, uint8 *&end_addy) const
return res;
}

//---------------------------------------------------------------------------//
void *
Node::contiguous_data_ptr()
{
if(!is_contiguous())
{
return NULL;
}

// if contiguous, we simply need the first non null pointer.
// Note: use const_cast so we can share the same helper func
return const_cast<void*>(find_first_data_ptr());
}

//---------------------------------------------------------------------------//
const void *
Node::contiguous_data_ptr() const
{
if(!is_contiguous())
{
return NULL;
}

// if contiguous, we simply need the first non null pointer.
return find_first_data_ptr();
}

//---------------------------------------------------------------------------//
const void *
Node::find_first_data_ptr() const
{
const void *res = NULL;

index_t dtype_id = dtype().id();

if(dtype_id == DataType::OBJECT_ID ||
dtype_id == DataType::LIST_ID)
{
std::vector<Node*>::const_iterator itr;
for(itr = m_children.begin();
itr < m_children.end() && res == NULL; // stop if found
++itr)
{
// recurse
res = (*itr)->find_first_data_ptr();
}
}
// empty should always be NULL, but keep check since it follows form
// of is_contig
else if(dtype_id != DataType::EMPTY_ID)
{
res = element_ptr(0);
}

return res;
}

//---------------------------------------------------------------------------//
void
Expand Down
10 changes: 10 additions & 0 deletions src/libs/conduit/conduit_node.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -3188,6 +3188,12 @@ class CONDUIT_API Node
bool contiguous_with(void *address) const;


/// if this node has a contiguous data layout, returns
/// the start address of its memory, otherwise returns NULL

void *contiguous_data_ptr();
const void *contiguous_data_ptr() const;

/// is this node compatible with given node
bool compatible(const Node &n) const
{return m_schema->compatible(n.schema());}
Expand Down Expand Up @@ -3757,6 +3763,10 @@ class CONDUIT_API Node
void info(Node &res,
const std::string &curr_path) const;

/// helper that finds the first non null data pointer, used by
/// contiguous_data_ptr()
const void *find_first_data_ptr() const;

//-----------------------------------------------------------------------------
//
// -- private to_json helpers --
Expand Down
35 changes: 35 additions & 0 deletions src/tests/conduit/t_conduit_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -679,16 +679,22 @@ TEST(conduit_node, check_contiguous)
EXPECT_TRUE(n.is_compact());
// but not contig
EXPECT_FALSE(n.is_contiguous());
// contig dptr should be null if not contig
EXPECT_FALSE(n.contiguous_data_ptr() != NULL);

// compact to create compact + contig
Node n2;
n.compact_to(n2);
EXPECT_TRUE(n2.is_compact());
EXPECT_TRUE(n2.is_contiguous());
// contig dptr should not be null if contig
EXPECT_TRUE(n2.contiguous_data_ptr() != NULL);

// no longer contig
n2["e"] = 10;
EXPECT_FALSE(n2.is_contiguous());
// contig dptr should be null if not contig
EXPECT_FALSE(n2.contiguous_data_ptr() != NULL);
// still compact
EXPECT_TRUE(n2.is_compact());

Expand All @@ -697,17 +703,45 @@ TEST(conduit_node, check_contiguous)
n3["a"].set_external(u64av,2);
n3["b"].set_external(u64av,4,sizeof(uint64)*2);
EXPECT_TRUE(n3.is_contiguous());
// contig dptr should not be null if contig
EXPECT_TRUE(n3.contiguous_data_ptr() != NULL);


// make non contig
n3["c"].set_external(u64av,3,sizeof(uint64)*3);
EXPECT_FALSE(n3.is_contiguous());
// contig dptr should be null if not contig
EXPECT_TRUE(n3.contiguous_data_ptr() == NULL);


// contig but not compact
Node n4;
n4["a"].set_external(u64av,2);
n4["b"].set_external(u64av,2,sizeof(uint64)*2,sizeof(uint64)*2);
EXPECT_FALSE(n4.is_compact());
EXPECT_TRUE(n4.is_contiguous());


// nested contig and compact
Node n5;
n5["a/b/c/d/e/f"].set_int64(10);

EXPECT_TRUE(n5.is_compact());
EXPECT_TRUE(n5.is_contiguous());

void *n5_contg_ptr = n5.contiguous_data_ptr();

// contig dptr should be null if not contig
EXPECT_TRUE(n5_contg_ptr != NULL);

// check loc and value of contig dptr

EXPECT_EQ(n5_contg_ptr,
n5["a/b/c/d/e/f"].data_ptr());

int64 *n5_v_ptr = (int64*)n5_contg_ptr;
EXPECT_EQ(n5_v_ptr[0],
n5["a/b/c/d/e/f"].as_int64());


}
Expand Down Expand Up @@ -773,6 +807,7 @@ TEST(conduit_node, check_contiguous_with)

}


//-----------------------------------------------------------------------------
TEST(conduit_node, check_path)
{
Expand Down

0 comments on commit 61b406e

Please sign in to comment.