001/**
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.camel.management.mbean;
018
019/**
020 * Default implementation of {@link Statistic}
021 */
022public class Statistic {
023
024    /**
025     * Statistics mode
026     * <ul>
027     * <li>VALUE - A statistic with this update mode is a simple value that is a straight forward
028     * representation of the updated value.</li>
029     * <li>DIFFERENCE - A statistic with this update mode is a value that represents the difference
030     * between the last two recorded values (or the initial value if two updates have
031     * not been recorded).</li>
032     * <li>DELTA - A statistic with this update mode is a value that represents the delta
033     * between the last two recorded values (or the initial value if two updates have
034     * not been recorded). This value can be negative if the delta goes up or down.</li>
035     * <li>COUNTER - A statistic with this update mode interprets updates as increments (positive values)
036     * or decrements (negative values) to the current value.</li>
037     * <li>MAXIMUM - A statistic with this update mode is a value that represents the maximum value
038     * amongst the update values applied to this statistic.</li>
039     * <li>MINIMUM - A statistic with this update mode is a value that represents the minimum value
040     * amongst the update values applied to this statistic.</li>
041     * <ul>
042     */
043    public enum UpdateMode {
044        VALUE, DIFFERENCE, DELTA, COUNTER, MAXIMUM, MINIMUM
045    }
046
047    private final UpdateMode updateMode;
048    private long lastValue;
049    private long value;
050    private long updateCount;
051
052    /**
053     * Instantiates a new statistic.
054     *
055     * @param name  name of statistic
056     * @param owner owner
057     * @param updateMode The statistic update mode.
058     */
059    public Statistic(String name, Object owner, UpdateMode updateMode) {
060        this.updateMode = updateMode;
061    }
062
063    public synchronized void updateValue(long newValue) {
064        switch (this.updateMode) {
065        case COUNTER:
066            this.value += newValue;
067            break;
068        case VALUE:
069            this.value = newValue;
070            break;
071        case DIFFERENCE:
072            this.value -= newValue;
073            if (this.value < 0) {
074                this.value = -this.value;
075            }
076            break;
077        case DELTA:
078            if (updateCount > 0) {
079                this.lastValue = this.value;
080            }
081            this.value = newValue;
082            break;
083        case MAXIMUM:
084            // initialize value at first time
085            if (this.updateCount == 0 || this.value < newValue) {
086                this.value = newValue;
087            }
088            break;
089        case MINIMUM:
090            // initialize value at first time
091            if (this.updateCount == 0 || this.value > newValue) {
092                this.value = newValue;
093            }
094            break;
095        default:
096        }
097        this.updateCount++;
098    }
099
100    public synchronized void increment() {
101        updateValue(1);
102    }
103
104    public synchronized long getValue() {
105        if (updateMode == UpdateMode.DELTA) {
106            if (updateCount == 0) {
107                return this.value;
108            } else {
109                return this.value - this.lastValue;
110            }
111        } else {
112            return this.value;
113        }
114    }
115
116    public synchronized long getUpdateCount() {
117        return this.updateCount;
118    }
119
120    public synchronized void reset() {
121        this.value = 0;
122        this.lastValue = 0;
123        this.updateCount = 0;
124    }
125
126    public String toString() {
127        return "" + value;
128    }
129
130}