blob: 9689e9ef5463bbda9067ccf193d92152fd985348 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013, 2016 Ericsson
*
* 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
*
* Contributors:
* Jean-Christian Kouamé - Initial API and implementation
* Patrick Tasse - Updates to mipmap feature
*******************************************************************************/
package org.eclipse.tracecompass.internal.tmf.core.statesystem.mipmap;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.Map;
import java.util.Set;
import org.eclipse.jdt.annotation.NonNull;
import org.eclipse.tracecompass.internal.tmf.core.Activator;
import org.eclipse.tracecompass.statesystem.core.ITmfStateSystemBuilder;
import org.eclipse.tracecompass.statesystem.core.exceptions.StateValueTypeException;
import org.eclipse.tracecompass.statesystem.core.exceptions.TimeRangeException;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue;
import org.eclipse.tracecompass.statesystem.core.statevalue.ITmfStateValue.Type;
import org.eclipse.tracecompass.tmf.core.statesystem.AbstractTmfStateProvider;
import org.eclipse.tracecompass.tmf.core.trace.ITmfTrace;
/**
* This is an abstract state provider that allows attributes to be mipmapped
* for one or more of the supported mipmap features (min, max, average).
*
* Extend this class for a specific implementation
*/
public abstract class AbstractTmfMipmapStateProvider extends AbstractTmfStateProvider {
/**
* Feature bit for the maximum mipmap feature (value is 1<<1).
*/
public static final int MAX = 1 << 1;
/**
* Feature bit for the minimum mipmap feature (value is 1&lt;&lt;2).
*/
public static final int MIN = 1 << 2;
/**
* Feature bit for the average mipmap feature (value is 1&lt;&lt;3).
*/
public static final int AVG = 1 << 3;
/**
* The string for maximum mipmap feature sub-attribute.
* This attribute value is the mipmap number of levels.
* It has sub-attributes for every level ("1", "2", etc.)
*/
public static final String MAX_STRING = "max"; //$NON-NLS-1$
/**
* The string for minimum mipmap feature sub-attribute.
* This attribute value is the mipmap number of levels.
* It has sub-attributes for every level ("1", "2", etc.)
*/
public static final String MIN_STRING = "min"; //$NON-NLS-1$
/**
* The string for average mipmap feature sub-attribute.
* This attribute value is the mipmap number of levels.
* It has sub-attributes for every level ("1", "2", etc.)
*/
public static final String AVG_STRING = "avg"; //$NON-NLS-1$
/**
* Map of mipmap features per attribute. The map's key is the base attribute quark.
*/
private Map<Integer, Set<ITmfMipmapFeature>> featureMap = new HashMap<>();
// ------------------------------------------------------------------------
// Constructor
// ------------------------------------------------------------------------
/**
* Constructor
*
* @param trace
* The trace directory
* @param id
* The name given to this state change input. Only used
* internally.
*/
public AbstractTmfMipmapStateProvider(@NonNull ITmfTrace trace,
@NonNull String id) {
super(trace, id);
}
// ------------------------------------------------------------------------
// Public methods
// ------------------------------------------------------------------------
@Override
public void dispose() {
waitForEmptyQueue();
for (Set<ITmfMipmapFeature> features : featureMap.values()) {
for (ITmfMipmapFeature feature : features) {
feature.updateAndCloseMipmap();
}
}
super.dispose();
}
/**
* Modify a mipmap attribute. The base attribute is modified and the mipmap
* attributes for the feature(s) specified in the mipmap feature bitmap are
* created and/or updated.<br>
* Note: The mipmapFeatureBits and resolution are only used on the first
* call of this method for a particular attribute, and the mipmap features
* for this attribute are then activated until the end of the trace.<br>
* Note: The base attribute should only be modified by calling this method.
*
* @param ts
* The timestamp of the event
* @param value
* The value of the base attribute
* @param baseQuark
* The quark of the base attribute
* @param mipmapFeatureBits
* The mipmap feature bit(s)
* @param resolution
* The mipmap resolution (must be greater than 1)
* @throws TimeRangeException
* If the requested time is outside of the trace's range
* @throws StateValueTypeException
* If the inserted state value's type does not match what is
* already assigned to this attribute.
* @see #MAX
* @see #MIN
* @see #AVG
*/
public void modifyMipmapAttribute(long ts, ITmfStateValue value, int baseQuark, int mipmapFeatureBits, int resolution)
throws TimeRangeException, StateValueTypeException {
ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
ss.modifyAttribute(ts, value.unboxValue(), baseQuark);
if (value.getType() == Type.LONG || value.getType() == Type.INTEGER || value.getType() == Type.DOUBLE || value.isNull()) {
Set<ITmfMipmapFeature> features = getFeatureSet(baseQuark, ts, value, mipmapFeatureBits, resolution);
for (ITmfMipmapFeature mf : features) {
mf.updateMipmap(value, ts);
}
}
}
// ------------------------------------------------------------------------
// Private methods
// ------------------------------------------------------------------------
private Set<ITmfMipmapFeature> getFeatureSet(int baseQuark, long ts, ITmfStateValue value, int mipmapFeatureBits, int resolution) {
ITmfStateSystemBuilder ss = checkNotNull(getStateSystemBuilder());
Set<ITmfMipmapFeature> features = featureMap.get(baseQuark);
if (features != null) {
return features;
}
features = new LinkedHashSet<>();
if (value.isNull()) {
return features;
}
featureMap.put(baseQuark, features);
if (resolution > 1) {
try {
if ((mipmapFeatureBits & MAX) != 0) {
int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MAX_STRING);
ss.modifyAttribute(ts, 0, featureQuark);
MaxMipmapFeature mf = new MaxMipmapFeature(baseQuark, featureQuark, resolution, ss);
features.add(mf);
}
if ((mipmapFeatureBits & MIN) != 0) {
int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MIN_STRING);
ss.modifyAttribute(ts, 0, featureQuark);
MinMipmapFeature mf = new MinMipmapFeature(baseQuark, featureQuark, resolution, ss);
features.add(mf);
}
if ((mipmapFeatureBits & AVG) != 0) {
int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, AVG_STRING);
ss.modifyAttribute(ts, 0, featureQuark);
AvgMipmapFeature mf = new AvgMipmapFeature(baseQuark, featureQuark, resolution, ss);
features.add(mf);
}
} catch (TimeRangeException e) {
Activator.logError("MipMapProvider : Time stamp outside of time range of state system", e); //$NON-NLS-1$
} catch (StateValueTypeException e) {
Activator.logError("MipMapProvider : Wrong state value type", e); //$NON-NLS-1$
}
}
return features;
}
}