blob: 2307a4d74470f6e4cbdeb58f39a9c83d6bccbf3b [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2016 É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.tmf.chart.core.consumer;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.function.Predicate;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.tracecompass.internal.provisional.tmf.chart.core.resolver.INumericalResolver;
import com.google.common.collect.ImmutableList;
/**
* This class processes numerical values in order to create valid data for a XY
* chart. It takes a {@link INumericalResolver} for mapping values and a
* {@link Predicate} for testing them.
* <p>
* It also computes the minimum and maximum values of all the numbers it has
* consumed.
*
* @author Gabriel-Andrew Pollo-Guilbert
*/
public class NumericalConsumer implements IDataConsumer {
// ------------------------------------------------------------------------
// Members
// ------------------------------------------------------------------------
private final INumericalResolver<Object, Number> fResolver;
private final Predicate<@Nullable Number> fPredicate;
private final List<Number> fData = new ArrayList<>();
private Number fMin;
private Number fMax;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
* Constructor with a default non null predicate.
*
* @param resolver
* The resolver that maps values
*/
public NumericalConsumer(INumericalResolver<Object, Number> resolver) {
fResolver = resolver;
fPredicate = Objects::nonNull;
fMin = fResolver.getMaxValue();
fMax = fResolver.getMinValue();
}
/**
* Overloaded constructor with a predicate.
*
* @param resolver
* The resolver that maps values
* @param predicate
* The predicate for testing values
*/
public NumericalConsumer(INumericalResolver<Object, Number> resolver, Predicate<@Nullable Number> predicate) {
fResolver = resolver;
fPredicate = predicate;
fMin = fResolver.getMaxValue();
fMax = fResolver.getMinValue();
}
// ------------------------------------------------------------------------
// Overriden methods
// ------------------------------------------------------------------------
@Override
public boolean test(Object obj) {
Number number = fResolver.getMapper().apply(obj);
return fPredicate.test(number);
}
@Override
public void accept(Object obj) {
Number number = fResolver.getMapper().apply(obj);
if (number == null) {
number = fResolver.getZeroValue();
}
/* Update the minimum value */
if (fResolver.getComparator().compare(number, fMin) < 0) {
fMin = number;
}
/* Update the maximum value */
if (fResolver.getComparator().compare(number, fMax) > 0) {
fMax = number;
}
fData.add(number);
}
// ------------------------------------------------------------------------
// Accessors
// ------------------------------------------------------------------------
/**
* Accessor that returns the generated list of number.
*
* @return The list of number
*/
public List<Number> getData() {
return ImmutableList.copyOf(fData);
}
/**
* Accessor that returns the minimum numerical value that has been consumed.
*
* @return The minimum value
*/
public Number getMin() {
return fMin;
}
/**
* Accessor that returns the maximum numerical value that has been consumed.
*
* @return The maximum value
*/
public Number getMax() {
return fMax;
}
}