Commit | Line | Data |
---|---|---|
79e08fd0 | 1 | /******************************************************************************* |
ed902a2b | 2 | * Copyright (c) 2011, 2014 Ericsson |
013a5f1c | 3 | * |
79e08fd0 BH |
4 | * All rights reserved. This program and the accompanying materials are |
5 | * made available under the terms of the Eclipse Public License v1.0 which | |
6 | * accompanies this distribution, and is available at | |
7 | * http://www.eclipse.org/legal/epl-v10.html | |
013a5f1c | 8 | * |
79e08fd0 | 9 | * Contributors: |
09667aa4 MD |
10 | * Yann N. Dauphin <dhaemon@gmail.com> - Implementation for stats |
11 | * Francois Godin <copelnug@gmail.com> - Re-design for new stats structure | |
12 | * Mathieu Denis <mathieu.denis@polymtl.ca> - Re-design for new stats structure (2) | |
7588c810 | 13 | * Alexandre Montplaisir - Move the tree structure logic into the nodes |
79e08fd0 BH |
14 | *******************************************************************************/ |
15 | ||
2bdf0193 | 16 | package org.eclipse.tracecompass.tmf.ui.viewers.statistics.model; |
79e08fd0 | 17 | |
7588c810 | 18 | import java.util.Arrays; |
79e08fd0 | 19 | import java.util.Collection; |
7588c810 | 20 | import java.util.Map; |
1173f159 | 21 | import java.util.concurrent.ConcurrentHashMap; |
79e08fd0 | 22 | |
79e08fd0 | 23 | /** |
013a5f1c AM |
24 | * A tree where nodes can be accessed efficiently using paths. |
25 | * | |
09667aa4 | 26 | * It works like file systems. Each node is identified by a key. A path is an |
5673a177 AM |
27 | * array of String. The elements of the array represent the path from the root |
28 | * to this node. | |
013a5f1c | 29 | * |
7588c810 | 30 | * @author Mathieu Denis |
79e08fd0 BH |
31 | */ |
32 | public class TmfStatisticsTreeNode { | |
09667aa4 | 33 | |
7588c810 AM |
34 | /** Tree to which this node belongs */ |
35 | private final TmfStatisticsTree fTree; | |
09667aa4 | 36 | |
7588c810 AM |
37 | /** Path of this node. The last element represents its basename. */ |
38 | private final String[] fPath; | |
09667aa4 | 39 | |
7588c810 AM |
40 | /** Parent node */ |
41 | private final TmfStatisticsTreeNode fParent; | |
42 | ||
43 | /** Children of this node, indexed by their basename. */ | |
44 | private final Map<String, TmfStatisticsTreeNode> fChildren; | |
45 | ||
46 | /** Statistics values associated to this node. */ | |
47 | private final TmfStatisticsValues fValues; | |
09667aa4 | 48 | |
df2b3dbb VP |
49 | /** |
50 | * Return the node at the top of the branch | |
51 | */ | |
52 | private final TmfStatisticsTreeNode fTopNode; | |
53 | ||
09667aa4 MD |
54 | /** |
55 | * Constructor. | |
56 | * | |
7588c810 AM |
57 | * @param tree |
58 | * Owner tree of this node | |
59 | * @param parent | |
60 | * Parent node of this one | |
09667aa4 MD |
61 | * @param path |
62 | * Path to the node. | |
09667aa4 | 63 | */ |
7588c810 AM |
64 | public TmfStatisticsTreeNode(TmfStatisticsTree tree, |
65 | TmfStatisticsTreeNode parent, final String... path) { | |
df2b3dbb VP |
66 | /* |
67 | * The path must not contain any null element, or else we won't be able | |
68 | * to walk the tree. | |
69 | */ | |
7588c810 AM |
70 | for (String elem : path) { |
71 | if (elem == null) { | |
72 | throw new IllegalArgumentException(); | |
73 | } | |
74 | } | |
75 | ||
76 | fTree = tree; | |
09667aa4 | 77 | fPath = path; |
7588c810 | 78 | fParent = parent; |
1173f159 | 79 | fChildren = new ConcurrentHashMap<>(); |
89c06060 | 80 | fValues = new TmfStatisticsValues(); |
df2b3dbb VP |
81 | |
82 | /* calculating top node */ | |
83 | TmfStatisticsTreeNode topNode = this; | |
84 | while (topNode.getParent() != null && topNode.getParent().getParent() != null) { | |
85 | topNode = topNode.getParent(); | |
86 | } | |
87 | fTopNode = topNode; | |
09667aa4 MD |
88 | } |
89 | ||
7588c810 AM |
90 | /** |
91 | * Get the name for this node. It's used as the key in the parent's node. | |
92 | * | |
93 | * @return Name of this node. | |
94 | */ | |
95 | public String getName() { | |
96 | if (fPath.length == 0) { | |
97 | /* This means we are the root node, which has no path itself */ | |
98 | return "root"; //$NON-NLS-1$ | |
99 | } | |
100 | return fPath[fPath.length - 1]; | |
101 | } | |
102 | ||
09667aa4 MD |
103 | /** |
104 | * Test if a node contain the specified child. | |
105 | * | |
7588c810 | 106 | * @param childName |
09667aa4 MD |
107 | * Name of the child. |
108 | * @return true: if child with given key is present, false: if no child | |
109 | * exists with given key name | |
110 | */ | |
7588c810 AM |
111 | public boolean containsChild(String childName) { |
112 | return fChildren.containsKey(childName); | |
09667aa4 MD |
113 | } |
114 | ||
115 | /** | |
7588c810 | 116 | * Retrieve the given child from this node. |
09667aa4 | 117 | * |
7588c810 AM |
118 | * @param childName |
119 | * The (base)name of the child you want | |
120 | * @return The child object, or null if it doesn't exist | |
09667aa4 | 121 | */ |
7588c810 AM |
122 | public TmfStatisticsTreeNode getChild(String childName) { |
123 | return fChildren.get(childName); | |
09667aa4 MD |
124 | } |
125 | ||
126 | /** | |
7588c810 | 127 | * Get the children of this node. |
09667aa4 | 128 | * |
79e08fd0 BH |
129 | * @return Direct children of this node. |
130 | */ | |
7588c810 AM |
131 | public Collection<TmfStatisticsTreeNode> getChildren() { |
132 | return fChildren.values(); | |
79e08fd0 | 133 | } |
09667aa4 MD |
134 | |
135 | /** | |
7588c810 | 136 | * Add a child to this node. |
09667aa4 | 137 | * |
7588c810 AM |
138 | * @param childName |
139 | * Name of the child to add | |
140 | * @return The newly-created child | |
09667aa4 | 141 | */ |
7588c810 AM |
142 | public TmfStatisticsTreeNode addChild(String childName) { |
143 | TmfStatisticsTreeNode child; | |
144 | String[] childPath = new String[fPath.length + 1]; | |
145 | System.arraycopy(fPath, 0, childPath, 0, fPath.length); | |
146 | childPath[fPath.length] = childName; | |
147 | ||
148 | child = new TmfStatisticsTreeNode(this.fTree, this, childPath); | |
149 | fChildren.put(childName, child); | |
150 | return child; | |
09667aa4 MD |
151 | } |
152 | ||
153 | /** | |
154 | * Get the number of children this node have. | |
155 | * | |
156 | * @return Number of direct children of this node. | |
157 | */ | |
158 | public int getNbChildren() { | |
7588c810 | 159 | return fChildren.size(); |
09667aa4 MD |
160 | } |
161 | ||
162 | /** | |
163 | * Return the parent node. | |
164 | * | |
165 | * @return Parent node. | |
166 | */ | |
167 | public TmfStatisticsTreeNode getParent() { | |
7588c810 | 168 | return fParent; |
09667aa4 MD |
169 | } |
170 | ||
df2b3dbb VP |
171 | /** |
172 | * Return the top node. | |
173 | * | |
174 | * @return Top node. | |
df2b3dbb VP |
175 | */ |
176 | public TmfStatisticsTreeNode getTop() { | |
177 | return fTopNode; | |
178 | } | |
179 | ||
09667aa4 MD |
180 | /** |
181 | * Get the path of the node. | |
182 | * | |
183 | * @return The path of the node. | |
184 | */ | |
5673a177 | 185 | public String[] getPath() { |
09667aa4 MD |
186 | return fPath; |
187 | } | |
188 | ||
189 | /** | |
190 | * Get the value of this node. | |
191 | * | |
192 | * @return Value associated with this node. | |
193 | */ | |
89c06060 AM |
194 | public TmfStatisticsValues getValues() { |
195 | return fValues; | |
09667aa4 MD |
196 | } |
197 | ||
198 | /** | |
199 | * Indicate if the node have children. | |
200 | * | |
201 | * @return True if the node has children. | |
202 | */ | |
203 | public boolean hasChildren() { | |
7588c810 | 204 | return (fChildren.size() > 0); |
09667aa4 MD |
205 | } |
206 | ||
207 | /** | |
208 | * Start from creation time i.e. keep key and parent but new statistics and | |
209 | * no children. | |
210 | */ | |
211 | public void reset() { | |
7588c810 AM |
212 | fValues.resetTotalCount(); |
213 | fValues.resetPartialCount(); | |
214 | fChildren.clear(); | |
09667aa4 | 215 | } |
25a042b3 | 216 | |
73fbf6be | 217 | /** |
df2b3dbb VP |
218 | * Resets the global number of events. It doesn't remove any node and |
219 | * doesn't modify the partial event count. Works recursively. | |
73fbf6be MD |
220 | */ |
221 | public void resetGlobalValue() { | |
7588c810 AM |
222 | for (TmfStatisticsTreeNode child : fChildren.values()) { |
223 | child.resetGlobalValue(); | |
224 | } | |
225 | fValues.resetTotalCount(); | |
73fbf6be MD |
226 | } |
227 | ||
25a042b3 MD |
228 | /** |
229 | * Resets the number of events in the time range. It doesn't remove any node | |
7588c810 | 230 | * and doesn't modify the global event count. Works recursively. |
25a042b3 MD |
231 | */ |
232 | public void resetTimeRangeValue() { | |
7588c810 AM |
233 | for (TmfStatisticsTreeNode child : fChildren.values()) { |
234 | child.resetTimeRangeValue(); | |
235 | } | |
236 | fValues.resetPartialCount(); | |
237 | } | |
238 | ||
239 | @Override | |
240 | public String toString() { | |
241 | /* Used for debugging only */ | |
242 | return "Stats node, path = " + Arrays.toString(fPath) + //$NON-NLS-1$ | |
243 | ", values = " + fValues.toString(); //$NON-NLS-1$ | |
25a042b3 | 244 | } |
09667aa4 | 245 | } |