witchcraft_metrics/
counter.rs

1// Copyright 2019 Palantir Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15use std::sync::atomic::{AtomicI64, Ordering};
16
17/// A metric which counts a value.
18#[derive(Debug, Default)]
19pub struct Counter(AtomicI64);
20
21impl Counter {
22    /// Creates a new counter initialized to 0.
23    #[inline]
24    pub fn new() -> Counter {
25        Counter::default()
26    }
27
28    /// Resets the counter to 0.
29    #[inline]
30    pub fn clear(&self) {
31        self.0.store(0, Ordering::Relaxed);
32    }
33
34    /// Adds 1 to the counter.
35    #[inline]
36    pub fn inc(&self) {
37        self.add(1);
38    }
39
40    /// Subtracts 1 from the counter.
41    #[inline]
42    pub fn dec(&self) {
43        self.sub(1);
44    }
45
46    /// Adds a number to the counter.
47    #[inline]
48    pub fn add(&self, n: i64) {
49        self.0.fetch_add(n, Ordering::Relaxed);
50    }
51
52    /// Subtracts a number from the counter.
53    #[inline]
54    pub fn sub(&self, n: i64) {
55        self.0.fetch_sub(n, Ordering::Relaxed);
56    }
57
58    /// Returns the current value of the counter.
59    #[inline]
60    pub fn count(&self) -> i64 {
61        self.0.load(Ordering::Relaxed)
62    }
63}
64
65#[cfg(test)]
66mod test {
67    use crate::Counter;
68
69    #[test]
70    fn basic() {
71        let counter = Counter::new();
72        assert_eq!(counter.count(), 0);
73
74        counter.inc();
75        assert_eq!(counter.count(), 1);
76
77        counter.add(2);
78        assert_eq!(counter.count(), 3);
79
80        counter.dec();
81        assert_eq!(counter.count(), 2);
82
83        counter.sub(3);
84        assert_eq!(counter.count(), -1);
85
86        counter.clear();
87        assert_eq!(counter.count(), 0);
88    }
89}