fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER START
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * The contents of this file are subject to the terms of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Common Development and Distribution License (the "License").
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You may not use this file except in compliance with the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * or http://www.opensolaris.org/os/licensing.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * See the License for the specific language governing permissions
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * and limitations under the License.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * When distributing Covered Code, include this CDDL HEADER in each
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * If applicable, add the following below this CDDL HEADER, with the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * fields enclosed by brackets "[]" replaced with your own identifying
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * information: Portions Copyright [yyyy] [name of copyright owner]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * CDDL HEADER END
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/*
e77b06d21580f630e0a7c437495ab283d3672828tomee * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Use is subject to license terms.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * ident "%Z%%M% %I% %E% SMI"
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeepackage org.opensolaris.os.dtrace;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.util.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.beans.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeeimport java.io.*;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee/**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * A snapshot of a DTrace aggregation. The name of an {@code
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Aggregation} instance matches the source declaration, for example
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @a[execname] = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * results in an {@code Aggregation} named "a" (the name does not
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * include the preceding {@code @}). For convenience, a single
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * aggregation can remain unnamed (multiple aggregations in the same D
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * program need distinct names). The unnamed aggregation results in an
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@code Aggregation} instance whose name is the empty string, for
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * example
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @[execname] = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * An aggregation can list more than one variable in square brackets in
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * order to accumulate a value for each unique combination, or {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Tuple}. Each tuple instance is associated with its accumulated
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@link AggregationValue} in an {@link AggregationRecord}. For
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * example
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @counts[execname, probefunc, cpu] = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * results in an {@code Aggregation} named "counts" containing records
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * each pairing a {@link CountValue} to a three-element {@code Tuple}.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * It is also possible to omit the square brackets, for example
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @a = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * results in an {@code Aggregation} named "a" with only a single record
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * keyed to the empty tuple ({@link Tuple#EMPTY}).
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <p>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * For more information, see the <a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * href=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlh7?a=view>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <b>Aggregations</b></a> chapter of the <i>Solaris Dynamic Tracing
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Guide</i>. Also, the <a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * href=http://docs.sun.com/app/docs/doc/817-6223/6mlkidlfv?a=view>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <b>Built-in Variables</b></a> section of the <b>Variables</b> chapter
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * describes variables like {@code execname}, {@code probefunc}, and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@code cpu} useful for aggregating.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <p>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Immutable. Supports persistence using {@link java.beans.XMLEncoder}.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see Aggregate
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see PrintaRecord
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @author Tom Erickson
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomeepublic final class Aggregation implements Serializable {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static final long serialVersionUID = 2340811719178724026L;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee static {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee try {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanInfo info = Introspector.getBeanInfo(Aggregation.class);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee PersistenceDelegate persistenceDelegate =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new DefaultPersistenceDelegate(
8162146132b0fb9b7c6dc3371ff205edc236ebfatomee new String[] {"name", "ID", "records"})
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee protected boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee mutatesTo(Object oldInstance, Object newInstance)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return ((newInstance != null) && (oldInstance != null) &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (oldInstance.getClass() == newInstance.getClass()));
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee };
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee BeanDescriptor d = info.getBeanDescriptor();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee d.setValue("persistenceDelegate", persistenceDelegate);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } catch (IntrospectionException e) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee e.printStackTrace();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private String name;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /** @serial */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private final long id;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private transient Map <Tuple, AggregationRecord> map;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Package-level access, called by Aggregate
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Aggregation(String aggregationName, long aggregationID)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee name = Aggregate.filterUnnamedAggregationName(aggregationName);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee id = aggregationID;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee map = new HashMap <Tuple, AggregationRecord> ();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Creates an aggregation with the given name, ID, and records.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Supports XML persistence.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param aggregationName the name of this aggregation, empty string
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * if this aggregation is unnamed
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param aggregationID ID generated from a sequence by the native
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTrace library
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param aggregationRecords unordered collection of records
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * belonging to this aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws NullPointerException if the specified name or list of
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * records is {@code null}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if any record has an empty
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * tuple, unless it is the only record in the given collection (only
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * a singleton generated by an aggregation without square brackets
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * uses {@link Tuple#EMPTY} as a key)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @see #getRecord(Tuple key)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Aggregation(String aggregationName, long aggregationID,
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Collection <AggregationRecord> aggregationRecords)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee name = Aggregate.filterUnnamedAggregationName(aggregationName);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee id = aggregationID;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee mapRecords(aggregationRecords);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee validate();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // assumes map is not yet created
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee mapRecords(Collection <AggregationRecord> records)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int capacity = (int)(((float)records.size() * 3.0f) / 2.0f);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // avoid rehashing and optimize lookup; will never be modified
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee map = new HashMap <Tuple, AggregationRecord> (capacity, 1.0f);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (AggregationRecord record : records) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee map.put(record.getTuple(), record);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee private final void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee validate()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (name == null) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new NullPointerException("name is null");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (AggregationRecord r : map.values()) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if ((r.getTuple().size() == 0) && (map.size() > 1)) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("empty tuple " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "allowed only in singleton aggregation");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the name of this aggregation.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return the name of this aggregation exactly as it appears in the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * D program minus the preceding {@code @}, or an empty string if
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the aggregation is unnamed, for example:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @[execname] = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getName()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return name;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the D compiler-generated ID of this aggregation.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return the D compiler-generated ID
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public long
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getID()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return id;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
e77b06d21580f630e0a7c437495ab283d3672828tomee * Gets an unordered list of this aggregation's records. The list is
e77b06d21580f630e0a7c437495ab283d3672828tomee * sortable using {@link java.util.Collections#sort(List list,
e77b06d21580f630e0a7c437495ab283d3672828tomee * Comparator c)} with any user-defined ordering. Modifying the
e77b06d21580f630e0a7c437495ab283d3672828tomee * returned list has no effect on this aggregation. Supports XML
e77b06d21580f630e0a7c437495ab283d3672828tomee * persistence.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return a newly created list that copies this aggregation's
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * records by reference in no particular order
e77b06d21580f630e0a7c437495ab283d3672828tomee * @see Aggregate#getRecords()
e77b06d21580f630e0a7c437495ab283d3672828tomee * @see Aggregate#getOrderedRecords()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public List <AggregationRecord>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getRecords()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <AggregationRecord> list =
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee new ArrayList <AggregationRecord> (map.values());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return list;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Package level access, called by Aggregate and PrintaRecord.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @throws IllegalArgumentException if this aggregation already
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * contains a record with the same tuple key as the given record
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee addRecord(AggregationRecord record)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Tuple key = record.getTuple();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (map.put(key, record) != null) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throw new IllegalArgumentException("already contains a record " +
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee "with tuple " + key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a read-only {@code Map} view of this aggregation.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return a read-only {@code Map} view of this aggregation
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public Map <Tuple, AggregationRecord>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee asMap()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
e77b06d21580f630e0a7c437495ab283d3672828tomee return Collections. <Tuple, AggregationRecord> unmodifiableMap(map);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Compares the specified object with this aggregation for equality.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Defines equality as having equal names and equal records.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return {@code true} if and only if the specified object is an
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@code Aggregation} with the same name as this aggregation and
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * the {@code Map} views of both aggregations returned by {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * #asMap()} are equal as defined by {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * AbstractMap#equals(Object o) AbstractMap.equals()}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public boolean
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee equals(Object o)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (o instanceof Aggregation) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Aggregation a = (Aggregation)o;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return (name.equals(a.name) &&
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee (map.equals(a.map))); // same mappings
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return false;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Overridden to ensure that equal aggregations have equal hash
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * codes.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hashCode()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee int hash = 17;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hash = (37 * hash) + name.hashCode();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee hash = (37 * hash) + map.hashCode();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return hash;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets the record associated with the given key, or the singleton
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * record of an aggregation declared without square brackets if
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * {@code key} is {@code null} or empty.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @param key The record key, or an empty tuple (see {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Tuple#EMPTY}) to obtain the value from a <i>singleton</i> (a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * non-keyed instance with only a single value) generated from a
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * DTrace aggregation declarated without square brackets, for
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * example:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre> {@code @a = count();}</pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @return the record associated with the given key, or {@code null}
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * if no record in this aggregation is associated with the given key
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public AggregationRecord
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee getRecord(Tuple key)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (key == null) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee key = Tuple.EMPTY;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return map.get(key);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Serialize this {@code Aggregation} instance.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee *
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * @serialData Serialized fields are emitted, followed by a {@link
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * java.util.List} of {@link AggregationRecord} instances.
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee writeObject(ObjectOutputStream s) throws IOException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.defaultWriteObject();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.writeObject(getRecords());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @SuppressWarnings("unchecked")
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee private void
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee readObject(ObjectInputStream s)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee throws IOException, ClassNotFoundException
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee s.defaultReadObject();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // cannot cast to parametric type without compiler warning
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <AggregationRecord> records = (List)s.readObject();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // load serialized form into private map as a defensive copy
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee mapRecords(records);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Check class invariants (only after defensive copy)
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee name = Aggregate.filterUnnamedAggregationName(name);
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee try {
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee validate();
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee } catch (Exception e) {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee InvalidObjectException x = new InvalidObjectException(
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee e.getMessage());
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee x.initCause(e);
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee throw x;
91cfa10a8e55050a5103c4b2e83b0bf8d783a7cbtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee /**
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * Gets a string representation of this aggregation useful for
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * logging and not intended for display. The exact details of the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * representation are unspecified and subject to change, but the
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * following format may be regarded as typical:
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * <pre><code>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * class-name[property1 = value1, property2 = value2]
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee * </code></pre>
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee */
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee @Override
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public String
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee toString()
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee {
4ae67516a1d5dc4a5dbc761762bad5b596647388tomee StringBuilder buf = new StringBuilder();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(Aggregation.class.getName());
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append("[name = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(name);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", id = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(id);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", records = ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee List <AggregationRecord> recordList = getRecords();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee // Sort by tuple so that equal aggregations have equal strings
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Collections.sort(recordList, new Comparator <AggregationRecord> () {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee public int compare(AggregationRecord r1, AggregationRecord r2) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Tuple t1 = r1.getTuple();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee Tuple t2 = r2.getTuple();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return t1.compareTo(t2);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee });
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append('[');
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee boolean first = true;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee for (AggregationRecord record : recordList) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee if (first) {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee first = false;
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee } else {
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(", ");
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(record);
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee buf.append(']');
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee return buf.toString();
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee }
fb3fb4f3d76d55b64440afd0af72775dfad3bd1dtomee}