VLink  2.0.0
A high-performance communication middleware
cached_timestamp.h
浏览该文件的文档.
1 /*
2  * Copyright (C) 2026 by Thun Lu. All rights reserved.
3  * Author: Thun Lu <thun.lu@zohomail.cn>
4  * Repo: https://github.com/thun-res/vlink
5  * _ __ __ _ __
6  * | | / / / / (_) ____ / /__
7  * | | / / / / / / / __ \ / //_/
8  * | |/ / / /___ / / / / / / / ,<
9  * |___/ /_____/ /_/ /_/ /_/ /_/|_|
10  *
11  * Licensed under the Apache License, Version 2.0 (the "License");
12  * you may not use this file except in compliance with the License.
13  * You may obtain a copy of the License at
14  *
15  * http://www.apache.org/licenses/LICENSE-2.0
16  *
17  * Unless required by applicable law or agreed to in writing, software
18  * distributed under the License is distributed on an "AS IS" BASIS,
19  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20  * See the License for the specific language governing permissions and
21  * limitations under the License.
22  */
23 
24 /**
25  * @file cached_timestamp.h
26  * @brief Sub-second-cached timestamp string generator used by the VLink logger hot path.
27  *
28  * @details
29  * @c CachedTimestamp renders a wall-clock or UTC timestamp into a stable internal buffer and
30  * patches only the millisecond suffix when the seconds field has not advanced. This avoids the
31  * repeated @c snprintf / @c localtime_r round trip that dominates naive per-line logger output.
32  *
33  * @par Resolution and field layout
34  *
35  * | Field | Width | Source |
36  * | ----------------------------- | ----- | ------------------------------------- |
37  * | Month | 2 | @c %02d |
38  * | Day | 2 | @c %02d |
39  * | Hour | 2 | @c %02d |
40  * | Minute | 2 | @c %02d |
41  * | Second | 2 | @c %02d |
42  * | Millisecond (in-place patch) | 3 | @c %03d, last three chars of buffer |
43  *
44  * The default format @c "%02d-%02d @c %02d:%02d:%02d.%03d" produces 18 characters such as
45  * @c "03-18 14:30:01.042". The internal buffer is 32 bytes; longer formats are dropped.
46  *
47  * @par Example
48  * @code
49  * vlink::CachedTimestamp ts;
50  * for (int i = 0; i < 1000; ++i) {
51  * // Wall clock (local time) - patched in place on the same second.
52  * std::string_view local = ts.get();
53  * // UTC variant on demand:
54  * std::string_view utc = ts.get("%02d-%02d %02d:%02d:%02d.%03d", true);
55  * write_to_log(local);
56  * }
57  * @endcode
58  *
59  * @note Used internally by @c vlink::Logger. Application code rarely needs to construct one
60  * directly; doing so is harmless and inexpensive.
61  */
62 
63 #pragma once
64 
65 #include <atomic>
66 #include <chrono>
67 #include <cstdint>
68 #include <mutex>
69 #include <string_view>
70 
71 #include "./macros.h"
72 
73 namespace vlink {
74 
75 /**
76  * @class CachedTimestamp
77  * @brief Mutable cached generator for short formatted timestamps.
78  *
79  * @details
80  * Holds a 32-byte buffer protected by a mutex plus an atomic last-second counter so concurrent
81  * @c get calls share a single formatted prefix and only the millisecond suffix is rewritten.
82  * The first call seeds the cache; subsequent same-second calls patch only the trailing three
83  * characters in place.
84  */
86  public:
87  /**
88  * @brief Constructs the generator with an empty internal cache.
89  *
90  * @details
91  * The cache is populated lazily on the first @c get call.
92  */
94 
95  /**
96  * @brief Destructor.
97  */
99 
100  /**
101  * @brief Returns a view of the current formatted timestamp.
102  *
103  * @details
104  * The returned view points into the internal 32-byte buffer. It is invalidated by the next
105  * call to @c get on any thread sharing this instance. The format must end with a 3-digit
106  * millisecond field because the cache patches the last three bytes in place; the entire
107  * formatted string must fit within 31 characters. Switching @p format or @p use_utc forces
108  * a full reformat on the next second boundary.
109  *
110  * @param format @c snprintf format consuming six @c int arguments in this order:
111  * month, day, hour, minute, second, milliseconds. Default:
112  * @c "%02d-%02d @c %02d:%02d:%02d.%03d".
113  * @param use_utc @c true for UTC formatting; @c false for local time. Default: @c false.
114  * @return @c std::string_view over the rendered timestamp.
115  */
116  [[nodiscard]] std::string_view get(const char* format = "%02d-%02d %02d:%02d:%02d.%03d", bool use_utc = false);
117 
118  private:
119  void format_full_timestamp(const char* format, std::chrono::system_clock::time_point now, bool use_utc, int ms);
120 
121  void update_milliseconds(int ms);
122 
123  alignas(64) std::atomic<int64_t> last_sec_{0};
124  std::mutex mtx_;
125  char buffer_[32]{};
126  size_t buffer_len_{0};
127  size_t ms_offset_{0};
128  bool is_utc_{false};
129 };
130 
131 } // namespace vlink
Cross-platform macros for visibility, branch hints, copy prevention, singletons and string helpers.
#define VLINK_EXPORT
Definition: macros.h:81