Commit | Line | Data |
---|---|---|
a52fde77 | 1 | /******************************************************************************* |
61759503 | 2 | * Copyright (c) 2012, 2013 Ericsson |
a52fde77 AM |
3 | * Copyright (c) 2010, 2011 École Polytechnique de Montréal |
4 | * Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com> | |
cb42195c | 5 | * |
a52fde77 AM |
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 | |
cb42195c | 10 | * |
a52fde77 AM |
11 | *******************************************************************************/ |
12 | ||
f9a76cac | 13 | package org.eclipse.linuxtools.internal.tmf.core.statesystem.backends.historytree; |
a52fde77 AM |
14 | |
15 | import java.nio.ByteBuffer; | |
16 | ||
17 | /** | |
18 | * A Core node is a first-level node of a History Tree which is not a leaf node. | |
cb42195c | 19 | * |
a52fde77 | 20 | * It extends HTNode by adding support for child nodes, and also extensions. |
cb42195c | 21 | * |
ffd0aa67 | 22 | * @author Alexandre Montplaisir |
cb42195c | 23 | * |
a52fde77 | 24 | */ |
8d47cc34 | 25 | public class CoreNode extends HTNode { |
a52fde77 | 26 | |
cb42195c AM |
27 | /** Number of bytes in a int */ |
28 | private static final int SIZE_INT = 4; | |
29 | ||
30 | /** Number of bytes in a long */ | |
31 | private static final int SIZE_LONG = 8; | |
32 | ||
33 | /** Nb. of children this node has */ | |
a52fde77 AM |
34 | private int nbChildren; |
35 | ||
cb42195c | 36 | /** Seq. numbers of the children nodes (size = MAX_NB_CHILDREN) */ |
a52fde77 AM |
37 | private int[] children; |
38 | ||
cb42195c | 39 | /** Start times of each of the children (size = MAX_NB_CHILDREN) */ |
a52fde77 AM |
40 | private long[] childStart; |
41 | ||
cb42195c | 42 | /** Seq number of this node's extension. -1 if none */ |
8d47cc34 | 43 | private int extension = -1; |
a52fde77 AM |
44 | |
45 | /** | |
46 | * Initial constructor. Use this to initialize a new EMPTY node. | |
cb42195c | 47 | * |
ffd0aa67 EB |
48 | * @param config |
49 | * Configuration of the History Tree | |
a52fde77 AM |
50 | * @param seqNumber |
51 | * The (unique) sequence number assigned to this particular node | |
52 | * @param parentSeqNumber | |
53 | * The sequence number of this node's parent node | |
54 | * @param start | |
55 | * The earliest timestamp stored in this node | |
56 | */ | |
8d47cc34 | 57 | protected CoreNode(HTConfig config, int seqNumber, int parentSeqNumber, |
a52fde77 | 58 | long start) { |
ffd0aa67 | 59 | super(config, seqNumber, parentSeqNumber, start); |
a52fde77 | 60 | this.nbChildren = 0; |
ffd0aa67 | 61 | int size = config.getMaxChildren(); |
a52fde77 AM |
62 | |
63 | /* | |
64 | * We instantiate the two following arrays at full size right away, | |
65 | * since we want to reserve that space in the node's header. | |
66 | * "this.nbChildren" will tell us how many relevant entries there are in | |
67 | * those tables. | |
68 | */ | |
cb42195c AM |
69 | this.children = new int[size]; |
70 | this.childStart = new long[size]; | |
a52fde77 AM |
71 | } |
72 | ||
73 | @Override | |
8d47cc34 | 74 | public void readSpecificHeader(ByteBuffer buffer) { |
ffd0aa67 | 75 | int size = getConfig().getMaxChildren(); |
a52fde77 AM |
76 | |
77 | extension = buffer.getInt(); | |
78 | nbChildren = buffer.getInt(); | |
79 | ||
cb42195c AM |
80 | children = new int[size]; |
81 | for (int i = 0; i < nbChildren; i++) { | |
a52fde77 AM |
82 | children[i] = buffer.getInt(); |
83 | } | |
cb42195c | 84 | for (int i = nbChildren; i < size; i++) { |
a52fde77 AM |
85 | buffer.getInt(); |
86 | } | |
87 | ||
cb42195c AM |
88 | this.childStart = new long[size]; |
89 | for (int i = 0; i < nbChildren; i++) { | |
a52fde77 AM |
90 | childStart[i] = buffer.getLong(); |
91 | } | |
cb42195c | 92 | for (int i = nbChildren; i < size; i++) { |
a52fde77 AM |
93 | buffer.getLong(); |
94 | } | |
95 | } | |
96 | ||
97 | @Override | |
8d47cc34 | 98 | public void writeSpecificHeader(ByteBuffer buffer) { |
ffd0aa67 | 99 | int size = getConfig().getMaxChildren(); |
a52fde77 AM |
100 | |
101 | buffer.putInt(extension); | |
102 | buffer.putInt(nbChildren); | |
103 | ||
104 | /* Write the "children's seq number" array */ | |
cb42195c | 105 | for (int i = 0; i < nbChildren; i++) { |
a52fde77 AM |
106 | buffer.putInt(children[i]); |
107 | } | |
cb42195c | 108 | for (int i = nbChildren; i < size; i++) { |
a52fde77 AM |
109 | buffer.putInt(0); |
110 | } | |
111 | ||
112 | /* Write the "children's start times" array */ | |
cb42195c | 113 | for (int i = 0; i < nbChildren; i++) { |
a52fde77 AM |
114 | buffer.putLong(childStart[i]); |
115 | } | |
cb42195c | 116 | for (int i = nbChildren; i < size; i++) { |
a52fde77 AM |
117 | buffer.putLong(0); |
118 | } | |
119 | } | |
120 | ||
8d47cc34 AM |
121 | /** |
122 | * Return the number of child nodes this node has. | |
123 | * | |
124 | * @return The number of child nodes | |
125 | */ | |
126 | public int getNbChildren() { | |
a52fde77 AM |
127 | return nbChildren; |
128 | } | |
129 | ||
8d47cc34 AM |
130 | /** |
131 | * Get the child node corresponding to the specified index | |
132 | * | |
133 | * @param index The index of the child to lookup | |
134 | * @return The child node | |
135 | */ | |
136 | public int getChild(int index) { | |
a52fde77 AM |
137 | return children[index]; |
138 | } | |
139 | ||
8d47cc34 AM |
140 | /** |
141 | * Get the latest (right-most) child node of this node. | |
142 | * | |
143 | * @return The latest child node | |
144 | */ | |
145 | public int getLatestChild() { | |
a52fde77 AM |
146 | return children[nbChildren - 1]; |
147 | } | |
148 | ||
8d47cc34 AM |
149 | /** |
150 | * Get the start time of the specified child node. | |
151 | * | |
152 | * @param index | |
153 | * The index of the child node | |
154 | * @return The start time of the that child node. | |
155 | */ | |
156 | public long getChildStart(int index) { | |
a52fde77 AM |
157 | return childStart[index]; |
158 | } | |
159 | ||
8d47cc34 AM |
160 | /** |
161 | * Get the start time of the latest (right-most) child node. | |
162 | * | |
163 | * @return The start time of the latest child | |
164 | */ | |
165 | public long getLatestChildStart() { | |
a52fde77 AM |
166 | return childStart[nbChildren - 1]; |
167 | } | |
168 | ||
8d47cc34 AM |
169 | /** |
170 | * Get the sequence number of the extension to this node (if there is one). | |
171 | * | |
172 | * @return The sequence number of the extended node. '-1' is returned if | |
173 | * there is no extension node. | |
174 | */ | |
175 | public int getExtensionSequenceNumber() { | |
a52fde77 AM |
176 | return extension; |
177 | } | |
178 | ||
179 | /** | |
180 | * Tell this node that it has a new child (Congrats!) | |
cb42195c | 181 | * |
a52fde77 AM |
182 | * @param childNode |
183 | * The SHTNode object of the new child | |
184 | */ | |
8d47cc34 | 185 | public void linkNewChild(CoreNode childNode) { |
ffd0aa67 | 186 | assert (this.nbChildren < getConfig().getMaxChildren()); |
a52fde77 AM |
187 | |
188 | this.children[nbChildren] = childNode.getSequenceNumber(); | |
189 | this.childStart[nbChildren] = childNode.getNodeStart(); | |
190 | this.nbChildren++; | |
191 | } | |
192 | ||
193 | @Override | |
8d47cc34 | 194 | public byte getNodeType() { |
a52fde77 AM |
195 | return 1; |
196 | } | |
197 | ||
198 | @Override | |
8d47cc34 | 199 | public int getTotalHeaderSize() { |
ffd0aa67 | 200 | int maxChildren = getConfig().getMaxChildren(); |
cb42195c AM |
201 | int specificSize = |
202 | SIZE_INT /* 1x int (extension node) */ | |
203 | + SIZE_INT /* 1x int (nbChildren) */ | |
a52fde77 AM |
204 | |
205 | /* MAX_NB * int ('children' table) */ | |
cb42195c | 206 | + SIZE_INT * maxChildren |
a52fde77 AM |
207 | |
208 | /* MAX_NB * Timevalue ('childStart' table) */ | |
cb42195c | 209 | + SIZE_LONG * maxChildren; |
a52fde77 | 210 | |
cb42195c | 211 | return COMMON_HEADER_SIZE + specificSize; |
a52fde77 AM |
212 | } |
213 | ||
214 | @Override | |
8d47cc34 | 215 | public String toStringSpecific() { |
a52fde77 AM |
216 | /* Only used for debugging, shouldn't be externalized */ |
217 | return "Core Node, " + nbChildren + " children, "; //$NON-NLS-1$ //$NON-NLS-2$ | |
218 | } | |
219 | ||
220 | } |