ss: Move selectNextChildren to CoreNode and return sequenceNumber
[deliverable/tracecompass.git] / statesystem / org.eclipse.tracecompass.statesystem.core / src / org / eclipse / tracecompass / internal / statesystem / core / backend / historytree / classic / CoreNode.java
CommitLineData
a52fde77 1/*******************************************************************************
b2ca67ca 2 * Copyright (c) 2010, 2016 Ericsson, École Polytechnique de Montréal, and others
cb42195c 3 *
a52fde77
AM
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
cb42195c 8 *
bb7f92ce
FW
9 * Contributors:
10 * Alexandre Montplaisir - Initial API and implementation
11 * Florian Wininger - Add Extension and Leaf Node
a52fde77
AM
12 *******************************************************************************/
13
f4baf640 14package org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.classic;
a52fde77
AM
15
16import java.nio.ByteBuffer;
b2ca67ca 17import java.util.Arrays;
88598bff
LPD
18import java.util.Collection;
19import java.util.Collections;
62197b87 20import java.util.concurrent.locks.ReentrantReadWriteLock;
a52fde77 21
f4baf640
GB
22import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTConfig;
23import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.HTNode;
24import org.eclipse.tracecompass.internal.statesystem.core.backend.historytree.ParentNode;
88598bff 25import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
f4baf640 26
a52fde77
AM
27/**
28 * A Core node is a first-level node of a History Tree which is not a leaf node.
cb42195c 29 *
a52fde77 30 * It extends HTNode by adding support for child nodes, and also extensions.
cb42195c 31 *
ffd0aa67 32 * @author Alexandre Montplaisir
a52fde77 33 */
f4baf640 34public final class CoreNode extends ParentNode {
a52fde77 35
cb42195c 36 /** Nb. of children this node has */
a52fde77
AM
37 private int nbChildren;
38
cb42195c 39 /** Seq. numbers of the children nodes (size = MAX_NB_CHILDREN) */
a52fde77
AM
40 private int[] children;
41
cb42195c 42 /** Start times of each of the children (size = MAX_NB_CHILDREN) */
a52fde77
AM
43 private long[] childStart;
44
cb42195c 45 /** Seq number of this node's extension. -1 if none */
62197b87
AM
46 private volatile int extension = -1;
47
48 /**
49 * Lock used to gate the accesses to the children arrays. Meant to be a
50 * different lock from the one in {@link HTNode}.
51 */
52 private final ReentrantReadWriteLock rwl = new ReentrantReadWriteLock(false);
a52fde77
AM
53
54 /**
55 * Initial constructor. Use this to initialize a new EMPTY node.
cb42195c 56 *
ffd0aa67
EB
57 * @param config
58 * Configuration of the History Tree
a52fde77
AM
59 * @param seqNumber
60 * The (unique) sequence number assigned to this particular node
61 * @param parentSeqNumber
62 * The sequence number of this node's parent node
63 * @param start
64 * The earliest timestamp stored in this node
65 */
bb7f92ce 66 public CoreNode(HTConfig config, int seqNumber, int parentSeqNumber,
a52fde77 67 long start) {
ffd0aa67 68 super(config, seqNumber, parentSeqNumber, start);
a52fde77 69 this.nbChildren = 0;
ffd0aa67 70 int size = config.getMaxChildren();
a52fde77
AM
71
72 /*
73 * We instantiate the two following arrays at full size right away,
74 * since we want to reserve that space in the node's header.
75 * "this.nbChildren" will tell us how many relevant entries there are in
76 * those tables.
77 */
cb42195c
AM
78 this.children = new int[size];
79 this.childStart = new long[size];
a52fde77
AM
80 }
81
82 @Override
62197b87 83 protected void readSpecificHeader(ByteBuffer buffer) {
ffd0aa67 84 int size = getConfig().getMaxChildren();
a52fde77
AM
85
86 extension = buffer.getInt();
87 nbChildren = buffer.getInt();
88
cb42195c
AM
89 children = new int[size];
90 for (int i = 0; i < nbChildren; i++) {
a52fde77
AM
91 children[i] = buffer.getInt();
92 }
cb42195c 93 for (int i = nbChildren; i < size; i++) {
a52fde77
AM
94 buffer.getInt();
95 }
96
cb42195c
AM
97 this.childStart = new long[size];
98 for (int i = 0; i < nbChildren; i++) {
a52fde77
AM
99 childStart[i] = buffer.getLong();
100 }
cb42195c 101 for (int i = nbChildren; i < size; i++) {
a52fde77
AM
102 buffer.getLong();
103 }
104 }
105
106 @Override
62197b87 107 protected void writeSpecificHeader(ByteBuffer buffer) {
ffd0aa67 108 int size = getConfig().getMaxChildren();
a52fde77
AM
109
110 buffer.putInt(extension);
111 buffer.putInt(nbChildren);
112
113 /* Write the "children's seq number" array */
cb42195c 114 for (int i = 0; i < nbChildren; i++) {
a52fde77
AM
115 buffer.putInt(children[i]);
116 }
cb42195c 117 for (int i = nbChildren; i < size; i++) {
a52fde77
AM
118 buffer.putInt(0);
119 }
120
121 /* Write the "children's start times" array */
cb42195c 122 for (int i = 0; i < nbChildren; i++) {
a52fde77
AM
123 buffer.putLong(childStart[i]);
124 }
cb42195c 125 for (int i = nbChildren; i < size; i++) {
a52fde77
AM
126 buffer.putLong(0);
127 }
128 }
129
f4baf640 130 @Override
8d47cc34 131 public int getNbChildren() {
62197b87 132 rwl.readLock().lock();
88598bff
LPD
133 try {
134 return nbChildren;
135 } finally {
136 rwl.readLock().unlock();
137 }
a52fde77
AM
138 }
139
f4baf640 140 @Override
8d47cc34 141 public int getChild(int index) {
62197b87
AM
142 rwl.readLock().lock();
143 try {
144 return children[index];
145 } finally {
146 rwl.readLock().unlock();
147 }
a52fde77
AM
148 }
149
f4baf640 150 @Override
8d47cc34 151 public int getLatestChild() {
62197b87
AM
152 rwl.readLock().lock();
153 try {
154 return children[nbChildren - 1];
155 } finally {
156 rwl.readLock().unlock();
157 }
a52fde77
AM
158 }
159
f4baf640 160 @Override
8d47cc34 161 public long getChildStart(int index) {
62197b87
AM
162 rwl.readLock().lock();
163 try {
164 return childStart[index];
165 } finally {
166 rwl.readLock().unlock();
167 }
a52fde77
AM
168 }
169
8d47cc34
AM
170 /**
171 * Get the sequence number of the extension to this node (if there is one).
172 *
173 * @return The sequence number of the extended node. '-1' is returned if
174 * there is no extension node.
175 */
176 public int getExtensionSequenceNumber() {
88598bff
LPD
177 rwl.readLock().lock();
178 try {
179 return extension;
180 } finally {
181 rwl.readLock().unlock();
182 }
a52fde77
AM
183 }
184
f4baf640 185 @Override
bb7f92ce 186 public void linkNewChild(HTNode childNode) {
62197b87
AM
187 rwl.writeLock().lock();
188 try {
f4baf640
GB
189 if (nbChildren >= getConfig().getMaxChildren()) {
190 throw new IllegalStateException("Asked to link another child but parent already has maximum number of children"); //$NON-NLS-1$
191 }
a52fde77 192
62197b87
AM
193 children[nbChildren] = childNode.getSequenceNumber();
194 childStart[nbChildren] = childNode.getNodeStart();
195 nbChildren++;
196
197 } finally {
198 rwl.writeLock().unlock();
199 }
a52fde77
AM
200 }
201
88598bff
LPD
202 @Override
203 public Collection<Integer> selectNextChildren(long t) throws TimeRangeException {
204 if (t < getNodeStart() || (isOnDisk() && t > getNodeEnd())) {
205 throw new TimeRangeException("Requesting children outside the node's range: " + t); //$NON-NLS-1$
206 }
207 rwl.readLock().lock();
208 try {
209 int potentialNextSeqNb = -1;
210 for (int i = 0; i < nbChildren; i++) {
211 if (t >= childStart[i]) {
212 potentialNextSeqNb = children[i];
213 } else {
214 break;
215 }
216 }
217
218 if (potentialNextSeqNb == -1) {
219 throw new IllegalStateException("No next child node found"); //$NON-NLS-1$
220 }
221 return Collections.singleton(potentialNextSeqNb);
222 } finally {
223 rwl.readLock().unlock();
224 }
225 }
226
a52fde77 227 @Override
bb7f92ce
FW
228 public NodeType getNodeType() {
229 return NodeType.CORE;
a52fde77
AM
230 }
231
232 @Override
62197b87 233 protected int getSpecificHeaderSize() {
ffd0aa67 234 int maxChildren = getConfig().getMaxChildren();
cb42195c 235 int specificSize =
d0ed4962
LPD
236 Integer.BYTES /* 1x int (extension node) */
237 + Integer.BYTES /* 1x int (nbChildren) */
a52fde77
AM
238
239 /* MAX_NB * int ('children' table) */
d0ed4962 240 + Integer.BYTES * maxChildren
a52fde77
AM
241
242 /* MAX_NB * Timevalue ('childStart' table) */
d0ed4962 243 + Long.BYTES * maxChildren;
a52fde77 244
62197b87 245 return specificSize;
a52fde77
AM
246 }
247
248 @Override
8d47cc34 249 public String toStringSpecific() {
a52fde77 250 /* Only used for debugging, shouldn't be externalized */
b2ca67ca
PT
251 return String.format("Core Node, %d children %s", //$NON-NLS-1$
252 nbChildren, Arrays.toString(Arrays.copyOf(children, nbChildren)));
a52fde77
AM
253 }
254
255}
This page took 0.092083 seconds and 5 git commands to generate.