starlark/eval/runtime/
small_duration.rs

1/*
2 * Copyright 2019 The Starlark in Rust Authors.
3 * Copyright (c) Facebook, Inc. and its affiliates.
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 *     https://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18use std::iter::Sum;
19use std::ops::Add;
20use std::ops::AddAssign;
21use std::ops::Div;
22use std::time::Duration;
23
24use allocative::Allocative;
25use dupe::Dupe;
26
27/// Slightly faster than `Duration`.
28#[derive(
29    Copy, Clone, Dupe, Default, Eq, PartialEq, Ord, PartialOrd, Debug, Allocative
30)]
31pub(crate) struct SmallDuration {
32    /// `u64::MAX` nanos is 500 years.
33    pub(crate) nanos: u64,
34}
35
36impl SmallDuration {
37    pub(crate) fn from_duration(duration: Duration) -> SmallDuration {
38        SmallDuration {
39            nanos: duration.as_nanos() as u64,
40        }
41    }
42
43    #[cfg(test)]
44    pub(crate) fn from_millis(millis: u64) -> SmallDuration {
45        Self::from_duration(Duration::from_millis(millis))
46    }
47
48    pub(crate) fn to_duration(self) -> Duration {
49        Duration::from_nanos(self.nanos)
50    }
51}
52
53impl AddAssign for SmallDuration {
54    fn add_assign(&mut self, other: Self) {
55        self.nanos += other.nanos;
56    }
57}
58
59impl AddAssign<Duration> for SmallDuration {
60    fn add_assign(&mut self, other: Duration) {
61        self.nanos += other.as_nanos() as u64;
62    }
63}
64
65impl Add<Duration> for SmallDuration {
66    type Output = SmallDuration;
67
68    fn add(self, other: Duration) -> Self::Output {
69        SmallDuration {
70            nanos: self.nanos + other.as_nanos() as u64,
71        }
72    }
73}
74
75impl Add<SmallDuration> for SmallDuration {
76    type Output = SmallDuration;
77
78    fn add(self, other: SmallDuration) -> SmallDuration {
79        SmallDuration {
80            nanos: self.nanos + other.nanos,
81        }
82    }
83}
84
85impl Div<u64> for SmallDuration {
86    type Output = SmallDuration;
87
88    fn div(self, other: u64) -> SmallDuration {
89        SmallDuration {
90            nanos: self.nanos / other,
91        }
92    }
93}
94
95impl<'a> Sum<&'a SmallDuration> for SmallDuration {
96    fn sum<I>(iter: I) -> SmallDuration
97    where
98        I: Iterator<Item = &'a SmallDuration>,
99    {
100        iter.fold(SmallDuration::default(), |acc, x| acc + *x)
101    }
102}
103
104impl Sum<SmallDuration> for SmallDuration {
105    fn sum<I>(iter: I) -> SmallDuration
106    where
107        I: Iterator<Item = SmallDuration>,
108    {
109        iter.fold(SmallDuration::default(), |acc, x| acc + x)
110    }
111}