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
add node summary string methods #698
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -11981,6 +11981,341 @@ Node::to_string_default() const | |
return to_string(); | ||
} | ||
|
||
|
||
|
||
//----------------------------------------------------------------------------- | ||
// -- Summary string construction methods --- | ||
//----------------------------------------------------------------------------- | ||
|
||
//----------------------------------------------------------------------------- | ||
std::string | ||
Node::to_summary_string()const | ||
{ | ||
Node opts; | ||
return to_summary_string(opts); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
std::string | ||
Node::to_summary_string(const conduit::Node &opts)const | ||
{ | ||
std::ostringstream oss; | ||
to_summary_string_stream(oss,opts); | ||
return oss.str(); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
void | ||
Node::to_summary_string_stream(std::ostream &os, | ||
const conduit::Node &opts) const | ||
{ | ||
// unpack options and enforce defaults | ||
index_t num_children_threshold = 7; | ||
index_t num_elements_threshold = 5; | ||
index_t indent = 2; | ||
index_t depth = 0; | ||
std::string pad = " "; | ||
std::string eoe = "\n"; | ||
|
||
if(opts.has_child("num_children_threshold") && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I know we're using There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I used There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
opts["num_children_threshold"].dtype().is_number()) | ||
{ | ||
num_children_threshold = (index_t)opts["num_children_threshold"].to_int32(); | ||
} | ||
|
||
if(opts.has_child("num_elements_threshold") && | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Might it be useful to include a max/threshold on tree There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i agree, we should do that in the future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added #701 to track this |
||
opts["num_elements_threshold"].dtype().is_number()) | ||
{ | ||
num_elements_threshold = (index_t)opts["num_elements_threshold"].to_int32(); | ||
} | ||
|
||
if(opts.has_child("indent") && | ||
opts["indent"].dtype().is_number()) | ||
{ | ||
indent = (index_t)opts["indent"].to_int32(); | ||
} | ||
|
||
if(opts.has_child("depth") && | ||
opts["depth"].dtype().is_number()) | ||
{ | ||
depth = (index_t)opts["depth"].to_int32(); | ||
} | ||
|
||
if(opts.has_child("pad") && | ||
opts["pad"].dtype().is_string()) | ||
{ | ||
pad = opts["pad"].as_string(); | ||
} | ||
|
||
if(opts.has_child("eoe") && | ||
opts["eoe"].dtype().is_string()) | ||
{ | ||
eoe = opts["eoe"].as_string(); | ||
} | ||
|
||
to_summary_string_stream(os, | ||
num_children_threshold, | ||
num_elements_threshold, | ||
indent, | ||
depth, | ||
pad, | ||
eoe); | ||
} | ||
|
||
|
||
//----------------------------------------------------------------------------- | ||
//-- (private interface) | ||
//----------------------------------------------------------------------------- | ||
void | ||
Node::to_summary_string_stream(const std::string &stream_path, | ||
const conduit::Node &opts) const | ||
{ | ||
std::ofstream ofs; | ||
ofs.open(stream_path.c_str()); | ||
if(!ofs.is_open()) | ||
{ | ||
CONDUIT_ERROR("<Node::to_summary_string_stream> failed to open file: " | ||
<< "\"" << stream_path << "\""); | ||
} | ||
to_summary_string_stream(ofs,opts); | ||
ofs.close(); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
std::string | ||
Node::to_summary_string_default() const | ||
{ | ||
return to_summary_string(); | ||
} | ||
|
||
|
||
//----------------------------------------------------------------------------- | ||
//-- (private interface) | ||
//----------------------------------------------------------------------------- | ||
void | ||
Node::to_summary_string_stream(std::ostream &os, | ||
index_t num_children_threshold, | ||
index_t num_elements_threshold, | ||
index_t indent, | ||
index_t depth, | ||
const std::string &pad, | ||
const std::string &eoe) const | ||
{ | ||
// rubber, say hello to the road: | ||
|
||
std::ios_base::fmtflags prev_stream_flags(os.flags()); | ||
os.precision(15); | ||
if(dtype().id() == DataType::OBJECT_ID) | ||
{ | ||
os << eoe; | ||
int nchildren = m_children.size(); | ||
int threshold = num_children_threshold; | ||
|
||
// if we are neg or zero, show all children | ||
if(threshold <=0) | ||
{ | ||
threshold = nchildren; | ||
} | ||
|
||
// if above threshold only show threshold # of values | ||
int half = threshold / 2; | ||
int bottom = half; | ||
int top = half; | ||
int num_skipped = m_children.size() - threshold; | ||
|
||
// | ||
// if odd, show 1/2 +1 first | ||
// | ||
|
||
if( (threshold % 2) > 0) | ||
{ | ||
bottom++; | ||
} | ||
|
||
bool done = (nchildren == 0); | ||
int idx = 0; | ||
|
||
while(!done) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The code in these loops is rather hard for me to follow. I think using the lambdas we're afforded by C++11 could make it much more legible, e.g.:
Just my 2 cents here; I don't mind keeping this as is for the sake of expediency. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. added #699 to track this. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (i think this is great idea) |
||
{ | ||
utils::indent(os,indent,depth,pad); | ||
os << m_schema->object_order()[idx] << ": "; | ||
m_children[idx]->to_summary_string_stream(os, | ||
num_children_threshold, | ||
num_elements_threshold, | ||
indent, | ||
depth+1, | ||
pad, | ||
eoe); | ||
|
||
// if the child is a leaf, we need eoe | ||
if(m_children[idx]->number_of_children() == 0) | ||
os << eoe; | ||
|
||
idx++; | ||
|
||
if(idx == bottom && num_skipped > 0) | ||
{ | ||
utils::indent(os,indent,depth,pad); | ||
idx = nchildren - top; | ||
os << "... ( skipped " | ||
<< num_skipped; | ||
if( num_skipped == 1) | ||
{ | ||
os << " child )"; | ||
} | ||
else | ||
{ | ||
os << " children )"; | ||
} | ||
os << eoe; | ||
} | ||
|
||
if(idx == nchildren) | ||
{ | ||
done = true; | ||
} | ||
} | ||
} | ||
else if(dtype().id() == DataType::LIST_ID) | ||
{ | ||
os << eoe; | ||
int nchildren = m_children.size(); | ||
int threshold = num_children_threshold; | ||
|
||
// if we are neg or zero, show all children | ||
if(threshold <=0) | ||
{ | ||
threshold = nchildren; | ||
} | ||
|
||
// if above threshold only show threshold # of values | ||
int half = threshold / 2; | ||
int bottom = half; | ||
int top = half; | ||
int num_skipped = m_children.size() - threshold; | ||
|
||
// | ||
// if odd, show 1/2 +1 first | ||
// | ||
|
||
if( (threshold % 2) > 0) | ||
{ | ||
bottom++; | ||
} | ||
|
||
bool done = (nchildren == 0); | ||
int idx = 0; | ||
|
||
while(!done) | ||
{ | ||
utils::indent(os,indent,depth,pad); | ||
os << "- "; | ||
m_children[idx]->to_summary_string_stream(os, | ||
num_children_threshold, | ||
num_elements_threshold, | ||
indent, | ||
depth+1, | ||
pad, | ||
eoe); | ||
|
||
// if the child is a leaf, we need eoe | ||
if(m_children[idx]->number_of_children() == 0) | ||
os << eoe; | ||
|
||
idx++; | ||
|
||
if(idx == bottom && num_skipped > 0) | ||
{ | ||
utils::indent(os,indent,depth,pad); | ||
idx = nchildren - top; | ||
os << "... ( skipped " | ||
<< num_skipped; | ||
if( num_skipped == 1) | ||
{ | ||
os << " child )"; | ||
} | ||
else | ||
{ | ||
os << " children )"; | ||
} | ||
os << eoe; | ||
} | ||
|
||
if(idx == nchildren) | ||
{ | ||
done = true; | ||
} | ||
} | ||
} | ||
else // assume leaf data type | ||
{ | ||
// if we are neg or zero, show full array | ||
// | ||
if(num_elements_threshold <= 0) | ||
{ | ||
num_elements_threshold = dtype().number_of_elements(); | ||
} | ||
|
||
switch(dtype().id()) | ||
{ | ||
// ints | ||
case DataType::INT8_ID: | ||
as_int8_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::INT16_ID: | ||
as_int16_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::INT32_ID: | ||
as_int32_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::INT64_ID: | ||
as_int64_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
// uints | ||
case DataType::UINT8_ID: | ||
as_uint8_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::UINT16_ID: | ||
as_uint16_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::UINT32_ID: | ||
as_uint32_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::UINT64_ID: | ||
as_uint64_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
// floats | ||
case DataType::FLOAT32_ID: | ||
as_float32_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
case DataType::FLOAT64_ID: | ||
as_float64_array().to_summary_string_stream(os, | ||
num_elements_threshold); | ||
break; | ||
// char8_str | ||
case DataType::CHAR8_STR_ID: | ||
os << "\"" | ||
<< utils::escape_special_chars(as_string()) | ||
<< "\""; | ||
break; | ||
// empty | ||
case DataType::EMPTY_ID: | ||
break; | ||
} | ||
} | ||
|
||
os.flags(prev_stream_flags); | ||
} | ||
|
||
//----------------------------------------------------------------------------- | ||
// -- JSON construction methods --- | ||
//----------------------------------------------------------------------------- | ||
|
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.
Is the idea that the other
conduit::Node::to_*
methods are moving to an optionsconduit::Node
approach? This seems like a break from convention otherwise.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 would like to move in that direction, number of options is getting large.
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.
added: #700 to track this