17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * CDDL HEADER START 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 57c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 67c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 77c478bd9Sstevel@tonic-gate * with the License. 87c478bd9Sstevel@tonic-gate * 97c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 107c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 117c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 127c478bd9Sstevel@tonic-gate * and limitations under the License. 137c478bd9Sstevel@tonic-gate * 147c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 157c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 167c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 177c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 187c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * CDDL HEADER END 217c478bd9Sstevel@tonic-gate */ 227c478bd9Sstevel@tonic-gate /* 237c478bd9Sstevel@tonic-gate * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 247c478bd9Sstevel@tonic-gate * Use is subject to license terms. 257c478bd9Sstevel@tonic-gate * 267c478bd9Sstevel@tonic-gate * ident "%Z%%M% %I% %E% SMI" 277c478bd9Sstevel@tonic-gate */ 287c478bd9Sstevel@tonic-gate 297c478bd9Sstevel@tonic-gate package com.sun.solaris.domain.pools; 307c478bd9Sstevel@tonic-gate 317c478bd9Sstevel@tonic-gate 327c478bd9Sstevel@tonic-gate import java.util.*; 337c478bd9Sstevel@tonic-gate import java.text.DecimalFormat; 347c478bd9Sstevel@tonic-gate 357c478bd9Sstevel@tonic-gate import com.sun.solaris.service.logging.*; 367c478bd9Sstevel@tonic-gate 377c478bd9Sstevel@tonic-gate /** 387c478bd9Sstevel@tonic-gate * Contains information about statistics. An instance must only 397c478bd9Sstevel@tonic-gate * contain Statistics of the same type. 407c478bd9Sstevel@tonic-gate */ 417c478bd9Sstevel@tonic-gate class StatisticList extends LinkedList 427c478bd9Sstevel@tonic-gate { 437c478bd9Sstevel@tonic-gate /** 447c478bd9Sstevel@tonic-gate * The name of the statistic. 457c478bd9Sstevel@tonic-gate */ 467c478bd9Sstevel@tonic-gate private final String name; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate /** 497c478bd9Sstevel@tonic-gate * The maximum number of samples to be stored. 507c478bd9Sstevel@tonic-gate */ 517c478bd9Sstevel@tonic-gate private final int maxSize; 527c478bd9Sstevel@tonic-gate 537c478bd9Sstevel@tonic-gate /** 547c478bd9Sstevel@tonic-gate * The list of StatisticListeners. 557c478bd9Sstevel@tonic-gate */ 567c478bd9Sstevel@tonic-gate private List listeners; 577c478bd9Sstevel@tonic-gate 587c478bd9Sstevel@tonic-gate /** 597c478bd9Sstevel@tonic-gate * Statistically assess utilization. 607c478bd9Sstevel@tonic-gate */ 617c478bd9Sstevel@tonic-gate private StatisticOperations statisticOperations; 627c478bd9Sstevel@tonic-gate 637c478bd9Sstevel@tonic-gate /** 647c478bd9Sstevel@tonic-gate * Constructor. 657c478bd9Sstevel@tonic-gate */ StatisticList()667c478bd9Sstevel@tonic-gate public StatisticList() 677c478bd9Sstevel@tonic-gate { 687c478bd9Sstevel@tonic-gate this("default", 10); 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate 717c478bd9Sstevel@tonic-gate /** 727c478bd9Sstevel@tonic-gate * Constructor. Statistics will not be held for this set. 737c478bd9Sstevel@tonic-gate * 747c478bd9Sstevel@tonic-gate * @param name is the name of the contained statistics 757c478bd9Sstevel@tonic-gate * @param size is the maximum number of statistics to hold 767c478bd9Sstevel@tonic-gate */ StatisticList(String name, int size)777c478bd9Sstevel@tonic-gate public StatisticList(String name, int size) 787c478bd9Sstevel@tonic-gate { 797c478bd9Sstevel@tonic-gate this(name, size, false); 807c478bd9Sstevel@tonic-gate } 817c478bd9Sstevel@tonic-gate 827c478bd9Sstevel@tonic-gate /** 837c478bd9Sstevel@tonic-gate * Constructor. 847c478bd9Sstevel@tonic-gate * 857c478bd9Sstevel@tonic-gate * @param name is the name of the contained statistics 867c478bd9Sstevel@tonic-gate * @param size is the maximum number of statistics to hold 877c478bd9Sstevel@tonic-gate * @param doStats indicates whether or not statistics should 887c478bd9Sstevel@tonic-gate * be calculated for the data. 897c478bd9Sstevel@tonic-gate */ StatisticList(String name, int size, boolean doStats)907c478bd9Sstevel@tonic-gate public StatisticList(String name, int size, boolean doStats) 917c478bd9Sstevel@tonic-gate throws IllegalArgumentException 927c478bd9Sstevel@tonic-gate { 937c478bd9Sstevel@tonic-gate super(); 947c478bd9Sstevel@tonic-gate this.name = name; 957c478bd9Sstevel@tonic-gate if (size < 1) 967c478bd9Sstevel@tonic-gate throw new IllegalArgumentException("Size must be > 0"); 977c478bd9Sstevel@tonic-gate this.maxSize = size; 987c478bd9Sstevel@tonic-gate listeners = new LinkedList(); 997c478bd9Sstevel@tonic-gate if (doStats) { 1007c478bd9Sstevel@tonic-gate statisticOperations = new StatisticOperations(this); 1017c478bd9Sstevel@tonic-gate addStatisticListener(statisticOperations); 1027c478bd9Sstevel@tonic-gate } 1037c478bd9Sstevel@tonic-gate } 104*55fea89dSDan Cross 1057c478bd9Sstevel@tonic-gate /** 1067c478bd9Sstevel@tonic-gate * Return the name of the Statistics being sampled. 1077c478bd9Sstevel@tonic-gate */ getName()1087c478bd9Sstevel@tonic-gate public String getName() 1097c478bd9Sstevel@tonic-gate { 1107c478bd9Sstevel@tonic-gate return (name); 111*55fea89dSDan Cross } 1127c478bd9Sstevel@tonic-gate 1137c478bd9Sstevel@tonic-gate /** 1147c478bd9Sstevel@tonic-gate * Return a "snapshot" which is the aggregation of all 1157c478bd9Sstevel@tonic-gate * statistic records. 1167c478bd9Sstevel@tonic-gate * 1177c478bd9Sstevel@tonic-gate * @throws NoSuchElementException if there is an error 1187c478bd9Sstevel@tonic-gate * accessing a list member. 1197c478bd9Sstevel@tonic-gate */ getSnapshot()1207c478bd9Sstevel@tonic-gate public AggregateStatistic getSnapshot() 1217c478bd9Sstevel@tonic-gate throws NoSuchElementException 1227c478bd9Sstevel@tonic-gate { 1237c478bd9Sstevel@tonic-gate return (getSnapshotForInterval(iterator(), null, null)); 1247c478bd9Sstevel@tonic-gate } 1257c478bd9Sstevel@tonic-gate 1267c478bd9Sstevel@tonic-gate /** 1277c478bd9Sstevel@tonic-gate * Return a "snapshot" of the data using the supplied 1287c478bd9Sstevel@tonic-gate * iterator. 1297c478bd9Sstevel@tonic-gate * 1307c478bd9Sstevel@tonic-gate * @param it An iterator over the contained elements to be 1317c478bd9Sstevel@tonic-gate * used as the basis for the snapshot. 1327c478bd9Sstevel@tonic-gate * @throws NoSuchElementException if there is an error 1337c478bd9Sstevel@tonic-gate * accessing a list member. 1347c478bd9Sstevel@tonic-gate */ getSnapshot(Iterator it)1357c478bd9Sstevel@tonic-gate private AggregateStatistic getSnapshot(Iterator it) 1367c478bd9Sstevel@tonic-gate throws NoSuchElementException 1377c478bd9Sstevel@tonic-gate { 1387c478bd9Sstevel@tonic-gate return (getSnapshotForInterval(it, null, null)); 1397c478bd9Sstevel@tonic-gate } 1407c478bd9Sstevel@tonic-gate 1417c478bd9Sstevel@tonic-gate /** 1427c478bd9Sstevel@tonic-gate * Returns the aggregated value for the StatisticList only 1437c478bd9Sstevel@tonic-gate * including samples which satisfy the start and end criteria. 1447c478bd9Sstevel@tonic-gate * 1457c478bd9Sstevel@tonic-gate * @param start start time or null if unspecified. 1467c478bd9Sstevel@tonic-gate * @param end end time or null if unspecified. 1477c478bd9Sstevel@tonic-gate * @throws NoSuchElementException if there is an error 1487c478bd9Sstevel@tonic-gate * accessing a list member. 1497c478bd9Sstevel@tonic-gate */ getSnapshotForInterval(Date start, Date end)1507c478bd9Sstevel@tonic-gate public AggregateStatistic getSnapshotForInterval(Date start, 1517c478bd9Sstevel@tonic-gate Date end) throws NoSuchElementException 1527c478bd9Sstevel@tonic-gate 1537c478bd9Sstevel@tonic-gate { 1547c478bd9Sstevel@tonic-gate return (getSnapshotForInterval(iterator(), start, end)); 1557c478bd9Sstevel@tonic-gate } 1567c478bd9Sstevel@tonic-gate 1577c478bd9Sstevel@tonic-gate /** 1587c478bd9Sstevel@tonic-gate * Returns the aggregated value for the StatisticList only 1597c478bd9Sstevel@tonic-gate * including samples which satisfy the start and end criteria. 1607c478bd9Sstevel@tonic-gate * 1617c478bd9Sstevel@tonic-gate * @param it An iterator over the contained elements to be 1627c478bd9Sstevel@tonic-gate * used as the basis for the snapshot. 1637c478bd9Sstevel@tonic-gate * @param start start time or null if unspecified. 1647c478bd9Sstevel@tonic-gate * @param end end time or null if unspecified. 1657c478bd9Sstevel@tonic-gate * @throws NoSuchElementException if there is an error 1667c478bd9Sstevel@tonic-gate * accessing a list member. 1677c478bd9Sstevel@tonic-gate */ getSnapshotForInterval(Iterator it, Date start, Date end)1687c478bd9Sstevel@tonic-gate private AggregateStatistic getSnapshotForInterval(Iterator it, 1697c478bd9Sstevel@tonic-gate Date start, Date end) 1707c478bd9Sstevel@tonic-gate { 1717c478bd9Sstevel@tonic-gate AggregateStatistic f = (AggregateStatistic) getFirst(); 1727c478bd9Sstevel@tonic-gate return (f.getSnapshotForInterval(it, start, end)); 1737c478bd9Sstevel@tonic-gate } 174*55fea89dSDan Cross 1757c478bd9Sstevel@tonic-gate /** 1767c478bd9Sstevel@tonic-gate * Add the supplied object to the list. If the list is full, 1777c478bd9Sstevel@tonic-gate * remove the first entry before adding the new entry. 1787c478bd9Sstevel@tonic-gate * 1797c478bd9Sstevel@tonic-gate * @param o Object to add to the list. 1807c478bd9Sstevel@tonic-gate */ add(Object o)181*55fea89dSDan Cross public boolean add(Object o) 1827c478bd9Sstevel@tonic-gate { 1837c478bd9Sstevel@tonic-gate boolean ret; 1847c478bd9Sstevel@tonic-gate if (size() == maxSize) 1857c478bd9Sstevel@tonic-gate removeFirst(); 1867c478bd9Sstevel@tonic-gate ret = super.add(o); 1877c478bd9Sstevel@tonic-gate if (ret) 1887c478bd9Sstevel@tonic-gate notifyStatisticAdd((AggregateStatistic) o); 1897c478bd9Sstevel@tonic-gate return (ret); 1907c478bd9Sstevel@tonic-gate } 1917c478bd9Sstevel@tonic-gate 1927c478bd9Sstevel@tonic-gate /** 1937c478bd9Sstevel@tonic-gate * Remove the supplied object from the list. 1947c478bd9Sstevel@tonic-gate * 1957c478bd9Sstevel@tonic-gate * @param o Object to remove from the list. 1967c478bd9Sstevel@tonic-gate */ remove(Object o)197*55fea89dSDan Cross public boolean remove(Object o) 1987c478bd9Sstevel@tonic-gate { 1997c478bd9Sstevel@tonic-gate boolean ret; 2007c478bd9Sstevel@tonic-gate ret = super.remove(o); 2017c478bd9Sstevel@tonic-gate if (ret) 2027c478bd9Sstevel@tonic-gate notifyStatisticRemove((AggregateStatistic) o); 2037c478bd9Sstevel@tonic-gate return (ret); 2047c478bd9Sstevel@tonic-gate } 2057c478bd9Sstevel@tonic-gate 2067c478bd9Sstevel@tonic-gate /** 2077c478bd9Sstevel@tonic-gate * Removes and returns the first element from this list. 2087c478bd9Sstevel@tonic-gate * 2097c478bd9Sstevel@tonic-gate * @return the first element from this list. 2107c478bd9Sstevel@tonic-gate * @throws NoSuchElementException if this list is empty. 2117c478bd9Sstevel@tonic-gate */ removeFirst()2127c478bd9Sstevel@tonic-gate public Object removeFirst() { 2137c478bd9Sstevel@tonic-gate Object first = getFirst(); 2147c478bd9Sstevel@tonic-gate remove(first); 2157c478bd9Sstevel@tonic-gate return (first); 2167c478bd9Sstevel@tonic-gate } 2177c478bd9Sstevel@tonic-gate 2187c478bd9Sstevel@tonic-gate /** 2197c478bd9Sstevel@tonic-gate * Add a listener for StatisticEvents. 2207c478bd9Sstevel@tonic-gate * 2217c478bd9Sstevel@tonic-gate * @param l Listener to add. 2227c478bd9Sstevel@tonic-gate */ addStatisticListener(StatisticListener l)2237c478bd9Sstevel@tonic-gate public void addStatisticListener(StatisticListener l) { 2247c478bd9Sstevel@tonic-gate listeners.add(l); 2257c478bd9Sstevel@tonic-gate } 2267c478bd9Sstevel@tonic-gate 2277c478bd9Sstevel@tonic-gate /** 2287c478bd9Sstevel@tonic-gate * Remove a listener for StatisticEvents. 2297c478bd9Sstevel@tonic-gate * 2307c478bd9Sstevel@tonic-gate * @param l Listener to remove. 2317c478bd9Sstevel@tonic-gate */ removeStatisticListener(StatisticListener l)2327c478bd9Sstevel@tonic-gate public void removeStatisticListener(StatisticListener l) { 2337c478bd9Sstevel@tonic-gate listeners.remove(l); 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate 2367c478bd9Sstevel@tonic-gate /** 2377c478bd9Sstevel@tonic-gate * Notify all StatisticEvent listeners of a new Add event. 2387c478bd9Sstevel@tonic-gate * 2397c478bd9Sstevel@tonic-gate * @param s Event payload. 2407c478bd9Sstevel@tonic-gate */ notifyStatisticAdd(AggregateStatistic s)2417c478bd9Sstevel@tonic-gate private void notifyStatisticAdd(AggregateStatistic s) 2427c478bd9Sstevel@tonic-gate { 2437c478bd9Sstevel@tonic-gate StatisticEvent e = new StatisticEvent(this, 2447c478bd9Sstevel@tonic-gate StatisticEvent.ADD, s); 2457c478bd9Sstevel@tonic-gate 2467c478bd9Sstevel@tonic-gate Iterator listIt = listeners.iterator(); 2477c478bd9Sstevel@tonic-gate 2487c478bd9Sstevel@tonic-gate while (listIt.hasNext()) { 249*55fea89dSDan Cross 2507c478bd9Sstevel@tonic-gate StatisticListener l = (StatisticListener)listIt.next(); 2517c478bd9Sstevel@tonic-gate l.onStatisticAdd(e); 2527c478bd9Sstevel@tonic-gate } 2537c478bd9Sstevel@tonic-gate } 2547c478bd9Sstevel@tonic-gate 2557c478bd9Sstevel@tonic-gate /** 2567c478bd9Sstevel@tonic-gate * Notify all StatisticEvent listeners of a new Remove event. 2577c478bd9Sstevel@tonic-gate * 2587c478bd9Sstevel@tonic-gate * @param s Event payload. 2597c478bd9Sstevel@tonic-gate */ notifyStatisticRemove(AggregateStatistic s)2607c478bd9Sstevel@tonic-gate private void notifyStatisticRemove(AggregateStatistic s) 2617c478bd9Sstevel@tonic-gate { 2627c478bd9Sstevel@tonic-gate StatisticEvent e = new StatisticEvent(this, 2637c478bd9Sstevel@tonic-gate StatisticEvent.REMOVE, s); 2647c478bd9Sstevel@tonic-gate 2657c478bd9Sstevel@tonic-gate Iterator listIt = listeners.iterator(); 2667c478bd9Sstevel@tonic-gate 2677c478bd9Sstevel@tonic-gate while (listIt.hasNext()) { 268*55fea89dSDan Cross 2697c478bd9Sstevel@tonic-gate StatisticListener l = (StatisticListener)listIt.next(); 2707c478bd9Sstevel@tonic-gate l.onStatisticRemove(e); 2717c478bd9Sstevel@tonic-gate } 2727c478bd9Sstevel@tonic-gate } 2737c478bd9Sstevel@tonic-gate 2747c478bd9Sstevel@tonic-gate /** 2757c478bd9Sstevel@tonic-gate * Return true if the contents of the instance are 2767c478bd9Sstevel@tonic-gate * statistically valid. 2777c478bd9Sstevel@tonic-gate */ isValid()2787c478bd9Sstevel@tonic-gate boolean isValid() 2797c478bd9Sstevel@tonic-gate { 2807c478bd9Sstevel@tonic-gate return (statisticOperations.isValid()); 2817c478bd9Sstevel@tonic-gate } 2827c478bd9Sstevel@tonic-gate 2837c478bd9Sstevel@tonic-gate /** 2847c478bd9Sstevel@tonic-gate * Return the zone of control to which the supplied val 2857c478bd9Sstevel@tonic-gate * belongs based on the target details in the supplied 2867c478bd9Sstevel@tonic-gate * objective expression. 2877c478bd9Sstevel@tonic-gate * 2887c478bd9Sstevel@tonic-gate * @param kve Objective expression used to determine zone 2897c478bd9Sstevel@tonic-gate * details. 2907c478bd9Sstevel@tonic-gate * @param val The value to be assessed. 2917c478bd9Sstevel@tonic-gate */ getZone(KVOpExpression kve, double val)2927c478bd9Sstevel@tonic-gate int getZone(KVOpExpression kve, double val) 2937c478bd9Sstevel@tonic-gate { 2947c478bd9Sstevel@tonic-gate return (statisticOperations.getZone(kve, val)); 2957c478bd9Sstevel@tonic-gate } 2967c478bd9Sstevel@tonic-gate 2977c478bd9Sstevel@tonic-gate /** 2987c478bd9Sstevel@tonic-gate * Return the zone of control to which the supplied val 2997c478bd9Sstevel@tonic-gate * belongs based on the mean of the sampled data. 3007c478bd9Sstevel@tonic-gate * 3017c478bd9Sstevel@tonic-gate * @param val The value to be assessed. 3027c478bd9Sstevel@tonic-gate */ getZoneMean(double val)3037c478bd9Sstevel@tonic-gate int getZoneMean(double val) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate return (statisticOperations.getZoneMean(val)); 3067c478bd9Sstevel@tonic-gate } 3077c478bd9Sstevel@tonic-gate 3087c478bd9Sstevel@tonic-gate /** 3097c478bd9Sstevel@tonic-gate * Return the difference (gap) between the target utilization 3107c478bd9Sstevel@tonic-gate * expressed in the supplied objective expression and the 3117c478bd9Sstevel@tonic-gate * supplied value. 3127c478bd9Sstevel@tonic-gate * 3137c478bd9Sstevel@tonic-gate * @param kve Objective expression used to determine target 3147c478bd9Sstevel@tonic-gate * utilization details. 3157c478bd9Sstevel@tonic-gate * @param val The value to be assessed. 3167c478bd9Sstevel@tonic-gate */ getGap(KVOpExpression kve, double val)3177c478bd9Sstevel@tonic-gate double getGap(KVOpExpression kve, double val) 3187c478bd9Sstevel@tonic-gate { 3197c478bd9Sstevel@tonic-gate return (statisticOperations.getGap(kve, val)); 3207c478bd9Sstevel@tonic-gate } 3217c478bd9Sstevel@tonic-gate 3227c478bd9Sstevel@tonic-gate /** 3237c478bd9Sstevel@tonic-gate * Clear all the data from the StatisticList and reset all the 3247c478bd9Sstevel@tonic-gate * statistic counters. 3257c478bd9Sstevel@tonic-gate */ clear()326*55fea89dSDan Cross public void clear() 3277c478bd9Sstevel@tonic-gate { 3287c478bd9Sstevel@tonic-gate if (statisticOperations != null) { 3297c478bd9Sstevel@tonic-gate removeStatisticListener(statisticOperations); 3307c478bd9Sstevel@tonic-gate statisticOperations = new StatisticOperations(this); 3317c478bd9Sstevel@tonic-gate addStatisticListener(statisticOperations); 3327c478bd9Sstevel@tonic-gate } 3337c478bd9Sstevel@tonic-gate super.clear(); 3347c478bd9Sstevel@tonic-gate } 3357c478bd9Sstevel@tonic-gate 3367c478bd9Sstevel@tonic-gate /** 3377c478bd9Sstevel@tonic-gate * Return a string which describes the zones for this set of 3387c478bd9Sstevel@tonic-gate * data. 3397c478bd9Sstevel@tonic-gate * 3407c478bd9Sstevel@tonic-gate * @param kve The expression containing objectives. 3417c478bd9Sstevel@tonic-gate * @param val The value to be assessed against objectives. 3427c478bd9Sstevel@tonic-gate */ toZoneString(KVOpExpression kve, double val)3437c478bd9Sstevel@tonic-gate public String toZoneString(KVOpExpression kve, double val) 3447c478bd9Sstevel@tonic-gate { 3457c478bd9Sstevel@tonic-gate return (statisticOperations.toZoneString(kve, val)); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate } 3487c478bd9Sstevel@tonic-gate 3497c478bd9Sstevel@tonic-gate /** 3507c478bd9Sstevel@tonic-gate * Event class which describes modifications (Add, Remove) to a 3517c478bd9Sstevel@tonic-gate * StatisticList instance. 3527c478bd9Sstevel@tonic-gate */ 3537c478bd9Sstevel@tonic-gate final class StatisticEvent extends EventObject 3547c478bd9Sstevel@tonic-gate { 3557c478bd9Sstevel@tonic-gate /** 3567c478bd9Sstevel@tonic-gate * Identifier for an ADD event. 3577c478bd9Sstevel@tonic-gate */ 3587c478bd9Sstevel@tonic-gate public static final int ADD = 0x1; 3597c478bd9Sstevel@tonic-gate 3607c478bd9Sstevel@tonic-gate /** 3617c478bd9Sstevel@tonic-gate * Identifier for a REMOVE event. 3627c478bd9Sstevel@tonic-gate */ 3637c478bd9Sstevel@tonic-gate public static final int REMOVE = 0x2; 3647c478bd9Sstevel@tonic-gate 3657c478bd9Sstevel@tonic-gate /** 3667c478bd9Sstevel@tonic-gate * The target of the event. 3677c478bd9Sstevel@tonic-gate */ 3687c478bd9Sstevel@tonic-gate private final AggregateStatistic target; 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate /** 3717c478bd9Sstevel@tonic-gate * The identifier of this event. 3727c478bd9Sstevel@tonic-gate */ 3737c478bd9Sstevel@tonic-gate private final int id; 3747c478bd9Sstevel@tonic-gate 3757c478bd9Sstevel@tonic-gate /** 3767c478bd9Sstevel@tonic-gate * Constructor. 3777c478bd9Sstevel@tonic-gate * 3787c478bd9Sstevel@tonic-gate * @param source The source of the event. 3797c478bd9Sstevel@tonic-gate * @param id The type of the event. 3807c478bd9Sstevel@tonic-gate * @param target The target of the event. 3817c478bd9Sstevel@tonic-gate */ StatisticEvent(Object source, int id, AggregateStatistic target)3827c478bd9Sstevel@tonic-gate public StatisticEvent(Object source, int id, AggregateStatistic target) 3837c478bd9Sstevel@tonic-gate { 3847c478bd9Sstevel@tonic-gate super(source); 3857c478bd9Sstevel@tonic-gate this.id = id; 3867c478bd9Sstevel@tonic-gate this.target = target; 3877c478bd9Sstevel@tonic-gate } 3887c478bd9Sstevel@tonic-gate 3897c478bd9Sstevel@tonic-gate /** 3907c478bd9Sstevel@tonic-gate * Return the target of the event. 3917c478bd9Sstevel@tonic-gate */ getTarget()3927c478bd9Sstevel@tonic-gate public AggregateStatistic getTarget() 3937c478bd9Sstevel@tonic-gate { 3947c478bd9Sstevel@tonic-gate return (target); 3957c478bd9Sstevel@tonic-gate } 3967c478bd9Sstevel@tonic-gate 3977c478bd9Sstevel@tonic-gate /** 3987c478bd9Sstevel@tonic-gate * Return the ID (type) of the event. 3997c478bd9Sstevel@tonic-gate */ getID()4007c478bd9Sstevel@tonic-gate public int getID() 4017c478bd9Sstevel@tonic-gate { 4027c478bd9Sstevel@tonic-gate return (id); 4037c478bd9Sstevel@tonic-gate } 4047c478bd9Sstevel@tonic-gate 4057c478bd9Sstevel@tonic-gate /** 4067c478bd9Sstevel@tonic-gate * Return the source of the event. This is a typesafe 4077c478bd9Sstevel@tonic-gate * alternative to using getSource(). 4087c478bd9Sstevel@tonic-gate */ getStatisticList()4097c478bd9Sstevel@tonic-gate public StatisticList getStatisticList() 4107c478bd9Sstevel@tonic-gate { 4117c478bd9Sstevel@tonic-gate return ((StatisticList) source); 4127c478bd9Sstevel@tonic-gate } 413*55fea89dSDan Cross 4147c478bd9Sstevel@tonic-gate } 4157c478bd9Sstevel@tonic-gate 4167c478bd9Sstevel@tonic-gate /** 4177c478bd9Sstevel@tonic-gate * The listener interface for receiving statistic events. The class 4187c478bd9Sstevel@tonic-gate * that is interested in processing a statistic event implements this 4197c478bd9Sstevel@tonic-gate * interface, and the object created with that class is registered 4207c478bd9Sstevel@tonic-gate * with a component, using the component's addStatisticListener 4217c478bd9Sstevel@tonic-gate * method. When the statistic event occurs, the relevant method in the 4227c478bd9Sstevel@tonic-gate * listener object is invoked, and the StatisticEvent is passed to it. 4237c478bd9Sstevel@tonic-gate */ 4247c478bd9Sstevel@tonic-gate interface StatisticListener extends EventListener 4257c478bd9Sstevel@tonic-gate { 4267c478bd9Sstevel@tonic-gate /** 4277c478bd9Sstevel@tonic-gate * Invoked when a statistic is added to the source 4287c478bd9Sstevel@tonic-gate * StatisticList. 4297c478bd9Sstevel@tonic-gate * 4307c478bd9Sstevel@tonic-gate * @param e The event. 4317c478bd9Sstevel@tonic-gate */ onStatisticAdd(StatisticEvent e)4327c478bd9Sstevel@tonic-gate public void onStatisticAdd(StatisticEvent e); 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate /** 4357c478bd9Sstevel@tonic-gate * Invoked when a statistic is removed from the source 4367c478bd9Sstevel@tonic-gate * StatisticList. 4377c478bd9Sstevel@tonic-gate * 4387c478bd9Sstevel@tonic-gate * @param e The event. 4397c478bd9Sstevel@tonic-gate */ onStatisticRemove(StatisticEvent e)4407c478bd9Sstevel@tonic-gate public void onStatisticRemove(StatisticEvent e); 4417c478bd9Sstevel@tonic-gate } 4427c478bd9Sstevel@tonic-gate 4437c478bd9Sstevel@tonic-gate /** 4447c478bd9Sstevel@tonic-gate * This class performs statistical calculations on a source 4457c478bd9Sstevel@tonic-gate * StatisticList. Zones are regions in a set of samples which are set 4467c478bd9Sstevel@tonic-gate * to be at 1, 2 and 3 standard deviations from the mean. ZONEC is 4477c478bd9Sstevel@tonic-gate * closest to the center, with ZONEZ representing the region beyond 4487c478bd9Sstevel@tonic-gate * ZONEA. 4497c478bd9Sstevel@tonic-gate */ 4507c478bd9Sstevel@tonic-gate class StatisticOperations implements StatisticListener 4517c478bd9Sstevel@tonic-gate { 4527c478bd9Sstevel@tonic-gate /** 4537c478bd9Sstevel@tonic-gate * Control zone C. 4547c478bd9Sstevel@tonic-gate */ 4557c478bd9Sstevel@tonic-gate public static final int ZONEC = 0x00010; 4567c478bd9Sstevel@tonic-gate 4577c478bd9Sstevel@tonic-gate /** 4587c478bd9Sstevel@tonic-gate * Control zone B. 4597c478bd9Sstevel@tonic-gate */ 4607c478bd9Sstevel@tonic-gate public static final int ZONEB = 0x00100; 4617c478bd9Sstevel@tonic-gate 4627c478bd9Sstevel@tonic-gate /** 4637c478bd9Sstevel@tonic-gate * Control zone A. 4647c478bd9Sstevel@tonic-gate */ 4657c478bd9Sstevel@tonic-gate public static final int ZONEA = 0x01000; 4667c478bd9Sstevel@tonic-gate 4677c478bd9Sstevel@tonic-gate /** 4687c478bd9Sstevel@tonic-gate * Control zone Z. 4697c478bd9Sstevel@tonic-gate */ 4707c478bd9Sstevel@tonic-gate public static final int ZONEZ = 0x10000; 4717c478bd9Sstevel@tonic-gate 4727c478bd9Sstevel@tonic-gate /** 4737c478bd9Sstevel@tonic-gate * Direction from mean (used to test ZONELT and ZONEGT). 4747c478bd9Sstevel@tonic-gate */ 4757c478bd9Sstevel@tonic-gate public static final int ZONET = 0x00001; 4767c478bd9Sstevel@tonic-gate 4777c478bd9Sstevel@tonic-gate /** 4787c478bd9Sstevel@tonic-gate * Less than the mean. 4797c478bd9Sstevel@tonic-gate */ 4807c478bd9Sstevel@tonic-gate public static final int ZONELT = 0x00000; 4817c478bd9Sstevel@tonic-gate 4827c478bd9Sstevel@tonic-gate /** 4837c478bd9Sstevel@tonic-gate * Greater than the mean. 4847c478bd9Sstevel@tonic-gate */ 4857c478bd9Sstevel@tonic-gate public static final int ZONEGT = 0x00001; 4867c478bd9Sstevel@tonic-gate 4877c478bd9Sstevel@tonic-gate /** 4887c478bd9Sstevel@tonic-gate * The raw statistical data. 4897c478bd9Sstevel@tonic-gate */ 4907c478bd9Sstevel@tonic-gate private final StatisticList statistics; 4917c478bd9Sstevel@tonic-gate 4927c478bd9Sstevel@tonic-gate /** 4937c478bd9Sstevel@tonic-gate * The mean of the samples. 4947c478bd9Sstevel@tonic-gate */ 4957c478bd9Sstevel@tonic-gate private double mean; 4967c478bd9Sstevel@tonic-gate 4977c478bd9Sstevel@tonic-gate /** 4987c478bd9Sstevel@tonic-gate * The standard deviation of the samples. 4997c478bd9Sstevel@tonic-gate */ 5007c478bd9Sstevel@tonic-gate private double sd; 5017c478bd9Sstevel@tonic-gate 5027c478bd9Sstevel@tonic-gate /** 5037c478bd9Sstevel@tonic-gate * The total of the samples. 5047c478bd9Sstevel@tonic-gate */ 5057c478bd9Sstevel@tonic-gate private AggregateStatistic total; 5067c478bd9Sstevel@tonic-gate 5077c478bd9Sstevel@tonic-gate /** 5087c478bd9Sstevel@tonic-gate * Constructs a new StatisticOperations object for working on 5097c478bd9Sstevel@tonic-gate * the given statistic, whose values are in the given 5107c478bd9Sstevel@tonic-gate * (modifiable) data set. 5117c478bd9Sstevel@tonic-gate * 5127c478bd9Sstevel@tonic-gate * @param statistics The statistics to operate on. 5137c478bd9Sstevel@tonic-gate */ StatisticOperations(StatisticList statistics)5147c478bd9Sstevel@tonic-gate public StatisticOperations(StatisticList statistics) 5157c478bd9Sstevel@tonic-gate { 5167c478bd9Sstevel@tonic-gate this.statistics = statistics; 5177c478bd9Sstevel@tonic-gate total = new DoubleStatistic(new Double(0.0)); 5187c478bd9Sstevel@tonic-gate } 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate /** 5217c478bd9Sstevel@tonic-gate * Calculate the standard deviation for the data held in the 5227c478bd9Sstevel@tonic-gate * associated StatisticsList. 5237c478bd9Sstevel@tonic-gate */ calc_sd()5247c478bd9Sstevel@tonic-gate private void calc_sd() 5257c478bd9Sstevel@tonic-gate { 5267c478bd9Sstevel@tonic-gate Iterator it; 5277c478bd9Sstevel@tonic-gate 5287c478bd9Sstevel@tonic-gate sd = 0; 5297c478bd9Sstevel@tonic-gate it = statistics.iterator(); 5307c478bd9Sstevel@tonic-gate while (it.hasNext()) { 5317c478bd9Sstevel@tonic-gate Double val = (Double)((DoubleStatistic) 5327c478bd9Sstevel@tonic-gate ((AggregateStatistic)it.next())).getValue(); 533*55fea89dSDan Cross 5347c478bd9Sstevel@tonic-gate sd += java.lang.Math.pow(val.doubleValue() - mean, 2); 5357c478bd9Sstevel@tonic-gate } 5367c478bd9Sstevel@tonic-gate sd /= statistics.size(); 5377c478bd9Sstevel@tonic-gate sd = java.lang.Math.sqrt(sd); 5387c478bd9Sstevel@tonic-gate } 5397c478bd9Sstevel@tonic-gate 5407c478bd9Sstevel@tonic-gate /** 5417c478bd9Sstevel@tonic-gate * Return a string which describes the zones for this set of 5427c478bd9Sstevel@tonic-gate * data. 5437c478bd9Sstevel@tonic-gate * 5447c478bd9Sstevel@tonic-gate * @param kve The expression containing objectives. 5457c478bd9Sstevel@tonic-gate * @param val The value to be assessed against objectives. 5467c478bd9Sstevel@tonic-gate */ toZoneString(KVOpExpression kve, double val)5477c478bd9Sstevel@tonic-gate public String toZoneString(KVOpExpression kve, double val) 5487c478bd9Sstevel@tonic-gate { 5497c478bd9Sstevel@tonic-gate if (isValid()) { 5507c478bd9Sstevel@tonic-gate DecimalFormat f = new DecimalFormat("00.00"); 5517c478bd9Sstevel@tonic-gate double target = kve.getValue(); 5527c478bd9Sstevel@tonic-gate 5537c478bd9Sstevel@tonic-gate if (kve.getOp() == KVOpExpression.LT) { 5547c478bd9Sstevel@tonic-gate target -= 3 * sd; 5557c478bd9Sstevel@tonic-gate } else if (kve.getOp() == KVOpExpression.GT) { 5567c478bd9Sstevel@tonic-gate target += 3 * sd; 5577c478bd9Sstevel@tonic-gate } 5587c478bd9Sstevel@tonic-gate StringBuffer buf = new StringBuffer(); 5597c478bd9Sstevel@tonic-gate buf.append(kve.toString()); 5607c478bd9Sstevel@tonic-gate buf.append("\nsample = " + statistics.size()); 5617c478bd9Sstevel@tonic-gate buf.append("\n\ttarget: " + f.format(target)); 5627c478bd9Sstevel@tonic-gate buf.append("\n\tvalue: " + f.format(val)); 5637c478bd9Sstevel@tonic-gate buf.append("\n\tsd: " + f.format(sd)); 5647c478bd9Sstevel@tonic-gate buf.append("\n\tZones:"); 5657c478bd9Sstevel@tonic-gate buf.append("\n\t\tC:" + f.format(target - sd)); 5667c478bd9Sstevel@tonic-gate buf.append("-" + f.format(target + sd)); 5677c478bd9Sstevel@tonic-gate buf.append("\n\t\tB:" + f.format(target - 2 * sd)); 5687c478bd9Sstevel@tonic-gate buf.append("-" + f.format(target + 2 * sd)); 5697c478bd9Sstevel@tonic-gate buf.append("\n\t\tA:" + f.format(target - 3 * sd)); 5707c478bd9Sstevel@tonic-gate buf.append("-" + f.format(target + 3 * sd)); 5717c478bd9Sstevel@tonic-gate return (buf.toString()); 5727c478bd9Sstevel@tonic-gate } else { 5737c478bd9Sstevel@tonic-gate return ("Still sampling..."); 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate } 5767c478bd9Sstevel@tonic-gate 5777c478bd9Sstevel@tonic-gate 5787c478bd9Sstevel@tonic-gate /** 5797c478bd9Sstevel@tonic-gate * Return a string which describes this instance. 5807c478bd9Sstevel@tonic-gate */ toString()5817c478bd9Sstevel@tonic-gate public String toString() 5827c478bd9Sstevel@tonic-gate { 5837c478bd9Sstevel@tonic-gate DecimalFormat f = new DecimalFormat("00.00"); 5847c478bd9Sstevel@tonic-gate 5857c478bd9Sstevel@tonic-gate if (isValid()) { 5867c478bd9Sstevel@tonic-gate return ("sample = " + statistics.size() + 5877c478bd9Sstevel@tonic-gate "\n\tmean: " + f.format(mean) + 5887c478bd9Sstevel@tonic-gate "\n\tsd: " + f.format(sd) + 5897c478bd9Sstevel@tonic-gate "\n\tZones:" + 5907c478bd9Sstevel@tonic-gate "\n\t\tC:" + f.format(mean - sd) + 5917c478bd9Sstevel@tonic-gate "-" + f.format(mean + sd) + 5927c478bd9Sstevel@tonic-gate "\n\t\tB:" + f.format(mean - 2 * sd) + 5937c478bd9Sstevel@tonic-gate "-" + f.format(mean + 2 * sd) + 5947c478bd9Sstevel@tonic-gate "\n\t\tA:" + f.format(mean - 3 * sd) + 5957c478bd9Sstevel@tonic-gate "-" + f.format(mean + 3 * sd)); 5967c478bd9Sstevel@tonic-gate } else { 5977c478bd9Sstevel@tonic-gate return ("Still sampling..."); 5987c478bd9Sstevel@tonic-gate } 5997c478bd9Sstevel@tonic-gate } 6007c478bd9Sstevel@tonic-gate 6017c478bd9Sstevel@tonic-gate /** 6027c478bd9Sstevel@tonic-gate * Return true if the data is normally distributed. This 6037c478bd9Sstevel@tonic-gate * method currently just returns true if the sample size is >= 6047c478bd9Sstevel@tonic-gate * 5. It could be extended to use a test of normality, for 6057c478bd9Sstevel@tonic-gate * instance "Pearson's Chi-Squared Test" or "Shapiro-Wilks W 6067c478bd9Sstevel@tonic-gate * Test". 6077c478bd9Sstevel@tonic-gate */ isValid()6087c478bd9Sstevel@tonic-gate public boolean isValid() 6097c478bd9Sstevel@tonic-gate { 6107c478bd9Sstevel@tonic-gate if (statistics.size() >= 5) 6117c478bd9Sstevel@tonic-gate return (true); 6127c478bd9Sstevel@tonic-gate return (false); 6137c478bd9Sstevel@tonic-gate } 6147c478bd9Sstevel@tonic-gate 6157c478bd9Sstevel@tonic-gate /** 6167c478bd9Sstevel@tonic-gate * Calculate the statistical values for the associated 6177c478bd9Sstevel@tonic-gate * samples. This method should be called when the sample 6187c478bd9Sstevel@tonic-gate * population changes. 6197c478bd9Sstevel@tonic-gate */ process()6207c478bd9Sstevel@tonic-gate private final void process() 6217c478bd9Sstevel@tonic-gate { 6227c478bd9Sstevel@tonic-gate mean = ((Double)((DoubleStatistic)total).getValue()). 6237c478bd9Sstevel@tonic-gate doubleValue() / statistics.size(); 6247c478bd9Sstevel@tonic-gate calc_sd(); 6257c478bd9Sstevel@tonic-gate } 6267c478bd9Sstevel@tonic-gate 6277c478bd9Sstevel@tonic-gate /** 6287c478bd9Sstevel@tonic-gate * Return the control zone for the supplied value using the 6297c478bd9Sstevel@tonic-gate * information derived from the monitored statistics and the 6307c478bd9Sstevel@tonic-gate * objective expressed in the supplied objective expression. 6317c478bd9Sstevel@tonic-gate * 6327c478bd9Sstevel@tonic-gate * @param kve The target utilization expression. 6337c478bd9Sstevel@tonic-gate * @param val The value to be evaluated. 6347c478bd9Sstevel@tonic-gate */ getZone(KVOpExpression kve, double val)6357c478bd9Sstevel@tonic-gate public int getZone(KVOpExpression kve, double val) 6367c478bd9Sstevel@tonic-gate { 6377c478bd9Sstevel@tonic-gate if (!isValid()) 6387c478bd9Sstevel@tonic-gate return (StatisticOperations.ZONEC); 6397c478bd9Sstevel@tonic-gate 6407c478bd9Sstevel@tonic-gate double target = kve.getValue(); 6417c478bd9Sstevel@tonic-gate 6427c478bd9Sstevel@tonic-gate if (kve.getOp() == KVOpExpression.LT) { 6437c478bd9Sstevel@tonic-gate target -= 3 * sd; 6447c478bd9Sstevel@tonic-gate } else if (kve.getOp() == KVOpExpression.GT) { 6457c478bd9Sstevel@tonic-gate target += 3 * sd; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate 6487c478bd9Sstevel@tonic-gate return (getZone(target, val)); 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate /** 6527c478bd9Sstevel@tonic-gate * Return the control zone for the supplied value using the 6537c478bd9Sstevel@tonic-gate * information derived from the monitored statistics. 6547c478bd9Sstevel@tonic-gate * 6557c478bd9Sstevel@tonic-gate * @param val The value to be evaluated. 6567c478bd9Sstevel@tonic-gate */ getZoneMean(double val)6577c478bd9Sstevel@tonic-gate public int getZoneMean(double val) 6587c478bd9Sstevel@tonic-gate { 6597c478bd9Sstevel@tonic-gate if (!isValid()) 6607c478bd9Sstevel@tonic-gate return (StatisticOperations.ZONEC); 6617c478bd9Sstevel@tonic-gate 6627c478bd9Sstevel@tonic-gate return (getZone(mean, val)); 6637c478bd9Sstevel@tonic-gate } 6647c478bd9Sstevel@tonic-gate 6657c478bd9Sstevel@tonic-gate /** 6667c478bd9Sstevel@tonic-gate * Return the control zone for the supplied value using the 6677c478bd9Sstevel@tonic-gate * information derived from the supplied target. 6687c478bd9Sstevel@tonic-gate * 6697c478bd9Sstevel@tonic-gate * @param val The value to be evaluated. 6707c478bd9Sstevel@tonic-gate */ getZone(double target, double val)6717c478bd9Sstevel@tonic-gate private int getZone(double target, double val) 6727c478bd9Sstevel@tonic-gate { 6737c478bd9Sstevel@tonic-gate if (!isValid()) 6747c478bd9Sstevel@tonic-gate return (StatisticOperations.ZONEC); 6757c478bd9Sstevel@tonic-gate 6767c478bd9Sstevel@tonic-gate return ((val < target - 3 * sd) ? 6777c478bd9Sstevel@tonic-gate ZONEZ | ZONELT : (val > target + 3 * sd) ? 6787c478bd9Sstevel@tonic-gate ZONEZ | ZONEGT : (val < target - 2 * sd) ? 6797c478bd9Sstevel@tonic-gate ZONEA | ZONELT : (val > target + 2 * sd) ? 6807c478bd9Sstevel@tonic-gate ZONEA | ZONEGT : (val < target - sd) ? 6817c478bd9Sstevel@tonic-gate ZONEB | ZONELT : (val > target + sd) ? 6827c478bd9Sstevel@tonic-gate ZONEB | ZONEGT : (val < target) ? 6837c478bd9Sstevel@tonic-gate ZONEC | ZONELT : ZONEC | ZONEGT); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate 6867c478bd9Sstevel@tonic-gate /** 6877c478bd9Sstevel@tonic-gate * Return the difference (gap) between the target utilization 6887c478bd9Sstevel@tonic-gate * expressed in the supplied objective expression and the 6897c478bd9Sstevel@tonic-gate * supplied value. 6907c478bd9Sstevel@tonic-gate * 6917c478bd9Sstevel@tonic-gate * @param kve Objective expression used to determine target 6927c478bd9Sstevel@tonic-gate * utilization details. 6937c478bd9Sstevel@tonic-gate * @param val The value to be assessed. 6947c478bd9Sstevel@tonic-gate */ getGap(KVOpExpression kve, double val)6957c478bd9Sstevel@tonic-gate public double getGap(KVOpExpression kve, double val) 6967c478bd9Sstevel@tonic-gate { 6977c478bd9Sstevel@tonic-gate if (!isValid()) 6987c478bd9Sstevel@tonic-gate return (0.0); 6997c478bd9Sstevel@tonic-gate 7007c478bd9Sstevel@tonic-gate double target = kve.getValue(); 7017c478bd9Sstevel@tonic-gate 7027c478bd9Sstevel@tonic-gate if (kve.getOp() == KVOpExpression.LT) { 7037c478bd9Sstevel@tonic-gate target -= 3 * sd; 7047c478bd9Sstevel@tonic-gate } else if (kve.getOp() == KVOpExpression.GT) { 7057c478bd9Sstevel@tonic-gate target += 3 * sd; 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate if (val - target < -100) 7087c478bd9Sstevel@tonic-gate return (-100); 7097c478bd9Sstevel@tonic-gate else if (val - target > 100) 7107c478bd9Sstevel@tonic-gate return (100); 7117c478bd9Sstevel@tonic-gate else 7127c478bd9Sstevel@tonic-gate return (val - target); 7137c478bd9Sstevel@tonic-gate } 7147c478bd9Sstevel@tonic-gate 7157c478bd9Sstevel@tonic-gate /** 7167c478bd9Sstevel@tonic-gate * Event handler for added statistics. 7177c478bd9Sstevel@tonic-gate * 7187c478bd9Sstevel@tonic-gate * @param e The event. 7197c478bd9Sstevel@tonic-gate */ onStatisticAdd(StatisticEvent e)7207c478bd9Sstevel@tonic-gate public void onStatisticAdd(StatisticEvent e) 7217c478bd9Sstevel@tonic-gate { 7227c478bd9Sstevel@tonic-gate total = total.add(e.getTarget()); 7237c478bd9Sstevel@tonic-gate process(); 724*55fea89dSDan Cross 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate 7277c478bd9Sstevel@tonic-gate /** 7287c478bd9Sstevel@tonic-gate * Event handler for removed statistics. 7297c478bd9Sstevel@tonic-gate * 7307c478bd9Sstevel@tonic-gate * @param e The event. 7317c478bd9Sstevel@tonic-gate */ onStatisticRemove(StatisticEvent e)7327c478bd9Sstevel@tonic-gate public void onStatisticRemove(StatisticEvent e) 7337c478bd9Sstevel@tonic-gate { 7347c478bd9Sstevel@tonic-gate total = total.subtract(e.getTarget()); 7357c478bd9Sstevel@tonic-gate process(); 736*55fea89dSDan Cross } 7377c478bd9Sstevel@tonic-gate } 738