/* * 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 * or http://www.opensolaris.org/os/licensing. * 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 2007 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * ident "%Z%%M% %I% %E% SMI" */ package org.opensolaris.os.dtrace; import java.util.*; import java.beans.*; import java.io.*; /** * A snapshot of a DTrace aggregation. The name of an {@code * Aggregation} instance matches the source declaration, for example *
{@code @a[execname] = count();}* results in an {@code Aggregation} named "a" (the name does not * include the preceding {@code @}). For convenience, a single * aggregation can remain unnamed (multiple aggregations in the same D * program need distinct names). The unnamed aggregation results in an * {@code Aggregation} instance whose name is the empty string, for * example *
{@code @[execname] = count();}* An aggregation can list more than one variable in square brackets in * order to accumulate a value for each unique combination, or {@link * Tuple}. Each tuple instance is associated with its accumulated * {@link AggregationValue} in an {@link AggregationRecord}. For * example *
{@code @counts[execname, probefunc, cpu] = count();}* results in an {@code Aggregation} named "counts" containing records * each pairing a {@link CountValue} to a three-element {@code Tuple}. * It is also possible to omit the square brackets, for example *
{@code @a = count();}* results in an {@code Aggregation} named "a" with only a single record * keyed to the empty tuple ({@link Tuple#EMPTY}). *
* For more information, see the * Aggregations chapter of the Solaris Dynamic Tracing * Guide. Also, the * Built-in Variables section of the Variables chapter * describes variables like {@code execname}, {@code probefunc}, and * {@code cpu} useful for aggregating. *
* Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
*
* @see Aggregate
* @see PrintaRecord
*
* @author Tom Erickson
*/
public final class Aggregation implements Serializable {
static final long serialVersionUID = 2340811719178724026L;
static {
try {
BeanInfo info = Introspector.getBeanInfo(Aggregation.class);
PersistenceDelegate persistenceDelegate =
new DefaultPersistenceDelegate(
new String[] {"name", "ID", "records"})
{
@Override
protected boolean
mutatesTo(Object oldInstance, Object newInstance)
{
return ((newInstance != null) && (oldInstance != null) &&
(oldInstance.getClass() == newInstance.getClass()));
}
};
BeanDescriptor d = info.getBeanDescriptor();
d.setValue("persistenceDelegate", persistenceDelegate);
} catch (IntrospectionException e) {
e.printStackTrace();
}
}
/** @serial */
private String name;
/** @serial */
private final long id;
private transient Map {@code @[execname] = count();}
*/
public String
getName()
{
return name;
}
/**
* Gets the D compiler-generated ID of this aggregation.
*
* @return the D compiler-generated ID
*/
public long
getID()
{
return id;
}
/**
* Gets an unordered list of this aggregation's records. The list
* is easily sortable using {@link java.util.Collections#sort(List
* list, Comparator c)} provided any user-defined ordering.
* Modifying the returned list has no effect on this aggregation.
* Supports XML persistence.
*
* @return a newly created list that copies this aggregation's
* records by reference in no particular order
*/
public List {@code @a = count();}
* @return the record associated with the given key, or {@code null}
* if no record in this aggregation is associated with the given key
*/
public AggregationRecord
getRecord(Tuple key)
{
if (key == null) {
key = Tuple.EMPTY;
}
return map.get(key);
}
/**
* Serialize this {@code Aggregation} instance.
*
* @serialData Serialized fields are emitted, followed by a {@link
* java.util.List} of {@link AggregationRecord} instances.
*/
private void
writeObject(ObjectOutputStream s) throws IOException
{
s.defaultWriteObject();
s.writeObject(getRecords());
}
@SuppressWarnings("unchecked")
private void
readObject(ObjectInputStream s)
throws IOException, ClassNotFoundException
{
s.defaultReadObject();
// cannot cast to parametric type without compiler warning
List
*/
@Override
public String
toString()
{
StringBuilder buf = new StringBuilder();
buf.append(Aggregation.class.getName());
buf.append("[name = ");
buf.append(name);
buf.append(", id = ");
buf.append(id);
buf.append(", records = ");
List
* class-name[property1 = value1, property2 = value2]
*