xref: /aosp_15_r20/external/icing/icing/util/clock.h (revision 8b6cd535a057e39b3b86660c4aa06c99747c2136)
1 // Copyright (C) 2019 Google LLC
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 
15 #ifndef ICING_UTIL_CLOCK_H_
16 #define ICING_UTIL_CLOCK_H_
17 
18 #include <cstdint>
19 #include <functional>
20 #include <memory>
21 
22 namespace icing {
23 namespace lib {
24 
25 // Returns the current steady time in nanoseconds. The steady clock is different
26 // from the system clock. It's monotonic and never returns a lower value than a
27 // previous call, while a system clock can be occasionally adjusted.
28 int64_t GetSteadyTimeNanoseconds();
29 
30 // Returns the current steady time in Milliseconds. The steady clock is
31 // different from the system clock. It's monotonic and never returns a lower
32 // value than a previous call, while a system clock can be occasionally
33 // adjusted.
34 int64_t GetSteadyTimeMilliseconds();
35 
36 // Used to calculate the elapsed time.
37 class Timer {
38  public:
39   // Creates and starts the timer.
Timer()40   Timer() : start_timestamp_nanoseconds_(GetSteadyTimeNanoseconds()) {}
41 
42   virtual ~Timer() = default;
43 
44   // Returns the elapsed time from when timer started.
GetElapsedMilliseconds()45   virtual int64_t GetElapsedMilliseconds() const {
46     return GetElapsedNanoseconds() / 1000000;
47   }
48 
49   // Returns the elapsed time from when timer started.
GetElapsedNanoseconds()50   virtual int64_t GetElapsedNanoseconds() const {
51     return GetSteadyTimeNanoseconds() - start_timestamp_nanoseconds_;
52   }
53 
54  private:
55   int64_t start_timestamp_nanoseconds_;
56 };
57 
58 // Wrapper around real-time clock functions. This is separated primarily so
59 // tests can override this clock and inject it into the class under test.
60 class Clock {
61  public:
62   virtual ~Clock() = default;
63 
64   // Returns the current time in milliseconds, it's guaranteed that the return
65   // value is non-negative.
66   virtual int64_t GetSystemTimeMilliseconds() const;
67 
68   // Returns a timer used to calculate the elapsed time. The timer starts when
69   // the method returns.
70   virtual std::unique_ptr<Timer> GetNewTimer() const;
71 };
72 
73 // A convenient RAII timer class that receives a callback. Upon destruction, the
74 // callback will be called with the elapsed milliseconds or nanoseconds passed
75 // as a parameter, depending on which Unit was passed in the constructor.
76 class ScopedTimer {
77  public:
78   enum class Unit { kMillisecond, kNanosecond };
79 
80   ScopedTimer(std::unique_ptr<Timer> timer,
81               std::function<void(int64_t)> callback,
82               Unit unit = Unit::kMillisecond)
timer_(std::move (timer))83       : timer_(std::move(timer)), callback_(std::move(callback)), unit_(unit) {}
84 
~ScopedTimer()85   ~ScopedTimer() {
86     if (unit_ == Unit::kMillisecond) {
87       callback_(timer_->GetElapsedMilliseconds());
88     } else {
89       callback_(timer_->GetElapsedNanoseconds());
90     }
91   }
92 
timer()93   const Timer& timer() const { return *timer_; }
94 
95  private:
96   std::unique_ptr<Timer> timer_;
97   std::function<void(int64_t)> callback_;
98   Unit unit_;
99 };
100 
101 }  // namespace lib
102 }  // namespace icing
103 
104 #endif  // ICING_UTIL_CLOCK_H_
105