--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.internal.datastore.core.condition;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
+import org.junit.Test;
+
+/**
+ * Test the continuous time range condition
+ *
+ * @author Loïc Prieur-Drevon
+ */
+public class ContinuousTimeRangeConditionTest {
+
+ private static final long LOW = 0;
+ private static final long HIGH = 10;
+ private static final ContinuousTimeRangeCondition CONDITION = new ContinuousTimeRangeCondition(LOW, HIGH);
+
+ /**
+ * Ensure that we cannot build a condition with a bigger low than high bound.
+ */
+ @Test(expected = IllegalArgumentException.class)
+ public void testConstructor() {
+ new ContinuousTimeRangeCondition(HIGH, LOW);
+ }
+
+ /**
+ * Ensure that the minimum and maximum functions return the correct values.
+ */
+ @Test
+ public void testBounds() {
+ long low = CONDITION.min();
+ assertEquals(LOW, low);
+ long high = CONDITION.max();
+ assertEquals(HIGH, high);
+ }
+
+ /**
+ * Test that the right elements are contained in the condition.
+ */
+ @Test
+ public void testPredicate() {
+ assertFalse(CONDITION.test(-5));
+ assertTrue(CONDITION.test(LOW));
+ assertTrue(CONDITION.test(5));
+ assertTrue(CONDITION.test(HIGH));
+ assertFalse(CONDITION.test(15));
+ }
+
+ /**
+ * Test that the right intervals intersect the condition.
+ */
+ @Test
+ public void testIntersects() {
+ assertFalse(CONDITION.intersects(Integer.MIN_VALUE, LOW - 1));
+ assertTrue(CONDITION.intersects(-5, 5));
+ assertTrue(CONDITION.intersects(2, 8));
+ assertTrue(CONDITION.intersects(5, 15));
+ assertFalse(CONDITION.intersects(HIGH + 1, Integer.MAX_VALUE));
+ }
+
+ /**
+ * Test that the returned subcondition has the correct bounds.
+ */
+ @Test
+ public void testSubCondition() {
+ TimeRangeCondition sub = CONDITION.subCondition(-5, 8);
+ assertNotNull(sub);
+ assertEquals(ContinuousTimeRangeCondition.class, sub.getClass());
+ long low = sub.min();
+ long high = sub.max();
+ assertEquals(LOW, low);
+ assertEquals(8, high);
+
+ sub = CONDITION.subCondition(HIGH + 1, HIGH + 10);
+ assertNull(sub);
+ sub = CONDITION.subCondition(LOW - 10, LOW - 1);
+ assertNull(sub);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ ******************************************************************************/
+
+package org.eclipse.tracecompass.internal.datastore.core.condition;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
+import org.junit.Test;
+
+/**
+ * Test the singleton time range condition
+ *
+ * @author Geneviève Bastien
+ */
+public class SingletonTimeRangeConditionTest {
+
+ private static final long VALUE = 5;
+ private static final SingletonTimeRangeCondition CONDITION = new SingletonTimeRangeCondition(VALUE);
+
+ /**
+ * Ensure that the minimum and maximum functions return the correct values.
+ */
+ @Test
+ public void testBounds() {
+ assertEquals(VALUE, (int) CONDITION.min());
+ assertEquals(VALUE, (int) CONDITION.max());
+ }
+
+ /**
+ * Test that the right elements are contained in the condition.
+ */
+ @Test
+ public void testPredicate() {
+ assertFalse(CONDITION.test(-5));
+ assertTrue(CONDITION.test(VALUE));
+ assertFalse(CONDITION.test(15));
+ }
+
+ /**
+ * Test that the right intervals intersect the condition.
+ */
+ @Test
+ public void testIntersects() {
+ assertFalse(CONDITION.intersects(Integer.MIN_VALUE, VALUE - 1));
+ assertTrue(CONDITION.intersects(VALUE - 1, VALUE + 1));
+ assertTrue(CONDITION.intersects(VALUE, VALUE + 1));
+ assertTrue(CONDITION.intersects(VALUE - 1, VALUE));
+ assertFalse(CONDITION.intersects(VALUE + 1, Integer.MAX_VALUE));
+ }
+
+ /**
+ * Test that the returned subcondition has the correct bounds.
+ */
+ @Test
+ public void testSubCondition() {
+ TimeRangeCondition sub = CONDITION.subCondition(VALUE - 1, VALUE + 1);
+ assertNotNull(sub);
+ assertEquals(sub, CONDITION);
+
+ // For a range where no value is include, it should return null
+ sub = CONDITION.subCondition(Long.MIN_VALUE, VALUE - 1);
+ assertNull(sub);
+
+ sub = CONDITION.subCondition(VALUE + 1, VALUE + 2);
+ assertNull(sub);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.datastore.core.condition;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
+
+/**
+ * Time range condition that will verify if values are within a range limited by
+ * a lower and upper bound.
+ *
+ * @author Geneviève Bastien
+ */
+public class ContinuousTimeRangeCondition implements TimeRangeCondition {
+
+ private final long fLongMin;
+ private final long fLongMax;
+
+ /**
+ * Constructor
+ *
+ * @param low
+ * Lower bound of the range
+ * @param high
+ * Upper bound of the range
+ */
+ public ContinuousTimeRangeCondition(long low, long high) {
+ if (high < low) {
+ throw new IllegalArgumentException("Continuous time range condition: lower bound (" + low +") should be <= upper bound (" + high + ')'); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ fLongMin = low;
+ fLongMax = high;
+ }
+
+ @Override
+ public long min() {
+ return fLongMin;
+ }
+
+ @Override
+ public long max() {
+ return fLongMax;
+ }
+
+ @Override
+ public boolean test(long element) {
+ return (element >= fLongMin && element <= fLongMax);
+ }
+
+ @Override
+ public boolean intersects(long low, long high) {
+ return (fLongMin <= high && fLongMax >= low);
+ }
+
+ @Override
+ public @Nullable TimeRangeCondition subCondition(long from, long to) {
+ long low = Math.max(from, fLongMin);
+ long high = Math.min(fLongMax, to);
+ if (high < low) {
+ return null;
+ }
+ return new ContinuousTimeRangeCondition(low, high);
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.datastore.core.condition;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
+
+/**
+ * A time range condition for a singleton time.
+ *
+ * @author Geneviève Bastien
+ */
+public class SingletonTimeRangeCondition implements TimeRangeCondition {
+
+ private final long fValue;
+
+ /**
+ * Constructor
+ *
+ * @param ts
+ * The timestamp for this condition
+ */
+ public SingletonTimeRangeCondition(long ts) {
+ fValue = ts;
+ }
+
+ @Override
+ public long min() {
+ return fValue;
+ }
+
+ @Override
+ public long max() {
+ return fValue;
+ }
+
+ @Override
+ public boolean test(long element) {
+ return element == fValue;
+ }
+
+ @Override
+ public boolean intersects(long low, long high) {
+ return low <= fValue && high >= fValue;
+ }
+
+ @Override
+ public @Nullable TimeRangeCondition subCondition(long from, long to) {
+ if (intersects(from, to)) {
+ return this;
+ }
+ return null;
+ }
+
+}
--- /dev/null
+/*******************************************************************************
+ * Copyright (c) 2017 École Polytechnique de Montréal
+ *
+ * All rights reserved. This program and the accompanying materials are
+ * made available under the terms of the Eclipse Public License v1.0 which
+ * accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *******************************************************************************/
+
+package org.eclipse.tracecompass.internal.provisional.datastore.core.condition;
+
+import org.eclipse.jdt.annotation.Nullable;
+import org.eclipse.tracecompass.internal.datastore.core.condition.ContinuousTimeRangeCondition;
+import org.eclipse.tracecompass.internal.datastore.core.condition.SingletonTimeRangeCondition;
+
+/**
+ * A range condition specific for time ranges. It allows to work with long
+ * primitive types, which provides much better performances
+ *
+ * @author Geneviève Bastien
+ */
+public interface TimeRangeCondition {
+
+ /**
+ * Get the lower bound of this range
+ *
+ * @return the lowest acceptable value for this condition.
+ */
+ long min();
+
+ /**
+ * Get the upper bound of this range
+ *
+ * @return the highest acceptable value for this condition.
+ */
+ long max();
+
+ /**
+ * Test whether a value is within this specific range boundaries. If the
+ * range is continuous, it will return <code>true</code> if the value is
+ * between the lower and upper bounds. If the range is discrete, it will
+ * return <code>true</code> if the requested element is one of the elements
+ * in the discrete range.
+ *
+ * @param element
+ * value that we want to test
+ * @return true if element is contained in this condition's set or range
+ */
+ boolean test(long element);
+
+ /**
+ * Determine if the current range intersects a ranged bounded by the values
+ * in parameter
+ *
+ * @param low
+ * interval's lower bound
+ * @param high
+ * interval's upper bound
+ * @return true if this element intersects the range's condition or any of
+ * the set's elements
+ */
+ boolean intersects(long low, long high);
+
+ /**
+ * Reduce the Condition to elements or the range within bounds from and to.
+ * <code>null</code> is returned if the resulting condition is empty.
+ *
+ * @param from
+ * lower bound for the condition reduction.
+ * @param to
+ * upper bound for the condition reduction.
+ * @return the reduced condition or <code>null</code> if the reduced
+ * condition does not contain any element
+ */
+ @Nullable TimeRangeCondition subCondition(long from, long to);
+
+ /**
+ * Get a condition of a single element.
+ *
+ * @param elem The single element
+ * @return The corresponding range condition
+ */
+ static TimeRangeCondition singleton(long elem) {
+ return new SingletonTimeRangeCondition(elem);
+ }
+
+ /**
+ * Get a range condition representing a continuous time range.
+ *
+ * @param bound1
+ * The first bound
+ * @param bound2
+ * The second bound. It's fine for bound2 to be > or < than
+ * bound1.
+ * @return The corresponding range condition
+ */
+ static TimeRangeCondition forContinuousRange(long bound1, long bound2) {
+ if (bound2 < bound1) {
+ throw new IllegalArgumentException("Continuous time range condition: lower bound (" + bound1 +") should be <= upper bound (" + bound2 + ')'); //$NON-NLS-1$//$NON-NLS-2$
+ }
+ return new ContinuousTimeRangeCondition(bound1, bound2);
+ }
+
+}
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.common.core.NonNullUtils;
import org.eclipse.tracecompass.internal.datastore.core.historytree.HtIo;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions.RangeException;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.IHTNode.NodeType;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
}
@Override
- public Iterable<E> getMatchingIntervals(RangeCondition<Long> timeCondition,
+ public Iterable<E> getMatchingIntervals(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate) {
// TODO Change this to evaluate the nodes lazily
while (!queue.isEmpty()) {
int sequenceNumber = queue.pop();
HTNode<E> currentNode = readNode(sequenceNumber);
- RangeCondition<Long> nodeCondition = timeCondition.subCondition(
+ TimeRangeCondition nodeCondition = timeCondition.subCondition(
currentNode.getNodeStart(), currentNode.getNodeEnd());
if (nodeCondition == null) {
}
@Override
- public @Nullable E getMatchingInterval(RangeCondition<Long> timeCondition,
+ public @Nullable E getMatchingInterval(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate) {
/* Queue a stack of nodes containing nodes intersecting t */
Collection<Integer> nextChildren;
for (long t = parent.getNodeStart(); t < parent.getNodeEnd(); t++) {
shouldBeInCollection = true;
- nextChildren = parent.selectNextChildren(RangeCondition.singleton(t));
+ nextChildren = parent.selectNextChildren(TimeRangeCondition.singleton(t));
if (shouldBeInCollection != nextChildren.contains(childSequence)) {
return false;
}
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions.RangeException;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree.IHTNodeFactory;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
* @return Collection of sequence numbers of the child nodes that
* intersect t, non-null empty collection if this is a Leaf Node
*/
- public final Collection<Integer> selectNextChildren(RangeCondition<Long> timeCondition) {
+ public final Collection<Integer> selectNextChildren(TimeRangeCondition timeCondition) {
fNode.takeReadLock();
try {
return selectNextIndices(timeCondition).stream()
* @return Collection of the indices of the child nodes that intersect
* the time condition
*/
- protected Collection<Integer> selectNextIndices(RangeCondition<Long> timeCondition) {
+ protected Collection<Integer> selectNextIndices(TimeRangeCondition timeCondition) {
/* By default, all children are returned */
List<Integer> childList = new ArrayList<>();
for (int i = 0; i < fNbChildren; i++) {
* comparator.
*
* NOTE: sub-classes who override this may also need to override the
- * {@link #getStartIndexFor(RangeCondition, Predicate)}.
+ * {@link #getStartIndexFor(TimeRangeCondition, Predicate)}.
*
* @return The way intervals are to be sorted in this node
*/
}
@Override
- public Iterable<E> getMatchingIntervals(RangeCondition<Long> timeCondition,
+ public Iterable<E> getMatchingIntervals(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate) {
// TODO Benchmark using/returning streams instead of iterables
}
@Override
- public @Nullable E getMatchingInterval(RangeCondition<Long> timeCondition, Predicate<E> extraPredicate) {
+ public @Nullable E getMatchingInterval(TimeRangeCondition timeCondition, Predicate<E> extraPredicate) {
if (isOnDisk()) {
return doGetMatchingInterval(timeCondition, extraPredicate);
}
}
}
- private Iterable<E> doGetMatchingIntervals(RangeCondition<Long> timeCondition,
+ private Iterable<E> doGetMatchingIntervals(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate) {
List<E> list = new ArrayList<>();
for (int i = getStartIndexFor(timeCondition, extraPredicate); i < fIntervals.size(); i++) {
return list;
}
- private @Nullable E doGetMatchingInterval(RangeCondition<Long> timeCondition,
+ private @Nullable E doGetMatchingInterval(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate) {
for (int i = getStartIndexFor(timeCondition, extraPredicate); i < fIntervals.size(); i++) {
E curInterval = fIntervals.get(i);
* @return The index of the first interval greater than or equal to the
* conditions in parameter
*/
- protected int getStartIndexFor(RangeCondition<Long> timeCondition, Predicate<E> extraPredicate) {
+ protected int getStartIndexFor(TimeRangeCondition timeCondition, Predicate<E> extraPredicate) {
if (fIntervals.isEmpty()) {
return 0;
}
}
@Override
- public Collection<Integer> selectNextChildren(RangeCondition<Long> timeCondition)
+ public Collection<Integer> selectNextChildren(TimeRangeCondition timeCondition)
throws RangeException {
CoreNodeData extraData = fExtraData;
if (extraData != null) {
import java.util.function.Predicate;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions.RangeException;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
* matching this predicate will be returned.
* @return Iterable of the elements in this node matching the condtions
*/
- Iterable<E> getMatchingIntervals(RangeCondition<Long> timeCondition,
+ Iterable<E> getMatchingIntervals(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate);
/**
* @return An interval matching the conditions or <code>null</code> if no
* interval was found
*/
- @Nullable E getMatchingInterval(RangeCondition<Long> timeCondition,
+ @Nullable E getMatchingInterval(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate);
/**
* @throws RangeException
* If t is out of the node's range
*/
- default Collection<Integer> selectNextChildren(RangeCondition<Long> timeCondition) {
+ default Collection<Integer> selectNextChildren(TimeRangeCondition timeCondition) {
return Collections.emptyList();
}
import java.util.function.Predicate;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions.RangeException;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
* Iterable.
* @return An Iterable of the matching elements
*/
- Iterable<E> getMatchingIntervals(RangeCondition<Long> timeCondition,
+ Iterable<E> getMatchingIntervals(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate);
/**
* @return An interval matching the given conditions, or <code>null</code>
* if no interval was found.
*/
- @Nullable E getMatchingInterval(RangeCondition<Long> timeCondition,
+ @Nullable E getMatchingInterval(TimeRangeCondition timeCondition,
Predicate<E> extraPredicate);
// ------------------------------------------------------------------------
import java.io.IOException;
import java.util.Collection;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
protected boolean verifyIntersectingChildren(ClassicNode<E> parent, ClassicNode<E> child) {
int childSequence = child.getSequenceNumber();
for (long t = parent.getNodeStart(); t < parent.getNodeEnd(); t++) {
- RangeCondition<Long> timeCondition = RangeCondition.singleton(t);
+ TimeRangeCondition timeCondition = TimeRangeCondition.singleton(t);
boolean shouldBeInCollection = timeCondition.intersects(child.getNodeStart(), child.getNodeEnd());
Collection<Integer> nextChildren = parent.selectNextChildren(timeCondition);
/* There should be only one intersecting child */
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.exceptions.RangeException;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTNode;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.IHTNode;
}
@Override
- protected Collection<Integer> selectNextIndices(RangeCondition<Long> rc) {
+ protected Collection<Integer> selectNextIndices(TimeRangeCondition rc) {
ClassicNode<?> node = getNode();
if (rc.min() < node.getNodeStart()
import java.io.IOException;
import java.util.Collection;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.AbstractHistoryTree;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTIntervalReader;
boolean shouldBeInCollection;
Collection<Integer> nextChildren;
for (long t = parent.getNodeStart(); t < parent.getNodeEnd(); t++) {
- RangeCondition<Long> timeCondition = RangeCondition.singleton(t);
+ TimeRangeCondition timeCondition = TimeRangeCondition.singleton(t);
shouldBeInCollection = (timeCondition.intersects(child.getNodeStart(), child.getNodeEnd()));
nextChildren = parent.selectNextChildren(timeCondition);
if (shouldBeInCollection != nextChildren.contains(childSequence)) {
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
-import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.RangeCondition;
+import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.HTNode;
import org.eclipse.tracecompass.internal.provisional.datastore.core.historytree.IHTNode;
import org.eclipse.tracecompass.internal.provisional.datastore.core.interval.IHTInterval;
}
@Override
- protected Collection<Integer> selectNextIndices(RangeCondition<Long> rc) {
+ protected Collection<Integer> selectNextIndices(TimeRangeCondition rc) {
OverlappingNode<?> node = getNode();
if (rc.max() < node.getNodeStart()