View Javadoc

1   /***
2    *  Copyright 2003-2010 Terracotta, Inc.
3    *
4    *  Licensed under the Apache License, Version 2.0 (the "License");
5    *  you may not use this file except in compliance with the License.
6    *  You may obtain a copy of the License at
7    *
8    *      http://www.apache.org/licenses/LICENSE-2.0
9    *
10   *  Unless required by applicable law or agreed to in writing, software
11   *  distributed under the License is distributed on an "AS IS" BASIS,
12   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *  See the License for the specific language governing permissions and
14   *  limitations under the License.
15   */
16  
17  package net.sf.ehcache.util.counter.sampled;
18  
19  import java.util.TimerTask;
20  
21  import net.sf.ehcache.util.CircularLossyQueue;
22  import net.sf.ehcache.util.counter.CounterImpl;
23  
24  /***
25   * An implementation of {@link SampledCounter}
26   * 
27   * @author <a href="mailto:asanoujam@terracottatech.com">Abhishek Sanoujam</a>
28   * @since 1.7
29   * 
30   */
31  public class SampledCounterImpl extends CounterImpl implements SampledCounter {
32      private static final int MILLIS_PER_SEC = 1000;
33  
34      /***
35       * The history of this counter
36       */
37      protected final CircularLossyQueue<TimeStampedCounterValue> history;
38  
39      /***
40       * Should the counter reset on each sample?
41       */
42      protected final boolean resetOnSample;
43      private final TimerTask samplerTask;
44      private final long intervalMillis;
45  
46      /***
47       * todo GL how many threads is this creating?
48       * Constructor accepting a {@link SampledCounterConfig}
49       * 
50       * @param config
51       */
52      public SampledCounterImpl(SampledCounterConfig config) {
53          super(config.getInitialValue());
54  
55          this.intervalMillis = config.getIntervalSecs() * MILLIS_PER_SEC;
56          this.history = new CircularLossyQueue<TimeStampedCounterValue>(config.getHistorySize());
57          this.resetOnSample = config.isResetOnSample();
58  
59          this.samplerTask = new TimerTask() {
60              @Override
61              public void run() {
62                  recordSample();
63              }
64          };
65  
66          recordSample();
67      }
68  
69      /***
70       * {@inheritDoc}
71       */
72      public TimeStampedCounterValue getMostRecentSample() {
73          return this.history.peek();
74      }
75  
76      /***
77       * {@inheritDoc}
78       */
79      public TimeStampedCounterValue[] getAllSampleValues() {
80          return this.history.toArray(new TimeStampedCounterValue[this.history.depth()]);
81      }
82  
83      /***
84       * {@inheritDoc}
85       */
86      public void shutdown() {
87          if (samplerTask != null) {
88              samplerTask.cancel();
89          }
90      }
91  
92      /***
93       * Returns the timer task for this sampled counter
94       * 
95       * @return the timer task for this sampled counter
96       */
97      public TimerTask getTimerTask() {
98          return this.samplerTask;
99      }
100 
101     /***
102      * Returns the sampling thread interval in millis
103      * 
104      * @return the sampling thread interval in millis
105      */
106     public long getIntervalMillis() {
107         return intervalMillis;
108     }
109 
110     /***
111      * {@inheritDoc}
112      */
113     void recordSample() {
114         final long sample;
115         if (resetOnSample) {
116             sample = getAndReset();
117         } else {
118             sample = getValue();
119         }
120 
121         final long now = System.currentTimeMillis();
122         TimeStampedCounterValue timedSample = new TimeStampedCounterValue(now, sample);
123 
124         history.push(timedSample);
125     }
126 
127     /***
128      * {@inheritDoc}
129      */
130     public long getAndReset() {
131         return getAndSet(0L);
132     }
133 }