/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2012, 2016 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
*
package org.eclipse.tracecompass.lttng2.kernel.core.tests.analysis.kernel.statesystem;
+import static org.eclipse.tracecompass.statesystem.core.ITmfStateSystem.INVALID_ATTRIBUTE;
+import static org.eclipse.tracecompass.statesystem.core.ITmfStateSystem.ROOT_ATTRIBUTE;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail;
}
}
+ @Test
+ public void testOptQuarkAbsolute() {
+ int quark = fixture.optQuarkAbsolute();
+ assertEquals(ROOT_ATTRIBUTE, quark);
+
+ quark = fixture.optQuarkAbsolute(Attributes.THREADS, "1432", Attributes.EXEC_NAME);
+ assertNotEquals(INVALID_ATTRIBUTE, quark);
+ assertEquals(Attributes.EXEC_NAME, fixture.getAttributeName(quark));
+
+ quark = fixture.optQuarkAbsolute(Attributes.THREADS, "1432", "absent");
+ assertEquals(INVALID_ATTRIBUTE, quark);
+
+ quark = fixture.optQuarkAbsolute(Attributes.THREADS, "absent", Attributes.EXEC_NAME);
+ assertEquals(INVALID_ATTRIBUTE, quark);
+
+ quark = fixture.optQuarkAbsolute("absent", "1432", Attributes.EXEC_NAME);
+ assertEquals(INVALID_ATTRIBUTE, quark);
+ }
+
+ @Test
+ public void testOptQuarkRelative() {
+ int threadsQuark = INVALID_ATTRIBUTE;
+ try {
+ threadsQuark = fixture.getQuarkAbsolute(Attributes.THREADS);
+ } catch (AttributeNotFoundException e) {
+ fail();
+ }
+ assertNotEquals(INVALID_ATTRIBUTE, threadsQuark);
+
+ int quark = fixture.optQuarkRelative(threadsQuark);
+ assertEquals(threadsQuark, quark);
+
+ quark = fixture.optQuarkRelative(threadsQuark, "1432", Attributes.EXEC_NAME);
+ assertNotEquals(INVALID_ATTRIBUTE, quark);
+ assertEquals(Attributes.EXEC_NAME, fixture.getAttributeName(quark));
+
+ quark = fixture.optQuarkRelative(threadsQuark, "1432", "absent");
+ assertEquals(INVALID_ATTRIBUTE, quark);
+
+ quark = fixture.optQuarkRelative(threadsQuark, "absent", Attributes.EXEC_NAME);
+ assertEquals(INVALID_ATTRIBUTE, quark);
+ }
+
@Test
public void testFullAttributeName() {
try {
assertEquals(5, list.size());
}
+ @Test
+ public void testGetQuarksNoMatch() {
+ List<Integer> list = fixture.getQuarks("invalid");
+ assertEquals(0, list.size());
+
+ list = fixture.getQuarks("*", "invalid");
+ assertEquals(0, list.size());
+
+ list = fixture.getQuarks("invalid", "*");
+ assertEquals(0, list.size());
+
+ list = fixture.getQuarks(Attributes.THREADS, "*", "invalid");
+ assertEquals(0, list.size());
+ }
+
// ------------------------------------------------------------------------
// Tests verifying the *complete* results of a full queries
// ------------------------------------------------------------------------
assertEquals(path[i], name);
q = fixture.getParentAttributeQuark(q);
}
- assertEquals(-1, q);
+ assertEquals(ROOT_ATTRIBUTE, q);
q = fixture.getParentAttributeQuark(q);
- assertEquals(-1, q);
+ assertEquals(ROOT_ATTRIBUTE, q);
} catch (AttributeNotFoundException e) {
fail();
}
/*******************************************************************************
- * Copyright (c) 2015 Ericsson
+ * Copyright (c) 2015, 2016 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
import static org.junit.Assert.assertArrayEquals;
import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
import java.io.File;
import java.io.FileInputStream;
import org.eclipse.tracecompass.internal.statesystem.core.AttributeTree;
import org.eclipse.tracecompass.internal.statesystem.core.StateSystem;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.backend.IStateHistoryBackend;
import org.eclipse.tracecompass.statesystem.core.backend.StateHistoryBackendFactory;
-import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
import org.junit.Test;
/**
*
* @throws IOException
* if there is an error accessing the test file
- * @throws AttributeNotFoundException
- * if the test fails
*/
@Test
- public void testAttributeTreeFileStorage() throws IOException, AttributeNotFoundException {
+ public void testAttributeTreeFileStorage() throws IOException {
File file = File.createTempFile("AttributeTreeTest", ".ht");
IStateHistoryBackend backend1 = StateHistoryBackendFactory.createNullBackend("test");
StateSystem ss1 = new StateSystem(backend1);
AttributeTree attributeTree2 = new AttributeTree(ss2, fis);
for (String name : NAMES) {
String[] path = new String[] { THREADS, name, STATUS };
- int quark = attributeTree2.getQuarkDontAdd(-1, path);
+ int quark = attributeTree2.getQuarkDontAdd(ITmfStateSystem.ROOT_ATTRIBUTE, path);
+ assertNotEquals(ITmfStateSystem.INVALID_ATTRIBUTE, quark);
assertArrayEquals(path, attributeTree2.getFullAttributePathArray(quark));
assertEquals(name, attributeTree2.getAttributeName(attributeTree2.getParentAttributeQuark(quark)));
}
package org.eclipse.tracecompass.internal.statesystem.core;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.eclipse.tracecompass.statesystem.core.ITmfStateSystem.INVALID_ATTRIBUTE;
import java.io.PrintWriter;
import java.util.Collections;
import java.util.Map;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import com.google.common.collect.ImmutableList;
*
* @param path
* The path we are looking for, *relative to this node*.
- * @return The matching quark, or -1 if that attribute does not exist.
+ * @return The matching quark, or {@link ITmfStateSystem#INVALID_ATTRIBUTE}
+ * if that attribute does not exist.
*/
public int getSubAttributeQuark(String... path) {
return this.getSubAttributeQuark(path, 0);
private int getSubAttributeQuark(String[] path, int index) {
Attribute targetNode = this.getSubAttributeNode(path, index);
if (targetNode == null) {
- return -1;
+ return INVALID_ATTRIBUTE;
}
return targetNode.getQuark();
}
/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2012, 2016 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
*
package org.eclipse.tracecompass.internal.statesystem.core;
import static org.eclipse.tracecompass.common.core.NonNullUtils.checkNotNull;
+import static org.eclipse.tracecompass.statesystem.core.ITmfStateSystem.INVALID_ATTRIBUTE;
+import static org.eclipse.tracecompass.statesystem.core.ITmfStateSystem.ROOT_ATTRIBUTE;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.PrintWriter;
import java.nio.channels.FileChannel;
import java.util.ArrayList;
-import java.util.Arrays;
import java.util.List;
import org.eclipse.jdt.annotation.NonNull;
+import org.eclipse.tracecompass.statesystem.core.ITmfStateSystem;
import org.eclipse.tracecompass.statesystem.core.exceptions.AttributeNotFoundException;
/**
public AttributeTree(StateSystem ss) {
this.ss = ss;
this.attributeList = new ArrayList<>();
- this.attributeTreeRoot = new Attribute(null, "root", -1); //$NON-NLS-1$
+ this.attributeTreeRoot = new Attribute(null, "root", ROOT_ATTRIBUTE); //$NON-NLS-1$
}
/**
* the attributes. Simply create attributes the normal way from them.
*/
for (String[] attrib : attribList) {
- this.getQuarkAndAdd(-1, attrib);
+ this.getQuarkAndAdd(ROOT_ATTRIBUTE, attrib);
}
}
/**
* Get the quark for a given attribute path. No new attribute will be
- * created : if the specified path does not exist, throw an error.
+ * created : if the specified path does not exist, return
+ * {@link ITmfStateSystem#INVALID_ATTRIBUTE}.
*
* @param startingNodeQuark
* The quark of the attribute from which relative queries will
- * start. Use '-1' to start at the root node.
+ * start. Use {@link ITmfStateSystem#ROOT_ATTRIBUTE} 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
+ * @return The quark of the specified attribute, or
+ * {@link ITmfStateSystem#INVALID_ATTRIBUTE} if that attribute does
+ * not exist.
*/
- public synchronized int getQuarkDontAdd(int startingNodeQuark, String... subPath)
- throws AttributeNotFoundException {
- assert (startingNodeQuark >= -1);
+ public synchronized int getQuarkDontAdd(int startingNodeQuark, String... subPath) {
+ assert (startingNodeQuark >= ROOT_ATTRIBUTE);
Attribute prevNode;
}
/* Get the "starting node" */
- if (startingNodeQuark == -1) {
+ if (startingNodeQuark == ROOT_ATTRIBUTE) {
prevNode = attributeTreeRoot;
} else {
prevNode = attributeList.get(startingNodeQuark);
}
- int knownQuark = prevNode.getSubAttributeQuark(subPath);
- if (knownQuark == -1) {
- /*
- * The attribute doesn't exist, but we have been specified to NOT
- * add any new attributes.
- */
- throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + startingNodeQuark + ", SubPath:" + Arrays.toString(subPath)); //$NON-NLS-1$ //$NON-NLS-2$
- }
- /*
- * The attribute was already existing, return the quark of that
- * attribute
- */
- return knownQuark;
+ return prevNode.getSubAttributeQuark(subPath);
}
/**
*
* @param startingNodeQuark
* The quark of the attribute from which relative queries will
- * start. Use '-1' to start at the root node.
+ * start. Use {@link ITmfStateSystem#ROOT_ATTRIBUTE} 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
// FIXME synchronized here is probably quite costly... maybe only locking
// the "for" would be enough?
assert (subPath != null && subPath.length > 0);
- assert (startingNodeQuark >= -1);
+ assert (startingNodeQuark >= ROOT_ATTRIBUTE);
Attribute nextNode = null;
Attribute prevNode;
/* Get the "starting node" */
- if (startingNodeQuark == -1) {
+ if (startingNodeQuark == ROOT_ATTRIBUTE) {
prevNode = attributeTreeRoot;
} else {
prevNode = attributeList.get(startingNodeQuark);
}
int knownQuark = prevNode.getSubAttributeQuark(subPath);
- if (knownQuark == -1) {
+ if (knownQuark == INVALID_ATTRIBUTE) {
/*
* The attribute was not in the table previously, and we want to add
* it
* 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
+ * If 'attributeQuark' is invalid, or if there is no attribute
* associated to it.
*/
public synchronized @NonNull List<@NonNull Integer> getSubAttributes(int attributeQuark, boolean recursive)
Attribute startingAttribute;
/* Check if the quark is valid */
- if (attributeQuark < -1 || attributeQuark >= attributeList.size()) {
+ if (attributeQuark < ROOT_ATTRIBUTE || attributeQuark >= attributeList.size()) {
throw new AttributeNotFoundException(ss.getSSID() + " Quark:" + attributeQuark); //$NON-NLS-1$
}
/* Set up the node from which we'll start the search */
- if (attributeQuark == -1) {
+ if (attributeQuark == ROOT_ATTRIBUTE) {
startingAttribute = attributeTreeRoot;
} else {
startingAttribute = attributeList.get(attributeQuark);
/**
* Returns the parent quark of the attribute. The root attribute has no
- * parent and will return <code>-1</code>
+ * parent and will return {@link ITmfStateSystem#ROOT_ATTRIBUTE}.
*
* @param quark
* The quark of the attribute
- * @return Quark of the parent attribute or <code>-1</code> for the root
- * attribute
+ * @return Quark of the parent attribute or
+ * {@link ITmfStateSystem#ROOT_ATTRIBUTE} for the root attribute
*/
public synchronized int getParentAttributeQuark(int quark) {
- if (quark == -1) {
+ if (quark == ROOT_ATTRIBUTE) {
return quark;
}
return attributeList.get(quark).getParentAttributeQuark();
/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson
+ * Copyright (c) 2012, 2016 Ericsson
* Copyright (c) 2010, 2011 École Polytechnique de Montréal
* Copyright (c) 2010, 2011 Alexandre Montplaisir <alexandre.montplaisir@gmail.com>
*
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
+import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.CountDownLatch;
@Override
public int getQuarkAbsolute(String... attribute)
throws AttributeNotFoundException {
- return getAttributeTree().getQuarkDontAdd(-1, attribute);
+ int quark = getAttributeTree().getQuarkDontAdd(ROOT_ATTRIBUTE, attribute);
+ if (quark == INVALID_ATTRIBUTE) {
+ throw new AttributeNotFoundException(getSSID() + " Path:" + Arrays.toString(attribute)); //$NON-NLS-1$
+ }
+ return quark;
+ }
+
+ @Override
+ public int optQuarkAbsolute(String... attribute) {
+ return getAttributeTree().getQuarkDontAdd(ROOT_ATTRIBUTE, attribute);
}
@Override
public int getQuarkAbsoluteAndAdd(String... attribute) {
- return getAttributeTree().getQuarkAndAdd(-1, attribute);
+ return getAttributeTree().getQuarkAndAdd(ROOT_ATTRIBUTE, attribute);
}
@Override
public int getQuarkRelative(int startingNodeQuark, String... subPath)
throws AttributeNotFoundException {
+ int quark = getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
+ if (quark == INVALID_ATTRIBUTE) {
+ throw new AttributeNotFoundException(getSSID() + " Quark:" + startingNodeQuark + ", SubPath:" + Arrays.toString(subPath)); //$NON-NLS-1$ //$NON-NLS-2$
+ }
+ return quark;
+ }
+
+ @Override
+ public int optQuarkRelative(int startingNodeQuark, String... subPath) {
return getAttributeTree().getQuarkDontAdd(startingNodeQuark, subPath);
}
return quarks;
}
- try {
- if (prefix.size() == 0) {
- /*
- * If 'prefix' is empty, this means the wildcard was the first
- * element. Look for the root node's sub-attributes.
- */
- startingAttribute = -1;
- } else {
- startingAttribute = getQuarkAbsolute(prefixStr);
+ if (prefix.isEmpty()) {
+ /*
+ * If 'prefix' is empty, this means the wildcard was the first
+ * element. Look for the root node's sub-attributes.
+ */
+ startingAttribute = ROOT_ATTRIBUTE;
+ } else {
+ startingAttribute = optQuarkAbsolute(prefixStr);
+ if (startingAttribute == INVALID_ATTRIBUTE) {
+ /* That attribute path did not exist, return the empty array */
+ return quarks;
}
+ }
+ try {
directChildren = getSubAttributes(startingAttribute, false);
} catch (AttributeNotFoundException e) {
- /* That attribute path did not exist, return the empty array */
- return quarks;
+ /* Should not happen, starting attribute is a valid quark */
+ throw new IllegalStateException();
}
/*
* 'suffix' part of the initial pattern.
*/
for (int childQuark : directChildren) {
- int matchingQuark;
- try {
- matchingQuark = getQuarkRelative(childQuark, suffixStr);
- } catch (AttributeNotFoundException e) {
- continue;
+ int matchingQuark = optQuarkRelative(childQuark, suffixStr);
+ if (matchingQuark != INVALID_ATTRIBUTE) {
+ quarks.add(matchingQuark);
}
- quarks.add(matchingQuark);
}
return quarks;
/*******************************************************************************
- * Copyright (c) 2012, 2015 Ericsson and others.
+ * Copyright (c) 2012, 2016 Ericsson and others.
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
*/
public interface ITmfStateSystem {
+ /** Root attribute quark
+ * @since 2.0*/
+ int ROOT_ATTRIBUTE = -1;
+ /** Invalid attribute quark
+ * @since 2.0*/
+ int INVALID_ATTRIBUTE = -2;
+
/**
* Get the ID of this state system.
*
/**
* Basic quark-retrieving method. Pass an attribute in parameter as an array
* of strings, the matching quark will be returned.
- *
+ * <p>
* This version will NOT create any new attributes. If an invalid attribute
* is requested, an exception will be thrown.
+ * <p>
+ * If it is expected that the requested attribute might be absent, it is
+ * recommended to use {@link #optQuarkAbsolute(String...)} instead.
*
* @param attribute
* Attribute given as its full path in the Attribute Tree
int getQuarkAbsolute(String... attribute)
throws AttributeNotFoundException;
+ /**
+ * Quark-retrieving method for an optional attribute that may or may not be
+ * present. Pass an attribute in parameter as an array of strings, if it
+ * exists, the matching quark will be returned.
+ * <p>
+ * This version will NOT create any new attributes. If an attribute that
+ * does not exist is requested, {@link #INVALID_ATTRIBUTE} will be returned.
+ *
+ * @param attribute
+ * Attribute given as its full path in the Attribute Tree
+ * @return The quark of the requested attribute, or
+ * {@link #INVALID_ATTRIBUTE} if it does not exist.
+ * @since 2.0
+ */
+ int optQuarkAbsolute(String... attribute);
+
/**
* "Relative path" quark-getting method. Instead of specifying a full path,
* if you know the path is relative to another attribute for which you
* already have the quark, use this for better performance.
- *
+ * <p>
* This is useful for cases where a lot of modifications or queries will
* originate from the same branch of the attribute tree : the common part of
* the path won't have to be re-hashed for every access.
- *
+ * <p>
* This version will NOT create any new attributes. If an invalid attribute
* is requested, an exception will be thrown.
+ * <p>
+ * If it is expected that the requested sub-attribute might be absent, it is
+ * recommended to use {@link #optQuarkRelative(int, String...)} instead.
*
* @param startingNodeQuark
* The quark of the attribute from which 'subPath' originates.
int getQuarkRelative(int startingNodeQuark, String... subPath)
throws AttributeNotFoundException;
+ /**
+ * "Relative path" quark-getting method for an optional attribute that may
+ * or may not be present. Instead of specifying a full path, if you know the
+ * path is relative to another attribute for which you already have the
+ * quark, use this for better performance.
+ * <p>
+ * This is useful for cases where a lot of modifications or queries will
+ * originate from the same branch of the attribute tree : the common part of
+ * the path won't have to be re-hashed for every access.
+ * <p>
+ * This version will NOT create any new attributes. If a sub-attribute that
+ * does not exist is requested, {@link #INVALID_ATTRIBUTE} will be returned.
+ *
+ * @param startingNodeQuark
+ * The quark of the attribute from which 'subPath' originates.
+ * @param subPath
+ * "Rest" of the path to get to the final attribute
+ * @return The quark of the requested sub-attribute, or
+ * {@link #INVALID_ATTRIBUTE} if it does not exist.
+ * @throws IndexOutOfBoundsException
+ * If the starting node quark is out of range
+ * @since 2.0
+ */
+ int optQuarkRelative(int startingNodeQuark, String... subPath);
+
/**
* Return the sub-attributes of the target attribute, as a List of quarks.
*
* @param quark
* The attribute of which you want to sub-attributes. You can use
- * "-1" here to specify the root node.
+ * {@link #ROOT_ATTRIBUTE} here to specify the root node.
* @param recursive
* True if you want all recursive sub-attributes, false if you
* only want the first level.
*
* @param quark
* The attribute of which you want to sub-attributes. You can use
- * "-1" here to specify the root node.
+ * {@link #ROOT_ATTRIBUTE} here to specify the root node.
* @param recursive
* True if you want all recursive sub-attributes, false if you
* only want the first level. Note that the returned value will
*
* @param attributeQuark
* The quark of the attribute
- * @return Quark of the parent attribute or <code>-1</code> if root quark or
- * no parent.
+ * @return Quark of the parent attribute or {@link #ROOT_ATTRIBUTE} if root
+ * quark or no parent.
* @throws IndexOutOfBoundsException
* If the attribute quark is out of range
*/