profile.h
Go to the documentation of this file.
1 // *****************************************************************************
2 //
3 // Copyright (c) 2015, Southwest Research Institute® (SwRI®)
4 // All rights reserved.
5 //
6 // Redistribution and use in source and binary forms, with or without
7 // modification, are permitted provided that the following conditions are met:
8 // * Redistributions of source code must retain the above copyright
9 // notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 // notice, this list of conditions and the following disclaimer in the
12 // documentation and/or other materials provided with the distribution.
13 // * Neither the name of Southwest Research Institute® (SwRI®) nor the
14 // names of its contributors may be used to endorse or promote products
15 // derived from this software without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 // ARE DISCLAIMED. IN NO EVENT SHALL Southwest Research Institute® BE LIABLE
21 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
23 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
24 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
27 // DAMAGE.
28 //
29 // *****************************************************************************
30 
31 #ifndef SWRI_PROFILER_TOOLS_PROFILE_H_
32 #define SWRI_PROFILER_TOOLS_PROFILE_H_
33 
34 #include <deque>
35 #include <set>
36 #include <map>
37 #include <unordered_map>
38 
39 #include <QObject>
40 #include <QString>
41 #include <QStringList>
43 
44 namespace swri_profiler_tools
45 {
46 class ProfileDatabase;
47 
49 {
50 
51  public:
52  // projected is for internal use in the profiler. This flag
53  // indicates that the item's current data was projected from a
54  // previous data point. This is used to keep the profile data
55  // consistent despite missing or late data. This flag only applies
56  // to data in measured nodes.
57 
58  bool projected;
65 
67  :
68  projected(false),
75  {}
76 }; // class ProfileEntry
77 
79 {
80  // This is the node's key within it's profile. It must be positive
81  // to be a valid node.
82  int node_key_;
83 
84  // The name of this node. This is the last element of the path (c
85  // in a/b/c).
86  QString name_;
87 
88  // The full path of the node in the call tree. (e.g. a/b/c)
89  QString path_;
90 
91  // Nodes can be either measured or inferred. Measured nodes have
92  // their inclusive timing information provided by the profiler.
93  // These are your typical blocks measured by
94  // SWRI_PROFILE(). Inferred nodes are nodes that were created to
95  // fill in the call tree. These are typically your root node and
96  // nodes corresponding to ROS namespaces.
97  bool measured_;
98 
99  // The data stored by the node. The array is managed by the
100  // profile. Each element corresponds to a time which is determined
101  // by the Profile's min_time and max_time.
102  std::deque<ProfileEntry> data_;
103 
104  // The node's depth in the tree.
105  int depth_;
106 
107  // The key of this node's parent node. This will be invalid
108  // (negative) for the root node.
109  int parent_;
110 
111  // They node's children, in alphabetical order according to their
112  // paths.
113  std::vector<int> children_;
114 
115  // The ProfileNode is a "dumb" data storage object with read-only
116  // access to the rest of the world. The node is managed and
117  // manipulated directly by the profile.
118  friend class Profile;
119 
120  public:
122  :
123  node_key_(-1),
124  measured_(false),
125  depth_(-1),
126  parent_(-1)
127  {}
128 
129  bool isValid() const { return node_key_ >= 0; }
130  int nodeKey() const { return node_key_; }
131  const QString& name() const { return name_; }
132  const QString& path() const { return path_; }
133  bool isMeasured() const { return measured_; }
134  const std::deque<ProfileEntry>& data() const { return data_; }
135  int depth() const { return depth_; }
136  int parentKey() const { return parent_; }
137  const std::vector<int>& childKeys() const { return children_; }
138  bool hasChildren() const { return !children_.empty(); }
139 }; // class ProfileNode
140 
141 class Profile : public QObject
142 {
143  Q_OBJECT;
144 
145 
146  // The key of this profile in the database. This is negative for
147  // an invalid profile.
148  int profile_key_;
149 
150  // Name of the profile. This is initialized by the source and may
151  // be modified by the user.
152  QString name_;
153 
154  // All node data is stored in dense arrays of the same size. The
155  // min_time_s_ and max_time_s_ correspond to the timespan currently
156  // covered by the array. They are inclusive and exclusive,
157  // respectively (index 0 => min_time_s, index size() => max_time_s.
158  uint64_t min_time_s_;
159  uint64_t max_time_s_;
160 
161  // Nodes are stored in an unordered_map so that we can provide
162  // persistent keys with fast look ups. We could use the node's path
163  // as the key (though we need an adapter hash a QString rather than
164  // std::string), but they we're constantly hashing very long
165  // strings. Instead, we assign a unique integer key when the node
166  // is added. This map provides reasonable reverse-lookups. We
167  // could actually change nodes_ to a vector or deque and still have
168  // persistent indices as long as we don't allow nodes to be deleted.
169  std::map<QString, int> node_key_from_path_;
170  std::unordered_map<int, ProfileNode> nodes_;
171 
172  // The flat index stores all the profile's nodes in alphabetical by
173  // path order. Traversing in order corresponds to visiting the call
174  // tree in a depth-first pattern.
175  std::vector<int> flat_index_;
176 
177 
178  // The ProfileDatabase is the only place we want to create valid
179  // profiles. A valid profile is created by initializing a default
180  // profile. Initialization is only allowed to happen once.
181  friend class ProfileDatabase;
182  void initialize(int profile_key, const QString &name);
183 
184  void expandTimeline(const uint64_t sec);
185  void addDataToAllNodes(const bool back, const size_t count);
186 
187  bool touchNode(const QString &path);
188 
189  void storeItemData(std::set<uint64_t> &modified_times,
190  const int node_key,
191  const NewProfileData &item);
192 
193  size_t indexFromSec(const uint64_t secs) const { return secs - min_time_s_; }
194  uint64_t secFromIndex(const uint64_t index) const { return index + min_time_s_; }
195 
196  void rebuildIndices();
197  void rebuildFlatIndex();
198  void rebuildTreeIndex();
199 
200  void updateDerivedData(size_t index);
201  void updateDerivedDataInternal(ProfileNode& node, size_t index);
202 
203  public:
204  Profile();
205  ~Profile();
206 
207  void addData(const NewProfileDataVector &data);
208  bool isValid() const { return profile_key_ >= 0; }
209  int profileKey() const { return profile_key_; }
210 
211  const QString& name() const { return name_; }
212  void setName(const QString &name);
213 
214  const ProfileNode& node(int node_key) const;
215  const ProfileNode& rootNode() const;
216  int rootKey() const { return 0; }
217  const std::vector<int>& nodeKeys() const;
218 
219  Q_SIGNALS:
220  // Emitted when the profile is renamed.
221  void profileModified(int profile_key);
222  void nodesAdded(int profile_key);
223  void dataAdded(int profile_key);
224 }; // class Profile
225 } // namespace swri_profiler_tools
226 #endif // SWRI_PROFILER_TOOLS_PROFILE_H_
swri_profiler_tools::Profile::max_time_s_
uint64_t max_time_s_
Definition: profile.h:159
swri_profiler_tools::Profile::rebuildIndices
void rebuildIndices()
Definition: profile.cpp:277
swri_profiler_tools::Profile::rebuildFlatIndex
void rebuildFlatIndex()
Definition: profile.cpp:283
swri_profiler_tools::ProfileNode::path_
QString path_
Definition: profile.h:89
new_profile_data.h
swri_profiler_tools::ProfileNode::parentKey
int parentKey() const
Definition: profile.h:136
swri_profiler_tools::Profile::initialize
void initialize(int profile_key, const QString &name)
Definition: profile.cpp:63
swri_profiler_tools::Profile::indexFromSec
size_t indexFromSec(const uint64_t secs) const
Definition: profile.h:193
swri_profiler_tools::Profile::~Profile
~Profile()
Definition: profile.cpp:59
swri_profiler_tools::ProfileNode::ProfileNode
ProfileNode()
Definition: profile.h:121
swri_profiler_tools::ProfileNode::nodeKey
int nodeKey() const
Definition: profile.h:130
swri_profiler_tools::ProfileNode::parent_
int parent_
Definition: profile.h:109
swri_profiler_tools::ProfileNode::isValid
bool isValid() const
Definition: profile.h:129
swri_profiler_tools::ProfileEntry::cumulative_exclusive_duration_ns
uint64_t cumulative_exclusive_duration_ns
Definition: profile.h:62
swri_profiler_tools::Profile::addData
void addData(const NewProfileDataVector &data)
Definition: profile.cpp:75
swri_profiler_tools::Profile
Definition: profile.h:141
swri_profiler_tools::Profile::rebuildTreeIndex
void rebuildTreeIndex()
Definition: profile.cpp:338
swri_profiler_tools::Profile::nodes_
std::unordered_map< int, ProfileNode > nodes_
Definition: profile.h:170
swri_profiler_tools::Profile::profileKey
int profileKey() const
Definition: profile.h:209
swri_profiler_tools::ProfileNode::data
const std::deque< ProfileEntry > & data() const
Definition: profile.h:134
swri_profiler_tools::ProfileNode::hasChildren
bool hasChildren() const
Definition: profile.h:138
swri_profiler_tools::Profile::node_key_from_path_
std::map< QString, int > node_key_from_path_
Definition: profile.h:169
swri_profiler_tools::Profile::name
const QString & name() const
Definition: profile.h:211
swri_profiler_tools::ProfileEntry::incremental_exclusive_duration_ns
uint64_t incremental_exclusive_duration_ns
Definition: profile.h:63
swri_profiler_tools::ProfileEntry::incremental_inclusive_duration_ns
uint64_t incremental_inclusive_duration_ns
Definition: profile.h:61
swri_profiler_tools::Profile::rootNode
const ProfileNode & rootNode() const
Definition: profile.cpp:467
swri_profiler_tools::Profile::profile_key_
int profile_key_
Definition: profile.h:143
swri_profiler_tools::Profile::secFromIndex
uint64_t secFromIndex(const uint64_t index) const
Definition: profile.h:194
swri_profiler_tools::Profile::touchNode
bool touchNode(const QString &path)
Definition: profile.cpp:178
swri_profiler_tools::ProfileNode::depth_
int depth_
Definition: profile.h:105
swri_profiler_tools::Profile::nodesAdded
void nodesAdded(int profile_key)
swri_profiler_tools::Profile::min_time_s_
uint64_t min_time_s_
Definition: profile.h:158
swri_profiler_tools::Profile::nodeKeys
const std::vector< int > & nodeKeys() const
Definition: profile.cpp:472
swri_profiler_tools::ProfileEntry
Definition: profile.h:48
swri_profiler_tools::ProfileNode::measured_
bool measured_
Definition: profile.h:97
swri_profiler_tools::Profile::dataAdded
void dataAdded(int profile_key)
swri_profiler_tools::Profile::expandTimeline
void expandTimeline(const uint64_t sec)
Definition: profile.cpp:133
swri_profiler_tools::ProfileNode::isMeasured
bool isMeasured() const
Definition: profile.h:133
swri_profiler_tools::Profile::isValid
bool isValid() const
Definition: profile.h:208
swri_profiler_tools::ProfileEntry::ProfileEntry
ProfileEntry()
Definition: profile.h:66
swri_profiler_tools::ProfileNode::path
const QString & path() const
Definition: profile.h:132
swri_profiler_tools::Profile::updateDerivedData
void updateDerivedData(size_t index)
Definition: profile.cpp:370
swri_profiler_tools::Profile::storeItemData
void storeItemData(std::set< uint64_t > &modified_times, const int node_key, const NewProfileData &item)
Definition: profile.cpp:250
swri_profiler_tools::NewProfileData
Definition: new_profile_data.h:43
swri_profiler_tools::ProfileNode::depth
int depth() const
Definition: profile.h:135
swri_profiler_tools::ProfileEntry::incremental_max_duration_ns
uint64_t incremental_max_duration_ns
Definition: profile.h:64
swri_profiler_tools::Profile::setName
void setName(const QString &name)
Definition: profile.cpp:451
swri_profiler_tools::ProfileDatabase
Definition: profile_database.h:42
swri_profiler_tools::NewProfileDataVector
std::vector< NewProfileData > NewProfileDataVector
Definition: new_profile_data.h:54
swri_profiler_tools::Profile::node
const ProfileNode & node(int node_key) const
Definition: profile.cpp:457
swri_profiler_tools::ProfileEntry::cumulative_call_count
uint64_t cumulative_call_count
Definition: profile.h:59
swri_profiler_tools::ProfileNode::children_
std::vector< int > children_
Definition: profile.h:113
swri_profiler_tools::ProfileEntry::projected
bool projected
Definition: profile.h:58
swri_profiler_tools::ProfileNode::name_
QString name_
Definition: profile.h:86
swri_profiler_tools::Profile::profileModified
void profileModified(int profile_key)
swri_profiler_tools::Profile::Profile
Profile()
Definition: profile.cpp:42
swri_profiler_tools::ProfileNode::name
const QString & name() const
Definition: profile.h:131
swri_profiler_tools::ProfileNode::node_key_
int node_key_
Definition: profile.h:82
swri_profiler_tools::ProfileEntry::cumulative_inclusive_duration_ns
uint64_t cumulative_inclusive_duration_ns
Definition: profile.h:60
swri_profiler_tools::Profile::rootKey
int rootKey() const
Definition: profile.h:216
swri_profiler_tools::ProfileNode::data_
std::deque< ProfileEntry > data_
Definition: profile.h:102
swri_profiler_tools::Profile::name_
QString name_
Definition: profile.h:152
swri_profiler_tools
Definition: database_key.h:34
swri_profiler_tools::Profile::flat_index_
std::vector< int > flat_index_
Definition: profile.h:175
swri_profiler_tools::Profile::updateDerivedDataInternal
void updateDerivedDataInternal(ProfileNode &node, size_t index)
Definition: profile.cpp:380
swri_profiler_tools::ProfileNode::childKeys
const std::vector< int > & childKeys() const
Definition: profile.h:137
swri_profiler_tools::ProfileNode
Definition: profile.h:78
swri_profiler_tools::Profile::addDataToAllNodes
void addDataToAllNodes(const bool back, const size_t count)
Definition: profile.cpp:156


swri_profiler_tools
Author(s):
autogenerated on Wed Mar 2 2022 01:06:28