blob: 94339960f6f2f22917256478ca2b35caa7c9b0a9 [file] [log] [blame]
/*******************************************************************************
* 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 2.0 which
* accompanies this distribution, and is available at
* https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
*******************************************************************************/
package org.eclipse.tracecompass.internal.datastore.core.condition;
import java.util.Arrays;
import java.util.Collection;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.provisional.datastore.core.condition.TimeRangeCondition;
/**
* Primitive array backed time range condition
*
* @author Loic Prieur-Drevon
*/
public class ArrayTimeRangeCondition implements TimeRangeCondition {
private final long[] fTimeArray;
/**
* {@link ArrayTimeRangeCondition} from a collection
*
* @param times
* Collection of longs representing times.
*/
public ArrayTimeRangeCondition(Collection<@NonNull Long> times) {
if (times.isEmpty()) {
throw new IllegalArgumentException("QuarkArrayRangeCondition requires a non empty collection"); //$NON-NLS-1$
}
fTimeArray = new long[times.size()];
int i = 0;
for (Long quark : times) {
fTimeArray[i] = quark;
i++;
}
Arrays.sort(fTimeArray);
}
/**
* internal sub condition constructor
*
* @param timeArray
* a sorted array of times.
*/
private ArrayTimeRangeCondition(long[] timeArray) {
fTimeArray = timeArray;
}
@Override
public long min() {
return fTimeArray[0];
}
@Override
public long max() {
return fTimeArray[fTimeArray.length - 1];
}
@Override
public boolean test(long element) {
return Arrays.binarySearch(fTimeArray, element) >= 0;
}
@Override
public boolean intersects(long low, long high) {
int lowIndex = Arrays.binarySearch(fTimeArray, low);
if (lowIndex >= 0) {
// low is one of the times.
return true;
}
if (lowIndex == -fTimeArray.length - 1) {
// low is higher than the maximum times
return false;
}
/**
* -lowIndex - 1 is the insertion position low, which means that the current
* value at -lowIndex - 1 is larger than low. we just need to check that it is
* also smaller than or equal to high for the intersection
*/
return fTimeArray[-lowIndex - 1] <= high;
}
@Override
public @Nullable TimeRangeCondition subCondition(long from, long to) {
if (from <= min() && max() <= to) {
// all the elements are within the bounds
return this;
}
int fromIndex = Arrays.binarySearch(fTimeArray, from);
if (fromIndex == -fTimeArray.length - 1) {
// from is larger than than the maximum quark
return null;
}
fromIndex = (fromIndex >= 0) ? fromIndex : -fromIndex - 1;
int toIndex = Arrays.binarySearch(fTimeArray, fromIndex, fTimeArray.length, to);
if (toIndex == -1) {
// to is smaller than the minimum quark
return null;
}
toIndex = (toIndex >= 0) ? toIndex + 1 : -toIndex - 1;
if (toIndex <= fromIndex) {
return null;
}
return new ArrayTimeRangeCondition(Arrays.copyOfRange(fTimeArray, fromIndex, toIndex));
}
@Override
public String toString() {
return "ArrayTimeRangeCondition[" + fTimeArray.length + "](" + min() + '\u2025' + max() + ')'; //$NON-NLS-1$ //$NON-NLS-2$
}
}