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}