PrintaRecord.java revision fb3fb4f3d76d55b64440afd0af72775dfad3bd1d
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
/*
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*
* ident "%Z%%M% %I% %E% SMI"
*/
/**
* A record generated by the DTrace {@code printa()} action. Lists the
* aggregations passed to {@code printa()} and records the formatted
* output associated with each {@link Tuple}. If multiple aggregations
* were passed to the {@code printa()} action that generated this
* record, then the DTrace library tabulates the output, using a default
* format if no format string was specified. By default, the output
* string associated with a given {@code Tuple} includes a value from
* each aggregation, or zero wherever an aggregation has no value
* associated with that {@code Tuple}. For example, the D statements
* <pre><code>
* @a[123] = sum(1);
* @b[456] = sum(2);
* printa(@a, @b, @c);
* </code></pre>
* produce output for the tuples "123" and "456" similar to the
* following:
* <pre><code>
* 123 1 0 0
* 456 0 2 0
* </code></pre>
* The first column after the tuple contains values from {@code @a},
* the next column contains values from {@code @b}, and the last
* column contains zeros because {@code @c} has neither a value
* associated with "123" nor a value associated with "456".
* <p>
* If a format string is passed to {@code printa()}, it may limit the
* aggregation data available in this record. For example, if the
* format string specifies a value placeholder for only one of two
* aggregations passed to {@code printa()}, then the resulting {@code
* PrintaRecord} will contain only one {@code Aggregation}. If no value
* placeholder is specified, or if the aggregation tuple is not
* completely specified, the resulting {@code PrintaRecord} will contain
* no aggregation data. However, the formatted output generated by the
* DTrace library is available in all cases. For details about
* {@code printa()} format strings, see the <a
* <b>{@code printa()}</b></a> section of the <b>Output
* Formatting</b> chapter of the <i>Solaris Dynamic Tracing Guide</i>.
* <p>
* Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
*
* @author Tom Erickson
*/
static final long serialVersionUID = -4174277639915895694L;
static {
try {
"formattedStrings", "tuples", "output"});
} catch (IntrospectionException e) {
}
}
/** @serial */
private final long snaptime;
/** @serial */
/** @serial */
/** @serial */
private transient StringBuffer outputBuffer;
private transient boolean formatted;
/**
* Package level access, called by ProbeData.
*/
{
outputBuffer = new StringBuffer();
validate();
}
/**
* Creates a record with the given snaptime, aggregations, and
* formatted output.
*
* @param snaptimeNanos nanosecond timestamp of the snapshot used
* to create this {@code printa()} record
* @param aggs aggregations passed to the {@code printa()} action
* that generated this record
* @param formattedOutput the formatted output, if any, associated
* with each {@code Tuple} occurring in the aggregations belonging
* to this record, one formatted string per {@code Tuple}, or an
* empty or {@code null} map if an incomplete {@code printa()}
* format string caused aggregation tuples to be omitted from this
* record
* @param orderedTuples list of aggregation tuples in the same order
* generated by the native DTrace library (determined by the various
* "aggsort" options such as {@link Option#aggsortkey})
* @param formattedOutputString {@code printa()} formatted string
* output in the same order generated by the native DTrace library
* (determined by the various "aggsort" options such as
* {@link Option#aggsortkey})
* @throws NullPointerException if the given collection of
* aggregations is {@code null}, or if the given ordered lists of
* tuples or formatted strings are {@code null}
* @throws IllegalArgumentException if the given snaptime is
* negative
*/
public
{
}
if (formattedOutput != null) {
}
if (orderedTuples != null) {
}
validate();
}
private void
validate()
{
if (snaptime < 0) {
throw new IllegalArgumentException("snaptime is negative");
}
if (aggregations == null) {
throw new NullPointerException("aggregations list is null");
}
Aggregation a;
a = aggregations.get(i);
if (a == null) {
throw new NullPointerException(
"null aggregation at index " + i);
}
}
throw new NullPointerException("ordered tuple list is null");
}
throw new NullPointerException("formatted output is null");
}
}
/**
* Gets the nanosecond timestamp of the aggregate snapshot used to
* create this {@code printa()} record.
*
* @return nanosecond timestamp
*/
public long
{
return snaptime;
}
private Aggregation
{
return null;
}
for (Aggregation a : aggregations) {
return a;
}
}
return null;
}
/**
* Gets the named aggregation.
*
* @return the named aggregation passed to {@code printa()}, or
* {@code null} if the named aggregation is not passed to {@code
* printa()}, or if it is omitted due to an incomplete {@code
* printa()} format string, or if it is empty (a future release of
* this API may represent an empty DTrace aggregation as a non-null
* {@code Aggregation} with no records; users of this API should not
* rely on a non-null return value to indicate a non-zero record
* count)
*/
public Aggregation
{
return getAggregationImpl(name);
}
/**
* Gets a list of the aggregations passed to the {@code printa()}
* action that generated this record. The returned list is a copy,
* and modifying it has no effect on this record. Supports XML
* persistence.
*
* @return non-null, possibly empty list of aggregations belonging
* to this record (empty aggregations are excluded)
*/
public List <Aggregation>
{
}
/**
* Gets the formatted string, if any, associated with the given
* aggregation tuple.
*
* @param key aggregation tuple
* @return the formatted string associated with the given
* aggregation tuple, or {@code null} if the given tuple does not
* exist in the aggregations belonging to this record or if it
* is omitted from this record due to an incomplete {@code printa()}
* format string
* @see #getFormattedStrings()
* @see #getOutput()
*/
public String
{
if (formattedStrings == null) {
return null;
}
}
/**
* Gets the formatted output, if any, associated with each {@code
* Tuple} occurring in the aggregations belonging to this record,
* one formatted string per {@code Tuple}. Gets an empty map if
* aggregation tuples are omitted from this record due to an
* incomplete {@code printa()} format string. The returned map is a
* copy and modifying it has no effect on this record. Supports XML
* persistence.
*
* @return a map of aggregation tuples and their associated
* formatted output strings, empty if aggregation tuples are omitted
* from this record due to an incomplete {@code printa(}) format
* string
* @see #getFormattedString(Tuple key)
* @see #getOutput()
*/
{
if (formattedStrings == null) {
}
}
/**
* Gets an ordered list of this record's aggregation tuples. The
* returned list is a copy, and modifying it has no effect on this
* record. Supports XML persistence.
*
* @return a non-null list of this record's aggregation tuples in
* the order they were generated by the native DTrace library, as
* determined by the {@link Option#aggsortkey}, {@link
* Option#aggsortrev}, {@link Option#aggsortpos}, and {@link
* Option#aggsortkeypos} options
*/
{
}
/**
* Gets this record's formatted output. Supports XML persistence.
*
* @return non-null formatted output in the order generated by the
* native DTrace library, as determined by the {@link
* Option#aggsortkey}, {@link Option#aggsortrev}, {@link
* Option#aggsortpos}, and {@link Option#aggsortkeypos} options
*/
public String
{
outputBuffer = null;
output = "\n";
}
}
return output;
}
/**
* Package level access, called by ProbeData.
*
* @throws NullPointerException if aggregationName is null
* @throws IllegalStateException if this PrintaRecord has an
* aggregation matching the given name and it already has an
* AggregationRecord with the same tuple key as the given record.
*/
void
{
if (formattedStrings == null) {
// printa() format string does not completely specify tuple
return;
}
if (aggregation == null) {
}
try {
} catch (IllegalArgumentException e) {
//
// The printa() format string may specify the value of the
// aggregating action multiple times. While that changes
// the resulting formatted string associated with the tuple,
// we ignore the attempt to add the redundant record to the
// aggregation.
//
throw e;
}
}
}
//
// Called from native code when the tuple is not completely
// specified in the printa() format string.
//
void
{
}
void
{
throw new IllegalArgumentException("A formatted string " +
} else {
}
}
}
/**
* Serialize this {@code PrintaRecord} instance.
*
* @serialData Serialized fields are emitted, followed by the
* formatted output string.
*/
private void
{
s.defaultWriteObject();
} else {
s.writeObject(output);
}
}
private void
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
// make defensive copy
if (aggregations != null) {
(aggregations.size());
aggregations = copy;
}
if (formattedStrings != null) {
}
}
// check constructor invariants only after defensize copy
try {
validate();
} catch (Exception e) {
throw new InvalidObjectException(e.getMessage());
}
}
/**
* Gets a string representation of this instance useful for logging
* and not intended for display. The exact details of the
* representation are unspecified and subject to change, but the
* following format may be regarded as typical:
* <pre><code>
* class-name[property1 = value1, property2 = value2]
* </code></pre>
*/
public String
toString()
{
}
}