summaryrefslogtreecommitdiffstats
path: root/src/lib/util/stopwatch.h
blob: 304e285e64bc82ff3d230270758611e1054ce25c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
// Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.

#ifndef STOPWATCH_H
#define STOPWATCH_H

#include <boost/noncopyable.hpp>
#include <boost/date_time/posix_time/posix_time.hpp>

namespace isc {
namespace util {

/// @brief Forward declaration to the @c Stopwatch implementation.
class StopwatchImpl;

/// @brief Utility class to measure code execution times.
///
/// The API of this class is based on the use cases of a stopwatch. It is
/// used to measure time spent executing portions of the code. The typical
/// use case for the @c Stopwatch is to measure the time spent invoking
/// callouts in hooks library. This provides means for diagnosing the
/// server's performance degradations when hooks libraries are in use.
///
/// This class exposes functions like @c start, @c stop and @c reset which
/// behave in the same way as a stopwatch used to measure time for sport
/// activities.
///
/// It is possible to measure the cumulative execution time by invoking
/// @c start and @c stop consecutively. The total measured time will be
/// a sum of durations between the invocations of respective starts and
/// stops.
class Stopwatch : boost::noncopyable {
public:

    /// @brief Constructor.
    ///
    /// @param autostart Indicates if the stopwatch should be initialized to
    /// the "started" state. In this state the stopwatch is measuring the time
    /// since it has been started (object has been constructed in this case.
    /// If the parameter is set to false (default value), the
    /// @c Stopwatch::start must be called to start time measurement.
    Stopwatch(const bool autostart = true);

    /// @brief Destructor.
    ///
    /// Destroys the implementation instance.
    ~Stopwatch();

    /// @brief Starts the stopwatch.
    ///
    /// Sets the stopwatch to the "started" state. In this state the stopwatch
    /// is measuring the duration since @c Stopwatch::start has been invoked.
    ///
    //// This method is no-op if the stopwatch is already in the "started"
    /// state.
    void start();

    /// @brief Stops the stopwatch.
    ///
    /// Sets the stopwatch to the "stopped" state. The stopwatch stops the time
    /// measurement and records the duration between the last stopwatch start
    /// and the stop invocation. It also updates the total measured duration,
    /// i.e. the sum of durations between all start/stop invocations. Both
    /// values can be retrieved using @c Stopwatch::getLastDuration and
    /// @c Stopwatch::getTotalDuration respectively, or their variants.
    ///
    /// This method is no-op if the stopwatch is already in the "stopped" state.
    void stop();

    /// @brief Resets the stopwatch.
    ///
    /// It resets the stopwatch to the initial state. In this state, the last
    /// measured duration and the total duration is set to 0. The stopwatch
    /// is set to the "stopped" state.
    void reset();

    /// @brief Retrieves last measured duration.
    ///
    /// If the stopwatch is in the "stopped" state this method retrieves the
    /// duration between the last start and stop. If the stopwatch is in the
    /// "started" state, the retrieved duration is the duration between the
    /// last start of the stopwatch and the current time.
    boost::posix_time::time_duration getLastDuration() const;

    /// @brief Retrieves total measured duration.
    ///
    /// If the stopwatch is in the "stopped" state this method retrieves the
    /// total duration between all starts and stops invoked  during the
    /// lifetime of the object or since the last reset. If the stopwatch is
    /// in the "started" state, the returned is the sum of all durations
    /// between respective starts and stops, and the duration since the
    /// stopwatch has been last started and the current time.
    boost::posix_time::time_duration getTotalDuration() const;

    /// @brief Retrieves the last measured duration in milliseconds.
    long getLastMilliseconds() const;

    /// @brief Retrieves the total measured duration in milliseconds.
    long getTotalMilliseconds() const;

    /// @brief Retrieves the last measured duration in microseconds.
    long getLastMicroseconds() const;

    /// @brief Retrieves the total measured duration in microseconds.
    long getTotalMicroseconds() const;

    /// @brief Returns the last measured duration in the format directly
    /// usable in log messages.
    std::string logFormatLastDuration() const;

    /// @brief Returns the total measured duration in the format directly
    /// usable in the log messages.
    std::string logFormatTotalDuration() const;

private:

    /// @brief Pointer to the @c StopwatchImpl.
    StopwatchImpl* impl_;

};

}
}

#endif // STOPWATCH_H