// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.yolean.trace; import com.yahoo.yolean.concurrent.ThreadRobustList; import java.util.Collections; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.NoSuchElementException; /** *
This class represents a single node in a tree of TraceNodes
. The trace forms a tree where there is a
* branch for each parallel execution, and a node within such a branch for each traced event. As each TraceNode
* may contain a payload of any type, the trace tree can be used to exchange any thread-safe state between producers and
* consumers in different threads, whether or not the shape of the trace tree is relevant to the particular
* information.
This class uses a {@link ThreadRobustList} for its children. That list allows multiple threads to inspect the
* hierarchy of a TraceNode
tree while there are other threads concurrently modifying it, without incurring the
* cost of memory synchronization. The only caveat being that for each TraceNode
there can never be more than
* exactly one writer thread. If multiple threads need to mutate a single TraceNode
, then the writer threads
* need to synchronize their access on the TraceNode
.
Creates a new instance of this class.
* * @param payload the payload to assign to this, may benull
* @param timestamp the timestamp to assign to this
*/
public TraceNode(Object payload, long timestamp) {
this.payload = payload;
this.timestamp = timestamp;
}
/**
* Adds another TraceNode
as a child to this.
child
is not a root TraceNode
* @see #isRoot()
*/
public TraceNode add(TraceNode child) {
if (child.parent != null) {
throw new IllegalArgumentException("Can not add " + child + " to " + this + "; it is not a root.");
}
child.parent = this;
if (children == null) {
children = new ThreadRobustList<>();
}
children.add(child);
return this;
}
/**
* Returns a read-only iterable of all {@link #payload() payloads} that are instances of payloadType
,
* in all its decendants. The payload of this TraceNode
is ignored.
The payloads are retrieved in depth-first, prefix order.
* * @param payloadType the type of payloads to retrieve * @return the payloads, nevernull
*/
public Returns the payload of this TraceNode
, or null if none.
Returns the timestamp of this TraceNode
.
Returns the parent TraceNode
of this.
Returns the child TraceNodes
of this.
Returns whether or not this TraceNode
is a root node (i.e. it has no parent).
true
if {@link #parent()} returns null
*/
public boolean isRoot() {
return parent == null;
}
/**
* Returns the root TraceNode
of the tree that this TraceNode
belongs to.
Visits this TraceNode
and all of its descendants in depth-first, prefix order.
visitor
parameter.
*/
public