1 /*******************************************************************************
2 * Copyright (c) 2017 École Polytechnique de Montréal
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
8 *******************************************************************************/
10 package org
.eclipse
.tracecompass
.internal
.provisional
.datastore
.core
.historytree
;
12 import java
.io
.IOException
;
13 import java
.nio
.channels
.FileChannel
;
14 import java
.util
.Collection
;
15 import java
.util
.Collections
;
16 import java
.util
.function
.Predicate
;
18 import org
.eclipse
.jdt
.annotation
.Nullable
;
19 import org
.eclipse
.tracecompass
.internal
.provisional
.datastore
.core
.condition
.TimeRangeCondition
;
20 import org
.eclipse
.tracecompass
.internal
.provisional
.datastore
.core
.exceptions
.RangeException
;
21 import org
.eclipse
.tracecompass
.internal
.provisional
.datastore
.core
.interval
.IHTInterval
;
24 * Interface for history tree nodes
26 * @author Geneviève Bastien
28 * The type of objects that will be saved in the tree
30 public interface IHTNode
<E
extends IHTInterval
> {
35 public enum NodeType
{
37 * Core node, which is a "front" node, at any level of the tree except
38 * the bottom-most one. It has children, and may have extensions.
42 * Leaf node, which is a node at the last bottom level of the tree. It
43 * cannot have any children or extensions.
47 private final byte fByte
;
54 * Determine a node type by reading a serialized byte.
57 * The byte representation of the node type
58 * @return The corresponding NodeType
60 public static NodeType
fromByte(byte rep
) {
67 throw new IllegalArgumentException("The NodeType byte " + rep
+ " is not a valid type"); //$NON-NLS-1$ //$NON-NLS-2$
72 * Get the byte representation of this node type. It can then be read
73 * with {@link #fromByte}.
75 * @return The byte matching this node type
77 public byte toByte() {
83 * Write this node to the given file channel.
86 * The file channel to write to (should be sought to be correct
89 * If there was an error writing
91 void writeSelf(FileChannel fc
) throws IOException
;
94 * Get the start time of this node.
96 * @return The start time of this node
101 * Get the end time of this node. Will return {@link Long#MAX_VALUE} if the
102 * node is not yet written to disk, as the real end time is not yet known.
104 * @return The end time of this node.
109 * Get the sequence number of this node.
111 * @return The sequence number of this node
113 int getSequenceNumber();
116 * Get the sequence number of this node's parent.
118 * @return The parent sequence number
120 int getParentSequenceNumber();
123 * Change this node's parent. Used when we create a new root node for
127 * The sequence number of the node that is the new parent
129 void setParentSequenceNumber(int newParent
);
132 * Return if this node is "done" (full and written to disk).
134 * @return If this node is done or not
139 * Add an interval to this node. The caller of this method must make sure that
140 * there is enough space on this node to add this object. Also, it is the
141 * responsibility of the caller to make sure that the element to add is
142 * within the boundary of this node. No check on start and end is expected
143 * to be done in this method.
146 * Interval to add to this node
148 void add(E newInterval
);
151 * We've received word from the containerTree that newest nodes now exist to
152 * our right. (Puts isDone = true and sets the endtime)
155 * The nodeEnd time that the node will have
157 void closeThisNode(long endtime
);
160 * Retrieve the intervals inside this node that match the given conditions.
162 * @param timeCondition
163 * The time-based RangeCondition
164 * @param extraPredicate
165 * Extra predicate to run on the elements. Only those also
166 * matching this predicate will be returned.
167 * @return Iterable of the elements in this node matching the condtions
169 Iterable
<E
> getMatchingIntervals(TimeRangeCondition timeCondition
,
170 Predicate
<E
> extraPredicate
);
173 * Retrieve an interval inside this node that matches the given conditions.
175 * @param timeCondition
176 * The time-based RangeCondition
177 * @param extraPredicate
178 * Extra predicate to run on the elements. Only intervals also
179 * matching this predicate will be returned.
180 * @return An interval matching the conditions or <code>null</code> if no
183 @Nullable E
getMatchingInterval(TimeRangeCondition timeCondition
,
184 Predicate
<E
> extraPredicate
);
187 * Return the total header size of this node (will depend on the node type).
189 * @return The total header size
191 int getTotalHeaderSize();
194 * Returns the free space left in the node to write objects
196 * @return The amount of free space in the node (in bytes)
198 int getNodeFreeSpace();
201 * Returns the current space utilization of this node, as a percentage.
202 * (used space / total usable space, which excludes the header)
204 * @return The percentage (value between 0 and 100) of space utilization in
207 long getNodeUsagePercent();
210 * Get the type of this node
212 * @return The node type
214 NodeType
getNodeType();
217 * Return whether this node has elements in it or is empty
219 * @return <code>true</code> if the node is empty
223 // ---------------------------------------
224 // Methods for nodes with children. Leaf nodes can use these default methods
225 // ---------------------------------------
228 * Return the number of child nodes this node has.
230 * @return The number of child nodes
232 default int getNbChildren() {
237 * Get the child node corresponding to the specified index. It will throw an
238 * {@link IndexOutOfBoundsException} if there is no children at this index.
241 * The index of the child to lookup
242 * @return The child node
244 default int getChild(int index
) {
245 throw new IndexOutOfBoundsException("This node does not have any children"); //$NON-NLS-1$
249 * Get the latest (right-most) child node of this node. This applies only if
250 * the node is allowed to have children, ie is a {@link NodeType#CORE} node,
251 * otherwise this method is not supported.
253 * @return The latest child node
255 default int getLatestChild() {
256 throw new UnsupportedOperationException("This node does not support children"); //$NON-NLS-1$
260 * Tell this node that it has a new child. This applies only if the node is
261 * allowed to have children, ie is a {@link NodeType#CORE} node, otherwise
262 * this method is not supported.
265 * The new child node to add to this one
267 default void linkNewChild(IHTNode
<E
> childNode
) {
268 throw new UnsupportedOperationException("This node does not support children"); //$NON-NLS-1$
272 * Method to select the sequence numbers for the children of the current
273 * node that intersect the given timestamp. Useful when navigating the tree.
275 * @param timeCondition
276 * The time-based range condition to choose which child is the
278 * @return Collection of sequence numbers of the child nodes that intersect
279 * the time condition, non-null empty collection if this is a Leaf
281 * @throws RangeException
282 * If t is out of the node's range
284 default Collection
<Integer
> selectNextChildren(TimeRangeCondition timeCondition
) {
285 return Collections
.emptyList();