001    /*
002    // $Id: //open/mondrian/src/main/mondrian/rolap/agg/CountingAggregationManager.java#2 $
003    // This software is subject to the terms of the Common Public License
004    // Agreement, available at the following URL:
005    // http://www.opensource.org/licenses/cpl.html.
006    // Copyright (C) 2002-2008 Julian Hyde and others
007    // All Rights Reserved.
008    // You must accept the terms of that agreement to use this software.
009    //
010    */
011    
012    package mondrian.rolap.agg;
013    
014    import mondrian.olap.Util;
015    import mondrian.rolap.RolapStar;
016    import mondrian.rolap.RolapAggregationManager.PinSet;
017    
018    /**
019     * This class adds to {@link AggregationManager} counters for
020     * aggregation cache hit and miss. It should only be used for testing
021     * purpose due to potential performance regression by the
022     * introduction of synchronized blocks.
023     *
024     * @author Khanh Vu
025     * @version $Id: //open/mondrian/src/main/mondrian/rolap/agg/CountingAggregationManager.java#2 $
026     */
027    public class CountingAggregationManager extends AggregationManager {
028        private SynchronizedCounter requestCount;
029        private SynchronizedCounter missCount;
030    
031        CountingAggregationManager() {
032            super();
033            requestCount = new SynchronizedCounter();
034            missCount = new SynchronizedCounter();
035        }
036    
037        /**
038         * Calls super method and sets counters.
039         */
040        public Object getCellFromCache(CellRequest request) {
041            requestCount.increment();
042            Object obj = super.getCellFromCache(request);
043            if (obj == null) {
044                missCount.increment();
045            }
046            return obj;
047        }
048    
049        /**
050         * Calls super method and sets counters.
051         */
052        public Object getCellFromCache(CellRequest request, PinSet pinSet) {
053            requestCount.increment();
054            Object obj = super.getCellFromCache(request, pinSet);
055            if (obj == null) {
056                missCount.increment();
057            }
058            return obj;
059        }
060    
061        /**
062         * Returns total number of cache requests.
063         *
064         * @return an integer represents value of request counter
065         */
066        public int getRequestCount() {
067            return requestCount.value();
068        }
069    
070        /**
071         * Returns number of cache misses.
072         *
073         * @return an integer represents value of cache miss counter
074         */
075        public int getMissCount() {
076            return missCount.value();
077        }
078    
079        /**
080         * Returns the cache hit ratio.
081         *
082         * @return a double value represent hit ratio
083         */
084        public double getHitRatio() {
085            return ((double) requestCount.value() - missCount.value()) /
086                requestCount.value();
087        }
088    
089        /**
090         * Resets both counters to zero
091         *
092         */
093        public void resetCounters() {
094            requestCount.reset();
095            missCount.reset();
096        }
097    
098        private class SynchronizedCounter {
099            private int c = 0;
100    
101            public synchronized void increment() {
102                c++;
103            }
104    
105            public synchronized void reset() {
106                c = 0;
107            }
108    
109            public synchronized int value() {
110                return c;
111            }
112        }
113    }
114    
115    // End CountingAggregationManager.java