moab
|
00001 00015 #ifndef TREESTATS_HPP 00016 #define TREESTATS_HPP 00017 00018 #include "moab/Interface.hpp" 00019 00020 #include <vector> 00021 #include <iostream> 00022 #include <string> 00023 00024 namespace moab 00025 { 00026 class TreeStats{ 00027 public: 00029 TreeStats() {reset();} 00030 00035 ErrorCode compute_stats(Interface *impl, EntityHandle root_node); 00036 00038 void reset_trav_stats(); 00039 00041 void reset(); 00042 00044 void print() const ; 00045 00047 void output_all_stats(const bool with_endl = true) const ; 00048 00050 void output_trav_stats(const bool with_endl = true) const ; 00051 00052 // times 00053 double initTime; 00054 00055 // tree stats that depend only on structure (not traversal) 00056 unsigned int maxDepth; 00057 unsigned int numNodes; 00058 unsigned int numLeaves; 00059 double avgObjPerLeaf; 00060 unsigned int minObjPerLeaf; 00061 unsigned int maxObjPerLeaf; 00062 00063 00064 // traversal statistics 00065 unsigned int nodesVisited; // number of tree nodes visited since last reset 00066 unsigned int leavesVisited; // number of tree leaves visited since last reset 00067 unsigned int numTraversals; // number of tree traversals since last reset 00068 unsigned int constructLeafObjectTests; // during construction, number of tests of objects (e.g. elements) 00069 unsigned int traversalLeafObjectTests; // during traversals, number of tests of objects (e.g. elements) 00070 unsigned int boxElemTests; // during construction, number of calls to GeomUtil::box_elem_overlap (KD tree only) 00071 00072 private: 00073 ErrorCode traverse(Interface *impl, EntityHandle node, unsigned int &depth); 00074 00075 }; 00076 00077 inline ErrorCode TreeStats::compute_stats(Interface *impl, EntityHandle root_node) 00078 { 00079 maxDepth = 0; 00080 numNodes = 0; 00081 numLeaves = 0; 00082 avgObjPerLeaf = 0.0; 00083 minObjPerLeaf = 0; 00084 maxObjPerLeaf = 0; 00085 00086 ErrorCode rval = traverse(impl, root_node, maxDepth); 00087 avgObjPerLeaf = (avgObjPerLeaf > 0 ? avgObjPerLeaf/(double)numLeaves : 0.0); 00088 return rval; 00089 } 00090 00091 inline ErrorCode TreeStats::traverse(Interface *impl, EntityHandle node, unsigned int &depth) 00092 { 00093 depth++; 00094 numNodes++; 00095 std::vector<EntityHandle> children; 00096 children.reserve(2); 00097 ErrorCode rval = impl->get_child_meshsets(node, children); 00098 if (MB_SUCCESS != rval) return rval; 00099 if (children.empty()) { 00100 numLeaves++; 00101 rval = impl->get_entities_by_handle(node, children); 00102 if (MB_SUCCESS != rval) return rval; 00103 avgObjPerLeaf += children.size(); 00104 minObjPerLeaf = std::min((unsigned int)children.size(), minObjPerLeaf); 00105 maxObjPerLeaf = std::max((unsigned int)children.size(), maxObjPerLeaf); 00106 return MB_SUCCESS; 00107 } 00108 else { 00109 unsigned int right_depth = depth, left_depth = depth; 00110 rval = traverse(impl, children[0], left_depth); 00111 if (MB_SUCCESS != rval) return rval; 00112 rval = traverse(impl, children[1], right_depth); 00113 if (MB_SUCCESS != rval) return rval; 00114 depth = std::max(left_depth, right_depth); 00115 return MB_SUCCESS; 00116 } 00117 } 00118 00119 inline void TreeStats::reset() 00120 { 00121 initTime = 0.0; 00122 00123 maxDepth = 0; 00124 numNodes = 0; 00125 numLeaves = 0; 00126 constructLeafObjectTests = 0; 00127 boxElemTests = 0; 00128 avgObjPerLeaf = 0.0; 00129 minObjPerLeaf = 0.0; 00130 maxObjPerLeaf = 0.0; 00131 00132 reset_trav_stats(); 00133 } 00134 00135 inline void TreeStats::reset_trav_stats() 00136 { 00137 nodesVisited = 0; 00138 leavesVisited = 0; 00139 numTraversals = 0; 00140 traversalLeafObjectTests = 0; 00141 } 00142 00143 inline void TreeStats::print() const { 00144 std::cout << "Tree initialization time = " << initTime << " seconds" << std::endl; 00145 00146 std::cout << "Num nodes = " << numNodes << std::endl; 00147 std::cout << "Num leaves = " << numLeaves << std::endl; 00148 std::cout << "Max depth = " << maxDepth << std::endl << std::endl; 00149 00150 std::cout << "Avg objs per leaf = " << avgObjPerLeaf << std::endl; 00151 std::cout << "Min objs per leaf = " << minObjPerLeaf << std::endl; 00152 std::cout << "Max objs per leaf = " << maxObjPerLeaf << std::endl; 00153 00154 std::cout << "Construction Leaf Object Tests = " << constructLeafObjectTests << std::endl; 00155 std::cout << "Box-Element Tests = " << boxElemTests << std::endl; 00156 00157 std::cout << "NodesVisited = " << nodesVisited << std::endl; 00158 std::cout << "LeavesVisited = " << leavesVisited << std::endl; 00159 std::cout << "Num Traversals = " << numTraversals << std::endl; 00160 std::cout << "Traversal Leaf Object Tests = " << traversalLeafObjectTests << std::endl; 00161 } 00162 00163 inline void TreeStats::output_all_stats(const bool with_endl) const 00164 { 00165 std::cout << initTime << " " << numNodes << " " << numLeaves << " " << maxDepth << " " 00166 << avgObjPerLeaf << " " << minObjPerLeaf << " " << maxObjPerLeaf << " " 00167 << constructLeafObjectTests << " " << boxElemTests << " " 00168 << nodesVisited << " " << leavesVisited << " " << numTraversals << " " << traversalLeafObjectTests << " "; 00169 if (with_endl) std::cout << std::endl; 00170 } 00171 00172 inline void TreeStats::output_trav_stats(const bool with_endl) const 00173 { 00174 std::cout << nodesVisited << " " << leavesVisited << " " << numTraversals << " " << traversalLeafObjectTests << " "; 00175 if (with_endl) std::cout << std::endl; 00176 } 00177 } 00178 00179 00180 00181 00182 00183 #endif