| 1 | /******************************************************************************* |
| 2 | * Copyright (c) 2013 Ericsson |
| 3 | * |
| 4 | * All rights reserved. This program and the accompanying materials are made |
| 5 | * 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 | * |
| 9 | * Contributors: |
| 10 | * Jean-Christian Kouamé - Initial API and implementation |
| 11 | * Patrick Tasse - Updates to mipmap feature |
| 12 | *******************************************************************************/ |
| 13 | |
| 14 | package org.eclipse.linuxtools.internal.tmf.core.statesystem.mipmap; |
| 15 | |
| 16 | import java.util.HashMap; |
| 17 | import java.util.LinkedHashSet; |
| 18 | import java.util.Map; |
| 19 | import java.util.Set; |
| 20 | |
| 21 | import org.eclipse.linuxtools.statesystem.core.exceptions.AttributeNotFoundException; |
| 22 | import org.eclipse.linuxtools.statesystem.core.exceptions.StateValueTypeException; |
| 23 | import org.eclipse.linuxtools.statesystem.core.exceptions.TimeRangeException; |
| 24 | import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue; |
| 25 | import org.eclipse.linuxtools.statesystem.core.statevalue.TmfStateValue; |
| 26 | import org.eclipse.linuxtools.statesystem.core.statevalue.ITmfStateValue.Type; |
| 27 | import org.eclipse.linuxtools.tmf.core.event.ITmfEvent; |
| 28 | import org.eclipse.linuxtools.tmf.core.statesystem.AbstractTmfStateProvider; |
| 29 | import org.eclipse.linuxtools.tmf.core.trace.ITmfTrace; |
| 30 | |
| 31 | /** |
| 32 | * This is an abstract state provider that allows attributes to be mipmapped |
| 33 | * for one or more of the supported mipmap features (min, max, average). |
| 34 | * |
| 35 | * Extend this class for a specific implementation |
| 36 | */ |
| 37 | public abstract class AbstractTmfMipmapStateProvider extends AbstractTmfStateProvider { |
| 38 | |
| 39 | /** |
| 40 | * Feature bit for the maximum mipmap feature (value is 1<<1). |
| 41 | */ |
| 42 | public static final int MAX = 1 << 1; |
| 43 | |
| 44 | /** |
| 45 | * Feature bit for the minimum mipmap feature (value is 1<<2). |
| 46 | */ |
| 47 | public static final int MIN = 1 << 2; |
| 48 | |
| 49 | /** |
| 50 | * Feature bit for the average mipmap feature (value is 1<<3). |
| 51 | */ |
| 52 | public static final int AVG = 1 << 3; |
| 53 | |
| 54 | /** |
| 55 | * The string for maximum mipmap feature sub-attribute. |
| 56 | * This attribute value is the mipmap number of levels. |
| 57 | * It has sub-attributes for every level ("1", "2", etc.) |
| 58 | */ |
| 59 | public static final String MAX_STRING = "max"; //$NON-NLS-1$ |
| 60 | |
| 61 | /** |
| 62 | * The string for minimum mipmap feature sub-attribute. |
| 63 | * This attribute value is the mipmap number of levels. |
| 64 | * It has sub-attributes for every level ("1", "2", etc.) |
| 65 | */ |
| 66 | public static final String MIN_STRING = "min"; //$NON-NLS-1$ |
| 67 | |
| 68 | /** |
| 69 | * The string for average mipmap feature sub-attribute. |
| 70 | * This attribute value is the mipmap number of levels. |
| 71 | * It has sub-attributes for every level ("1", "2", etc.) |
| 72 | */ |
| 73 | public static final String AVG_STRING = "avg"; //$NON-NLS-1$ |
| 74 | |
| 75 | /** |
| 76 | * Map of mipmap features per attribute. The map's key is the base attribute quark. |
| 77 | */ |
| 78 | private Map<Integer, Set<ITmfMipmapFeature>> featureMap = new HashMap<>(); |
| 79 | |
| 80 | // ------------------------------------------------------------------------ |
| 81 | // Constructor |
| 82 | // ------------------------------------------------------------------------ |
| 83 | |
| 84 | /** |
| 85 | * Constructor |
| 86 | * |
| 87 | * @param trace |
| 88 | * The trace directory |
| 89 | * @param eventType |
| 90 | * The specific class for the event type |
| 91 | * @param id |
| 92 | * The name given to this state change input. Only used |
| 93 | * internally. |
| 94 | */ |
| 95 | public AbstractTmfMipmapStateProvider(ITmfTrace trace, Class<? extends ITmfEvent> eventType, String id) { |
| 96 | super(trace, eventType, id); |
| 97 | } |
| 98 | |
| 99 | // ------------------------------------------------------------------------ |
| 100 | // Public methods |
| 101 | // ------------------------------------------------------------------------ |
| 102 | |
| 103 | @Override |
| 104 | public void dispose() { |
| 105 | waitForEmptyQueue(); |
| 106 | for (Set<ITmfMipmapFeature> features : featureMap.values()) { |
| 107 | for (ITmfMipmapFeature feature : features) { |
| 108 | feature.updateAndCloseMipmap(); |
| 109 | } |
| 110 | } |
| 111 | super.dispose(); |
| 112 | } |
| 113 | |
| 114 | /** |
| 115 | * Modify a mipmap attribute. The base attribute is modified and the mipmap |
| 116 | * attributes for the feature(s) specified in the mipmap feature bitmap are |
| 117 | * created and/or updated.<br> |
| 118 | * Note: The mipmapFeatureBits and resolution are only used on the first |
| 119 | * call of this method for a particular attribute, and the mipmap features |
| 120 | * for this attribute are then activated until the end of the trace.<br> |
| 121 | * Note: The base attribute should only be modified by calling this method. |
| 122 | * |
| 123 | * @param ts |
| 124 | * The timestamp of the event |
| 125 | * @param value |
| 126 | * The value of the base attribute |
| 127 | * @param baseQuark |
| 128 | * The quark of the base attribute |
| 129 | * @param mipmapFeatureBits |
| 130 | * The mipmap feature bit(s) |
| 131 | * @param resolution |
| 132 | * The mipmap resolution (must be greater than 1) |
| 133 | * @throws TimeRangeException |
| 134 | * If the requested time is outside of the trace's range |
| 135 | * @throws AttributeNotFoundException |
| 136 | * If the requested attribute quark is invalid |
| 137 | * @throws StateValueTypeException |
| 138 | * If the inserted state value's type does not match what is |
| 139 | * already assigned to this attribute. |
| 140 | * @see #MAX |
| 141 | * @see #MIN |
| 142 | * @see #AVG |
| 143 | */ |
| 144 | public void modifyMipmapAttribute(long ts, ITmfStateValue value, int baseQuark, int mipmapFeatureBits, int resolution) |
| 145 | throws TimeRangeException, AttributeNotFoundException, StateValueTypeException { |
| 146 | ss.modifyAttribute(ts, value, baseQuark); |
| 147 | if (value.getType() == Type.LONG || value.getType() == Type.INTEGER || value.getType() == Type.DOUBLE || value.isNull()) { |
| 148 | Set<ITmfMipmapFeature> features = getFeatureSet(baseQuark, ts, value, mipmapFeatureBits, resolution); |
| 149 | for (ITmfMipmapFeature mf : features) { |
| 150 | mf.updateMipmap(value, ts); |
| 151 | } |
| 152 | } |
| 153 | } |
| 154 | |
| 155 | // ------------------------------------------------------------------------ |
| 156 | // Private methods |
| 157 | // ------------------------------------------------------------------------ |
| 158 | |
| 159 | private Set<ITmfMipmapFeature> getFeatureSet(int baseQuark, long ts, ITmfStateValue value, int mipmapFeatureBits, int resolution) { |
| 160 | Set<ITmfMipmapFeature> features = featureMap.get(baseQuark); |
| 161 | if (features != null) { |
| 162 | return features; |
| 163 | } |
| 164 | features = new LinkedHashSet<>(); |
| 165 | if (value.isNull()) { |
| 166 | return features; |
| 167 | } |
| 168 | featureMap.put(baseQuark, features); |
| 169 | if (resolution > 1) { |
| 170 | try { |
| 171 | if ((mipmapFeatureBits & MAX) != 0) { |
| 172 | int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MAX_STRING); |
| 173 | ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); |
| 174 | MaxMipmapFeature mf = new MaxMipmapFeature(baseQuark, featureQuark, resolution, ss); |
| 175 | features.add(mf); |
| 176 | } |
| 177 | if ((mipmapFeatureBits & MIN) != 0) { |
| 178 | int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, MIN_STRING); |
| 179 | ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); |
| 180 | MinMipmapFeature mf = new MinMipmapFeature(baseQuark, featureQuark, resolution, ss); |
| 181 | features.add(mf); |
| 182 | } |
| 183 | if ((mipmapFeatureBits & AVG) != 0) { |
| 184 | int featureQuark = ss.getQuarkRelativeAndAdd(baseQuark, AVG_STRING); |
| 185 | ss.modifyAttribute(ts, TmfStateValue.newValueInt(0), featureQuark); |
| 186 | AvgMipmapFeature mf = new AvgMipmapFeature(baseQuark, featureQuark, resolution, ss); |
| 187 | features.add(mf); |
| 188 | } |
| 189 | } catch (TimeRangeException e) { |
| 190 | e.printStackTrace(); |
| 191 | } catch (AttributeNotFoundException e) { |
| 192 | e.printStackTrace(); |
| 193 | } catch (StateValueTypeException e) { |
| 194 | e.printStackTrace(); |
| 195 | } |
| 196 | } |
| 197 | return features; |
| 198 | } |
| 199 | } |