lttng: Use getEventName() in the kernel state provider
[deliverable/tracecompass.git] / org.eclipse.linuxtools.tmf.core / src / org / eclipse / linuxtools / tmf / core / statesystem / AttributeTree.java
CommitLineData
a52fde77
AM
1/*******************************************************************************
2 * Copyright (c) 2012 Ericsson
3 * Copyright (c) 2010, 2011 École Polytechnique de Montréal
4 * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
5 *
6 * All rights reserved. This program and the accompanying materials are
7 * made available under the terms of the Eclipse Public License v1.0 which
8 * accompanies this distribution, and is available at
9 * http://www.eclipse.org/legal/epl-v10.html
10 *
11 *******************************************************************************/
12
13package org.eclipse.linuxtools.tmf.core.statesystem;
14
15import java.io.*;
16import java.util.ArrayList;
17import java.util.Arrays;
18import java.util.Collections;
19import java.util.List;
20
21/**
22 * The Attribute Tree is the /proc-like filesystem used to organize attributes.
23 * Each node of this tree is both like a file and a directory in the
24 * "file system".
25 *
26 * @author alexmont
27 *
28 */
29final class AttributeTree {
30
31 /* "Magic number" for attribute tree files or file sections */
32 private final static int ATTRIB_TREE_MAGIC_NUMBER = 0x06EC3671;
33
34 private final StateSystem ss;
35 private final List<Attribute> attributeList;
36 private final Attribute attributeTreeRoot;
37
38 /**
39 * Standard constructor, create a new empty Attribute Tree
40 *
41 * @param ss
42 * The StateSystem to which this AT is attached
43 */
44 AttributeTree(StateSystem ss) {
45 this.ss = ss;
46 this.attributeList = Collections.synchronizedList(new ArrayList<Attribute>());
47 this.attributeTreeRoot = new AlphaNumAttribute(null, "root", -1); //$NON-NLS-1$
48 }
49
50 /**
51 * "Existing file" constructor Builds a attribute tree from a "mapping file"
52 * or mapping section previously saved somewhere.
53 *
54 * @param ss
55 * StateSystem to which this AT is attached
56 * @param fis
57 * File stream where to read the AT information. Make sure it's
58 * seeked at the right place!
59 * @throws IOException
60 */
61 AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
62 this(ss);
63 DataInputStream in = new DataInputStream(new BufferedInputStream(fis));
64
65 /* Message for exceptions, shouldn't be externalized */
66 final String errorMessage = "The attribute tree file section is either invalid or corrupted."; //$NON-NLS-1$
0a9de3d2 67
a52fde77
AM
68 ArrayList<String[]> list = new ArrayList<String[]>();
69 byte[] curByteArray;
70 String curFullString;
71 String[] curStringArray;
72 int res, remain, size;
73 int expectedSize = 0;
74 int total = 0;
75
76 /* Read the header of the Attribute Tree file (or file section) */
77 res = in.readInt(); /* Magic number */
78 if (res != ATTRIB_TREE_MAGIC_NUMBER) {
79 throw new IOException(errorMessage);
80 }
81
82 /* Expected size of the section */
83 expectedSize = in.readInt();
84 if (expectedSize <= 12) {
85 throw new IOException(errorMessage);
86 }
87
88 /* How many entries we have to read */
89 remain = in.readInt();
90 total += 12;
91
92 /* Read each entry */
93 for (; remain > 0; remain--) {
94 /* Read the first byte = the size of the entry */
95 size = in.readByte();
96 curByteArray = new byte[size];
ab604305
AM
97 res = in.read(curByteArray);
98 if (res != size) {
99 throw new IOException(errorMessage);
100 }
a52fde77
AM
101
102 /*
103 * Go buffer -> byteArray -> String -> String[] -> insert in list.
104 * bleh
105 */
106 curFullString = new String(curByteArray);
107 curStringArray = curFullString.split("/"); //$NON-NLS-1$
108 list.add(curStringArray);
109
110 /* Read the 0'ed confirmation byte */
111 res = in.readByte();
112 if (res != 0) {
113 throw new IOException(errorMessage);
114 }
115 total += curByteArray.length + 2;
116 }
117
118 if (total != expectedSize) {
119 throw new IOException(errorMessage);
120 }
121
122 /*
123 * Now we have 'list', the ArrayList of String arrays representing all
124 * the attributes. Simply create attributes the normal way from them.
125 */
126 for (String[] attrib : list) {
127 this.getQuarkAndAdd(-1, attrib);
128 }
129 }
130
131 /**
132 * Tell the Attribute Tree to write itself somewhere. The passed
133 * FileOutputStream defines where (which file/position).
134 *
135 * @param fos
136 * Where to write. Make sure it's seeked at the right position
137 * you want.
138 * @return The total number of bytes written.
139 */
140 int writeSelf(File file, long pos) {
157906bb 141 RandomAccessFile raf = null;
a52fde77
AM
142 int total = 0;
143 byte[] curByteArray;
144
145 try {
146 raf = new RandomAccessFile(file, "rw"); //$NON-NLS-1$
147 raf.seek(pos);
148
149 /* Write the almost-magic number */
150 raf.writeInt(ATTRIB_TREE_MAGIC_NUMBER);
151
152 /* Placeholder for the total size of the section... */
153 raf.writeInt(-8000);
154
155 /* Write the number of entries */
156 raf.writeInt(this.attributeList.size());
157 total += 12;
158
159 /* Write the attributes themselves */
160 for (Attribute entry : this.attributeList) {
161 curByteArray = entry.getFullAttributeName().getBytes();
162 if (curByteArray.length > Byte.MAX_VALUE) {
163 throw new IOException("Attribute with name \"" //$NON-NLS-1$
164 + Arrays.toString(curByteArray) + "\" is too long."); //$NON-NLS-1$
165 }
166 /* Write the first byte = size of the array */
167 raf.writeByte((byte) curByteArray.length);
168
169 /* Write the array itself */
170 raf.write(curByteArray);
171
172 /* Write the 0'ed byte */
173 raf.writeByte((byte) 0);
174
175 total += curByteArray.length + 2;
176 }
177
178 /* Now go back and write the actual size of this section */
179 raf.seek(pos + 4);
180 raf.writeInt(total);
181
182 raf.close();
183 } catch (IOException e) {
184 e.printStackTrace();
157906bb
AK
185 } finally {
186 if (raf != null) {
187 try {
188 raf.close();
189 } catch (IOException e) {
190 }
191 }
a52fde77
AM
192 }
193 return total;
194 }
195
196 /**
197 * Return the number of attributes this system as seen so far. Note that
198 * this also equals the integer value (quark) the next added attribute will
199 * have.
200 *
201 * @return
202 */
203 int getNbAttributes() {
204 return attributeList.size();
205 }
206
207 /**
208 * This is the version to specifically add missing attributes.
209 *
210 * If 'numericalNode' is true, all the new attributes created will be of
211 * type 'NumericalNode' instead of 'AlphaNumNode'. Be careful with this, if
212 * you do not want ALL added attributes to be numerical, call this function
213 * first with 'false' to create the parent nodes, then call it again to make
214 * sure only the final node is numerical.
215 *
216 * @throws AttributeNotFoundException
217 */
218 int getQuarkDontAdd(int startingNodeQuark, String... subPath)
219 throws AttributeNotFoundException {
a52fde77
AM
220 assert (startingNodeQuark >= -1);
221
222 Attribute prevNode;
223
6abc2d88
AM
224 /* If subPath is empty, simply return the starting quark */
225 if (subPath == null || subPath.length == 0) {
226 return startingNodeQuark;
227 }
228
a52fde77
AM
229 /* Get the "starting node" */
230 if (startingNodeQuark == -1) {
231 prevNode = attributeTreeRoot;
232 } else {
233 prevNode = attributeList.get(startingNodeQuark);
234 }
235
236 int knownQuark = prevNode.getSubAttributeQuark(subPath);
237 if (knownQuark == -1) {
238 /*
239 * The attribute doesn't exist, but we have been specified to NOT
240 * add any new attributes.
241 */
242 throw new AttributeNotFoundException();
243 }
244 /*
245 * The attribute was already existing, return the quark of that
246 * attribute
247 */
248 return knownQuark;
249 }
250
251 // FIXME synchronized here is probably quite costly... maybe only locking
252 // the "for" would be enough?
253 synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
254 assert (subPath != null && subPath.length > 0);
255 assert (startingNodeQuark >= -1);
256
257 Attribute nextNode = null;
258 Attribute prevNode;
259
260 /* Get the "starting node" */
261 if (startingNodeQuark == -1) {
262 prevNode = attributeTreeRoot;
263 } else {
264 prevNode = attributeList.get(startingNodeQuark);
265 }
266
267 int knownQuark = prevNode.getSubAttributeQuark(subPath);
268 if (knownQuark == -1) {
269 /*
270 * The attribute was not in the table previously, and we want to add
271 * it
272 */
273 for (String curDirectory : subPath) {
274 nextNode = prevNode.getSubAttributeNode(curDirectory);
275 if (nextNode == null) {
276 /* This is where we need to start adding */
277 nextNode = new AlphaNumAttribute(prevNode, curDirectory,
278 attributeList.size());
279 prevNode.addSubAttribute(nextNode);
280 attributeList.add(nextNode);
281 ss.transState.addEmptyEntry();
282 }
283 prevNode = nextNode;
284 }
285 return attributeList.size() - 1;
286 }
287 /*
288 * The attribute was already existing, return the quark of that
289 * attribute
290 */
291 return knownQuark;
292 }
293
294 int getSubAttributesCount(int quark) {
295 return attributeList.get(quark).getSubAttributesList().size();
296 }
297
0a9de3d2
AM
298 /**
299 * Returns the sub-attributes of the quark passed in parameter
300 *
301 * @param attributeQuark
c66426fd 302 * @param recursive
0a9de3d2
AM
303 * @return
304 * @throws AttributeNotFoundException
305 */
c66426fd 306 List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
0a9de3d2
AM
307 throws AttributeNotFoundException {
308 List<Integer> listOfChildren = new ArrayList<Integer>();
309 Attribute startingAttribute;
c66426fd 310
0a9de3d2 311 /* Check if the quark is valid */
f94a0bac 312 if (attributeQuark < -1 || attributeQuark >= attributeList.size()) {
0a9de3d2
AM
313 throw new AttributeNotFoundException();
314 }
c66426fd 315
0a9de3d2 316 /* Set up the node from which we'll start the search */
c66426fd 317 if (attributeQuark == -1) {
0a9de3d2
AM
318 startingAttribute = attributeTreeRoot;
319 } else {
320 startingAttribute = attributeList.get(attributeQuark);
321 }
c66426fd 322
0a9de3d2 323 /* Iterate through the sub-attributes and add them to the list */
c66426fd 324 addSubAttributes(listOfChildren, startingAttribute, recursive);
0a9de3d2 325
a52fde77
AM
326 return listOfChildren;
327 }
328
c66426fd
AM
329 private void addSubAttributes(List<Integer> list, Attribute curAttribute,
330 boolean recursive) {
331 for (Attribute childNode : curAttribute.getSubAttributesList()) {
332 list.add(childNode.getQuark());
333 if (recursive) {
334 addSubAttributes(list, childNode, true);
335 }
336 }
337 }
338
a52fde77
AM
339 String getFullAttributeName(int quark) {
340 if (quark >= attributeList.size() || quark < 0) {
341 return null;
342 }
343 return attributeList.get(quark).getFullAttributeName();
344 }
345
346 void debugPrint(PrintWriter writer) {
347 attributeTreeRoot.debugPrint(writer);
348 }
349
350}
This page took 0.037961 seconds and 5 git commands to generate.