* @author alexmont
*
*/
-abstract class Attribute {
+public abstract class Attribute {
private final Attribute parent;
private final String name;
private final int quark;
+
+ /** The list of sub-attributes */
protected final List<Attribute> subAttributes;
/**
* Constructor
+ *
+ * @param parent
+ * The parent attribute of this one. Can be 'null' to represent
+ * this attribute is the root node of the tree.
+ * @param name
+ * Base name of this attribute
+ * @param quark
+ * The integer representation of this attribute
*/
- Attribute(Attribute parent, String name, int quark) {
+ public Attribute(Attribute parent, String name, int quark) {
this.parent = parent;
this.quark = quark;
this.name = name;
this.subAttributes = new ArrayList<>();
}
+ // ------------------------------------------------------------------------
+ // Accessors
+ // ------------------------------------------------------------------------
+
/**
- * @name Accessors
+ * Get the quark (integer representation) of this attribute.
+ *
+ * @return The quark of this attribute
*/
-
- int getQuark() {
+ public int getQuark() {
return quark;
}
- Attribute getParent() {
- return parent;
+ /**
+ * Get the name of this attribute.
+ *
+ * @return The name of this attribute
+ */
+ public String getName() {
+ return name;
}
- List<Attribute> getSubAttributes() {
+ /**
+ * Get the list of child attributes below this one. This is a read-only
+ * view.
+ *
+ * @return The list of child attributes.
+ */
+ public List<Attribute> getSubAttributes() {
return Collections.unmodifiableList(subAttributes);
}
- String getName() {
- return name;
- }
-
/**
* Get the matching quark for a given path-of-strings
*
* The path we are looking for, *relative to this node*.
* @return The matching quark, or -1 if that attribute does not exist.
*/
- int getSubAttributeQuark(String... path) {
+ public int getSubAttributeQuark(String... path) {
return this.getSubAttributeQuark(path, 0);
}
* @return The Node object matching the last element in the path, or "null"
* if that attribute does not exist.
*/
- Attribute getSubAttributeNode(String... path) {
+ public Attribute getSubAttributeNode(String... path) {
return this.getSubAttributeNode(path, 0);
}
}
/* The methods how to access children are left to derived classes */
- abstract void addSubAttribute(Attribute newSubAttribute);
- abstract Attribute getSubAttributeNode(String[] path, int index);
+
+ /**
+ * Add a sub-attribute to this attribute
+ *
+ * @param newSubAttribute The new attribute to add
+ */
+ protected abstract void addSubAttribute(Attribute newSubAttribute);
+
+ /**
+ * Get a sub-attribute from this node's sub-attributes
+ *
+ * @param path
+ * The *full* path to the attribute
+ * @param index
+ * The index in 'path' where this attribute is located
+ * (indicating where to start searching).
+ * @return The requested attribute
+ */
+ protected abstract Attribute getSubAttributeNode(String[] path, int index);
/**
* Return a String array composed of the full (absolute) path representing
*
* @return
*/
- String[] getFullAttribute() {
+ private String[] getFullAttribute() {
LinkedList<String> list = new LinkedList<>();
Attribute curNode = this;
/* Add recursive parents to the list, but stop at the root node */
- while (curNode.getParent() != null) {
+ while (curNode.parent != null) {
list.addFirst(curNode.getName());
- curNode = curNode.getParent();
+ curNode = curNode.parent;
}
return list.toArray(new String[0]);
* Return the absolute path of this attribute, as a single slash-separated
* String.
*
- * @return
+ * @return The full name of this attribute
*/
- String getFullAttributeName() {
+ public String getFullAttributeName() {
String[] array = this.getFullAttribute();
StringBuffer buf = new StringBuffer();
return;
}
- void debugPrint(PrintWriter writer) {
+ /**
+ * Debugging method to print the contents of this attribute
+ *
+ * @param writer
+ * PrintWriter where to write the information
+ */
+ public void debugPrint(PrintWriter writer) {
/* Only used for debugging, shouldn't be externalized */
writer.println("------------------------------"); //$NON-NLS-1$
writer.println("Attribute tree: (quark)\n"); //$NON-NLS-1$
*/
final class AlphaNumAttribute extends Attribute {
- private Map<String, Integer> subAttributesMap;
+ private final Map<String, Integer> subAttributesMap;
- AlphaNumAttribute(Attribute parent, String name, int quark) {
+ public AlphaNumAttribute(Attribute parent, String name, int quark) {
super(parent, name, quark);
this.subAttributesMap = new HashMap<>();
}
@Override
- synchronized void addSubAttribute(Attribute newSubAttribute) {
+ protected synchronized void addSubAttribute(Attribute newSubAttribute) {
assert (newSubAttribute != null);
assert (newSubAttribute.getName() != null);
/* This should catch buggy state changing statements */
* @param ss
* The StateSystem to which this AT is attached
*/
- AttributeTree(StateSystem ss) {
+ public AttributeTree(StateSystem ss) {
this.ss = ss;
this.attributeList = Collections.synchronizedList(new ArrayList<Attribute>());
this.attributeTreeRoot = new AlphaNumAttribute(null, "root", -1); //$NON-NLS-1$
* File stream where to read the AT information. Make sure it's
* sought at the right place!
* @throws IOException
+ * If there is a problem reading from the file stream
*/
- AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
+ public AttributeTree(StateSystem ss, FileInputStream fis) throws IOException {
this(ss);
DataInputStream in = new DataInputStream(new BufferedInputStream(fis));
}
/**
- * Tell the Attribute Tree to write itself somewhere. The passed
- * FileOutputStream defines where (which file/position).
+ * Tell the Attribute Tree to write itself somewhere in a file.
*
- * @param fos
- * Where to write. Make sure it's sought at the right position
- * you want.
+ * @param file
+ * The file to write to
+ * @param pos
+ * The position (in bytes) in the file where to write
* @return The total number of bytes written.
*/
- int writeSelf(File file, long pos) {
+ public int writeSelf(File file, long pos) {
int total = 0;
byte[] curByteArray;
* this also equals the integer value (quark) the next added attribute will
* have.
*
- * @return
+ * @return The current number of attributes in the tree
*/
- int getNbAttributes() {
+ public int getNbAttributes() {
return attributeList.size();
}
/**
- * This is the version to specifically add missing attributes.
- *
- * If 'numericalNode' is true, all the new attributes created will be of
- * type 'NumericalNode' instead of 'AlphaNumNode'. Be careful with this, if
- * you do not want ALL added attributes to be numerical, call this function
- * first with 'false' to create the parent nodes, then call it again to make
- * sure only the final node is numerical.
+ * Get the quark for a given attribute path. No new attribute will be
+ * created : if the specified path does not exist, throw an error.
*
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the specified attribute
* @throws AttributeNotFoundException
+ * If the specified path was not found
*/
- int getQuarkDontAdd(int startingNodeQuark, String... subPath)
+ public int getQuarkDontAdd(int startingNodeQuark, String... subPath)
throws AttributeNotFoundException {
assert (startingNodeQuark >= -1);
return knownQuark;
}
- // FIXME synchronized here is probably quite costly... maybe only locking
- // the "for" would be enough?
- synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
+ /**
+ * Get the quark of a given attribute path. If that specified path does not
+ * exist, it will be created (and the quark that was just created will be
+ * returned).
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which relative queries will
+ * start. Use '-1' to start at the root node.
+ * @param subPath
+ * The path to the attribute, relative to the starting node.
+ * @return The quark of the attribute represented by the path
+ */
+ public synchronized int getQuarkAndAdd(int startingNodeQuark, String... subPath) {
+ // FIXME synchronized here is probably quite costly... maybe only locking
+ // the "for" would be enough?
assert (subPath != null && subPath.length > 0);
assert (startingNodeQuark >= -1);
return knownQuark;
}
- int getSubAttributesCount(int quark) {
- return attributeList.get(quark).getSubAttributes().size();
- }
-
/**
* Returns the sub-attributes of the quark passed in parameter
*
* @param attributeQuark
+ * The quark of the attribute to print the sub-attributes of.
* @param recursive
- * @return
+ * Should the query be recursive or not? If false, only children
+ * one level deep will be returned. If true, all descendants will
+ * be returned (depth-first search)
+ * @return The list of quarks representing the children attributes
* @throws AttributeNotFoundException
+ * If 'attributeQuark' is invalid, or if there is no attrbiute
+ * associated to it.
*/
- List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
+ public List<Integer> getSubAttributes(int attributeQuark, boolean recursive)
throws AttributeNotFoundException {
List<Integer> listOfChildren = new ArrayList<>();
Attribute startingAttribute;
}
}
- String getAttributeName(int quark) {
+ /**
+ * Get then base name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The (base) name of the attribute
+ */
+ public String getAttributeName(int quark) {
return attributeList.get(quark).getName();
}
- String getFullAttributeName(int quark) {
+ /**
+ * Get the full path name of an attribute specified by a quark.
+ *
+ * @param quark
+ * The quark of the attribute
+ * @return The full path name of the attribute
+ */
+ public String getFullAttributeName(int quark) {
if (quark >= attributeList.size() || quark < 0) {
return null;
}
return attributeList.get(quark).getFullAttributeName();
}
- void debugPrint(PrintWriter writer) {
+ /**
+ * Debug-print all the attributes in the tree.
+ *
+ * @param writer
+ * The writer where to print the output
+ */
+ public void debugPrint(PrintWriter writer) {
attributeTreeRoot.debugPrint(writer);
}
-}
\ No newline at end of file
+}
import org.eclipse.linuxtools.tmf.core.statevalue.ITmfStateValue.Type;
/**
- * The Transient State is used to build intervals from punctual state changes. It
- * contains a "state info" vector similar to the "current state", except here we
- * also record the start time of every state stored in it.
+ * The Transient State is used to build intervals from punctual state changes.
+ * It contains a "state info" vector similar to the "current state", except here
+ * we also record the start time of every state stored in it.
*
- * We can then build StateInterval's, to be inserted in the State History when
- * we detect state changes : the "start time" of the interval will be the
- * recorded time we have here, and the "end time" will be the timestamp of the
- * new state-changing event we just read.
- *
- * @author alexmont
+ * We can then build {@link ITmfStateInterval}'s, to be inserted in a
+ * {@link IStateHistoryBackend} when we detect state changes : the "start time"
+ * of the interval will be the recorded time we have here, and the "end time"
+ * will be the timestamp of the new state-changing event we just read.
*
+ * @author Alexandre Montplaisir
*/
-class TransientState {
+public class TransientState {
/* Indicates where to insert state changes that we generate */
private final IStateHistoryBackend backend;
private List<Long> ongoingStateStartTimes;
private List<Type> stateValueTypes;
- TransientState(IStateHistoryBackend backend) {
+ /**
+ * Constructor
+ *
+ * @param backend
+ * The back-end in which to insert the generated state intervals
+ */
+ public TransientState(IStateHistoryBackend backend) {
this.backend = backend;
isActive = true;
ongoingStateInfo = new ArrayList<>();
}
}
- long getLatestTime() {
+ /**
+ * Get the latest time we have seen so far.
+ *
+ * @return The latest time seen in the transient state
+ */
+ public long getLatestTime() {
return latestTime;
}
- ITmfStateValue getOngoingStateValue(int index) throws AttributeNotFoundException {
- checkValidAttribute(index);
- return ongoingStateInfo.get(index);
+ /**
+ * Retrieve the ongoing state value for a given index (attribute quark).
+ *
+ * @param quark
+ * The quark of the attribute to look for
+ * @return The corresponding state value
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public ITmfStateValue getOngoingStateValue(int quark) throws AttributeNotFoundException {
+ checkValidAttribute(quark);
+ return ongoingStateInfo.get(quark);
}
- long getOngoingStartTime(int index) throws AttributeNotFoundException {
- checkValidAttribute(index);
- return ongoingStateStartTimes.get(index);
+ /**
+ * Retrieve the start time of the state in which the given attribute is in.
+ *
+ * @param quark
+ * The quark of the attribute to look for
+ * @return The start time of the current state for this attribute
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public long getOngoingStartTime(int quark) throws AttributeNotFoundException {
+ checkValidAttribute(quark);
+ return ongoingStateStartTimes.get(quark);
}
- void changeOngoingStateValue(int index, ITmfStateValue newValue)
+ /**
+ * Modify the current state for a given attribute. This will not update the
+ * "ongoing state start time" in any way, so be careful when using this.
+ *
+ * @param quark
+ * The quark of the attribute to modify
+ * @param newValue
+ * The state value the attribute should have
+ * @throws AttributeNotFoundException
+ * If the quark is invalid
+ */
+ public void changeOngoingStateValue(int quark, ITmfStateValue newValue)
throws AttributeNotFoundException {
- checkValidAttribute(index);
- ongoingStateInfo.set(index, newValue);
+ checkValidAttribute(quark);
+ ongoingStateInfo.set(quark, newValue);
}
/**
- * Return the "ongoing" value for a given attribute as a dummy interval
- * whose end time = -1 (since we don't know its real end time yet).
+ * Convenience method to return the "ongoing" value for a given attribute as
+ * a dummy interval whose end time = -1 (since we don't know its real end
+ * time yet).
*
* @param quark
+ * The quark of the attribute
+ * @return An interval representing the current state (but whose end time is
+ * meaningless)
* @throws AttributeNotFoundException
+ * If the quark is invalid
*/
- ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException {
+ public ITmfStateInterval getOngoingInterval(int quark) throws AttributeNotFoundException {
checkValidAttribute(quark);
return new TmfStateInterval(ongoingStateStartTimes.get(quark), -1, quark,
ongoingStateInfo.get(quark));
/**
* More advanced version of {@link #changeOngoingStateValue}. Replaces the
- * complete {@link #ongoingStateInfo} in one go, and updates the
- * {@link #ongoingStateStartTimes} and {@link #stateValuesTypes}
- * accordingly. BE VERY CAREFUL WITH THIS!
+ * complete ongoingStateInfo in one go, and updates the
+ * ongoingStateStartTimes and #stateValuesTypes accordingly. BE VERY CAREFUL
+ * WITH THIS!
*
* @param newStateIntervals
* The List of intervals that will represent the new
* "ongoing state". Their end times don't matter, we will only
* check their value and start times.
*/
- synchronized void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
+ public synchronized void replaceOngoingState(List<ITmfStateInterval> newStateIntervals) {
int size = newStateIntervals.size();
ongoingStateInfo = new ArrayList<>(size);
ongoingStateStartTimes = new ArrayList<>(size);
* Ongoing... tables can stay in sync with the number of attributes in the
* attribute tree, namely when we add sub-path attributes.
*/
- synchronized void addEmptyEntry() {
+ public synchronized void addEmptyEntry() {
/*
* Since this is a new attribute, we suppose it was in the "null state"
* since the beginning (so we can have intervals covering for all
* @return True if the value is present in the Transient State at this
* moment in time, false if it's not
*/
- boolean hasInfoAboutStateOf(long time, int quark) {
+ public boolean hasInfoAboutStateOf(long time, int quark) {
return (this.isActive() && time >= ongoingStateStartTimes.get(quark));
}
/**
- * This is the lower-level method that will be called by the
- * StateHistorySystem (with already-built StateValues and timestamps)
+ * Process a state change to be inserted in the history.
*
- * @param index
- * The index in the vectors (== the quark of the attribute)
- * @param value
- * The new StateValue associated to this attribute
* @param eventTime
* The timestamp associated with this state change
+ * @param value
+ * The new StateValue associated to this attribute
+ * @param quark
+ * The quark of the attribute that is being modified
* @throws TimeRangeException
+ * If 'eventTime' is invalid
* @throws AttributeNotFoundException
+ * IF 'quark' does not represent an existing attribute
* @throws StateValueTypeException
+ * If the state value to be inserted is of a different type of
+ * what was inserted so far for this attribute.
*/
- synchronized void processStateChange(long eventTime,
- ITmfStateValue value, int index) throws TimeRangeException,
+ public synchronized void processStateChange(long eventTime,
+ ITmfStateValue value, int quark) throws TimeRangeException,
AttributeNotFoundException, StateValueTypeException {
assert (this.isActive);
- Type expectedSvType = stateValueTypes.get(index);
- checkValidAttribute(index);
+ Type expectedSvType = stateValueTypes.get(quark);
+ checkValidAttribute(quark);
/*
* Make sure the state value type we're inserting is the same as the
* The value hasn't been used yet, set it to the value
* we're currently inserting (which might be null/-1 again).
*/
- stateValueTypes.set(index, value.getType());
+ stateValueTypes.set(quark, value.getType());
} else if ((value.getType() != Type.NULL) && (value.getType() != expectedSvType)) {
/*
* We authorize inserting null values in any type of attribute,
latestTime = eventTime;
}
- if (ongoingStateInfo.get(index).equals(value)) {
+ if (ongoingStateInfo.get(quark).equals(value)) {
/*
* This is the case where the new value and the one already present
* in the Builder are the same. We do not need to create an
return;
}
- if (backend != null && ongoingStateStartTimes.get(index) < eventTime) {
+ if (backend != null && ongoingStateStartTimes.get(quark) < eventTime) {
/*
* These two conditions are necessary to create an interval and
* update ongoingStateInfo.
*/
- backend.insertPastState(ongoingStateStartTimes.get(index),
+ backend.insertPastState(ongoingStateStartTimes.get(quark),
eventTime - 1, /* End Time */
- index, /* attribute quark */
- ongoingStateInfo.get(index)); /* StateValue */
+ quark, /* attribute quark */
+ ongoingStateInfo.get(quark)); /* StateValue */
- ongoingStateStartTimes.set(index, eventTime);
+ ongoingStateStartTimes.set(quark, eventTime);
}
- ongoingStateInfo.set(index, value);
+ ongoingStateInfo.set(quark, value);
return;
}
* @param t
* The requested timestamp
*/
- void doQuery(List<ITmfStateInterval> stateInfo, long t) {
+ public void doQuery(List<ITmfStateInterval> stateInfo, long t) {
ITmfStateInterval interval;
if (!this.isActive) {
}
/**
- * Close off the Transient State, used for example when we are done reading a
- * static trace file. All the information currently contained in it will be
- * converted to intervals and "flushed" to the State History.
+ * Close off the Transient State, used for example when we are done reading
+ * a static trace file. All the information currently contained in it will
+ * be converted to intervals and "flushed" to the state history.
+ *
+ * @param endTime
+ * The timestamp to use as end time for the state history (since
+ * it may be different than the timestamp of the last state
+ * change)
*/
- void closeTransientState(long endTime) {
+ public void closeTransientState(long endTime) {
assert (this.isActive);
for (int i = 0; i < ongoingStateInfo.size(); i++) {
/**
* Simply returns if this Transient State is currently being used or not
*
- * @return
+ * @return True if this transient state is active
*/
- boolean isActive() {
+ public boolean isActive() {
return this.isActive;
}
- void setInactive() {
+ /**
+ * Mark this transient state as inactive
+ */
+ public void setInactive() {
isActive = false;
}
/**
- * Debugging method that prints the contents of both 'ongoing...' vectors
+ * Debugging method that prints the contents of the transient state
*
* @param writer
+ * The writer to which the output should be written
*/
- void debugPrint(PrintWriter writer) {
+ public void debugPrint(PrintWriter writer) {
/* Only used for debugging, shouldn't be externalized */
writer.println("------------------------------"); //$NON-NLS-1$
writer.println("Info stored in the Builder:"); //$NON-NLS-1$