Commit | Line | Data |
---|---|---|
79e08fd0 | 1 | /******************************************************************************* |
60ae41e1 | 2 | * Copyright (c) 2011, 2013 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 | ||
cfd22ad0 | 16 | package org.eclipse.linuxtools.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 |
25a042b3 | 31 | * @version 2.0 |
cfd22ad0 | 32 | * @since 2.0 |
79e08fd0 BH |
33 | */ |
34 | public class TmfStatisticsTreeNode { | |
09667aa4 | 35 | |
7588c810 AM |
36 | /** Tree to which this node belongs */ |
37 | private final TmfStatisticsTree fTree; | |
09667aa4 | 38 | |
7588c810 AM |
39 | /** Path of this node. The last element represents its basename. */ |
40 | private final String[] fPath; | |
09667aa4 | 41 | |
7588c810 AM |
42 | /** Parent node */ |
43 | private final TmfStatisticsTreeNode fParent; | |
44 | ||
45 | /** Children of this node, indexed by their basename. */ | |
46 | private final Map<String, TmfStatisticsTreeNode> fChildren; | |
47 | ||
48 | /** Statistics values associated to this node. */ | |
49 | private final TmfStatisticsValues fValues; | |
09667aa4 | 50 | |
df2b3dbb VP |
51 | /** |
52 | * Return the node at the top of the branch | |
53 | */ | |
54 | private final TmfStatisticsTreeNode fTopNode; | |
55 | ||
09667aa4 MD |
56 | /** |
57 | * Constructor. | |
58 | * | |
7588c810 AM |
59 | * @param tree |
60 | * Owner tree of this node | |
61 | * @param parent | |
62 | * Parent node of this one | |
09667aa4 MD |
63 | * @param path |
64 | * Path to the node. | |
09667aa4 | 65 | */ |
7588c810 AM |
66 | public TmfStatisticsTreeNode(TmfStatisticsTree tree, |
67 | TmfStatisticsTreeNode parent, final String... path) { | |
df2b3dbb VP |
68 | /* |
69 | * The path must not contain any null element, or else we won't be able | |
70 | * to walk the tree. | |
71 | */ | |
7588c810 AM |
72 | for (String elem : path) { |
73 | if (elem == null) { | |
74 | throw new IllegalArgumentException(); | |
75 | } | |
76 | } | |
77 | ||
78 | fTree = tree; | |
09667aa4 | 79 | fPath = path; |
7588c810 | 80 | fParent = parent; |
1173f159 | 81 | fChildren = new ConcurrentHashMap<>(); |
89c06060 | 82 | fValues = new TmfStatisticsValues(); |
df2b3dbb VP |
83 | |
84 | /* calculating top node */ | |
85 | TmfStatisticsTreeNode topNode = this; | |
86 | while (topNode.getParent() != null && topNode.getParent().getParent() != null) { | |
87 | topNode = topNode.getParent(); | |
88 | } | |
89 | fTopNode = topNode; | |
09667aa4 MD |
90 | } |
91 | ||
7588c810 AM |
92 | /** |
93 | * Get the name for this node. It's used as the key in the parent's node. | |
94 | * | |
95 | * @return Name of this node. | |
96 | */ | |
97 | public String getName() { | |
98 | if (fPath.length == 0) { | |
99 | /* This means we are the root node, which has no path itself */ | |
100 | return "root"; //$NON-NLS-1$ | |
101 | } | |
102 | return fPath[fPath.length - 1]; | |
103 | } | |
104 | ||
09667aa4 MD |
105 | /** |
106 | * Test if a node contain the specified child. | |
107 | * | |
7588c810 | 108 | * @param childName |
09667aa4 MD |
109 | * Name of the child. |
110 | * @return true: if child with given key is present, false: if no child | |
111 | * exists with given key name | |
112 | */ | |
7588c810 AM |
113 | public boolean containsChild(String childName) { |
114 | return fChildren.containsKey(childName); | |
09667aa4 MD |
115 | } |
116 | ||
117 | /** | |
7588c810 | 118 | * Retrieve the given child from this node. |
09667aa4 | 119 | * |
7588c810 AM |
120 | * @param childName |
121 | * The (base)name of the child you want | |
122 | * @return The child object, or null if it doesn't exist | |
09667aa4 | 123 | */ |
7588c810 AM |
124 | public TmfStatisticsTreeNode getChild(String childName) { |
125 | return fChildren.get(childName); | |
09667aa4 MD |
126 | } |
127 | ||
128 | /** | |
7588c810 | 129 | * Get the children of this node. |
09667aa4 | 130 | * |
79e08fd0 BH |
131 | * @return Direct children of this node. |
132 | */ | |
7588c810 AM |
133 | public Collection<TmfStatisticsTreeNode> getChildren() { |
134 | return fChildren.values(); | |
79e08fd0 | 135 | } |
09667aa4 MD |
136 | |
137 | /** | |
7588c810 | 138 | * Add a child to this node. |
09667aa4 | 139 | * |
7588c810 AM |
140 | * @param childName |
141 | * Name of the child to add | |
142 | * @return The newly-created child | |
09667aa4 | 143 | */ |
7588c810 AM |
144 | public TmfStatisticsTreeNode addChild(String childName) { |
145 | TmfStatisticsTreeNode child; | |
146 | String[] childPath = new String[fPath.length + 1]; | |
147 | System.arraycopy(fPath, 0, childPath, 0, fPath.length); | |
148 | childPath[fPath.length] = childName; | |
149 | ||
150 | child = new TmfStatisticsTreeNode(this.fTree, this, childPath); | |
151 | fChildren.put(childName, child); | |
152 | return child; | |
09667aa4 MD |
153 | } |
154 | ||
155 | /** | |
156 | * Get the number of children this node have. | |
157 | * | |
158 | * @return Number of direct children of this node. | |
159 | */ | |
160 | public int getNbChildren() { | |
7588c810 | 161 | return fChildren.size(); |
09667aa4 MD |
162 | } |
163 | ||
164 | /** | |
165 | * Return the parent node. | |
166 | * | |
167 | * @return Parent node. | |
168 | */ | |
169 | public TmfStatisticsTreeNode getParent() { | |
7588c810 | 170 | return fParent; |
09667aa4 MD |
171 | } |
172 | ||
df2b3dbb VP |
173 | /** |
174 | * Return the top node. | |
175 | * | |
176 | * @return Top node. | |
177 | * @since 3.0 | |
178 | */ | |
179 | public TmfStatisticsTreeNode getTop() { | |
180 | return fTopNode; | |
181 | } | |
182 | ||
09667aa4 MD |
183 | /** |
184 | * Get the path of the node. | |
185 | * | |
186 | * @return The path of the node. | |
187 | */ | |
5673a177 | 188 | public String[] getPath() { |
09667aa4 MD |
189 | return fPath; |
190 | } | |
191 | ||
192 | /** | |
193 | * Get the value of this node. | |
194 | * | |
195 | * @return Value associated with this node. | |
196 | */ | |
89c06060 AM |
197 | public TmfStatisticsValues getValues() { |
198 | return fValues; | |
09667aa4 MD |
199 | } |
200 | ||
201 | /** | |
202 | * Indicate if the node have children. | |
203 | * | |
204 | * @return True if the node has children. | |
205 | */ | |
206 | public boolean hasChildren() { | |
7588c810 | 207 | return (fChildren.size() > 0); |
09667aa4 MD |
208 | } |
209 | ||
210 | /** | |
211 | * Start from creation time i.e. keep key and parent but new statistics and | |
212 | * no children. | |
213 | */ | |
214 | public void reset() { | |
7588c810 AM |
215 | fValues.resetTotalCount(); |
216 | fValues.resetPartialCount(); | |
217 | fChildren.clear(); | |
09667aa4 | 218 | } |
25a042b3 | 219 | |
73fbf6be | 220 | /** |
df2b3dbb VP |
221 | * Resets the global number of events. It doesn't remove any node and |
222 | * doesn't modify the partial event count. Works recursively. | |
73fbf6be MD |
223 | * |
224 | * @since 2.0 | |
225 | */ | |
226 | public void resetGlobalValue() { | |
7588c810 AM |
227 | for (TmfStatisticsTreeNode child : fChildren.values()) { |
228 | child.resetGlobalValue(); | |
229 | } | |
230 | fValues.resetTotalCount(); | |
73fbf6be MD |
231 | } |
232 | ||
25a042b3 MD |
233 | /** |
234 | * Resets the number of events in the time range. It doesn't remove any node | |
7588c810 | 235 | * and doesn't modify the global event count. Works recursively. |
eeb388b1 | 236 | * |
25a042b3 MD |
237 | * @since 2.0 |
238 | */ | |
239 | public void resetTimeRangeValue() { | |
7588c810 AM |
240 | for (TmfStatisticsTreeNode child : fChildren.values()) { |
241 | child.resetTimeRangeValue(); | |
242 | } | |
243 | fValues.resetPartialCount(); | |
244 | } | |
245 | ||
246 | @Override | |
247 | public String toString() { | |
248 | /* Used for debugging only */ | |
249 | return "Stats node, path = " + Arrays.toString(fPath) + //$NON-NLS-1$ | |
250 | ", values = " + fValues.toString(); //$NON-NLS-1$ | |
25a042b3 | 251 | } |
09667aa4 | 252 | } |