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 A low-overhead, thread-safe, formatted timestamp generator for log output.
27 *
28 * @details
29 * @c CachedTimestamp generates a human-readable timestamp string (e.g.
30 * @c "03-18 14:30:01.042") without formatting the full string every call.
31 * Instead it caches the date-and-second part and only updates the millisecond
32 * field on sub-second increments, significantly reducing the number of expensive
33 * @c strftime / @c localtime_r calls under high log throughput.
34 *
35 * The caching strategy:
36 * - The full timestamp (up to seconds) is formatted only once per second.
37 * The second boundary is detected via an @c std::atomic<int64_t> storing the
38 * last formatted Unix second. Access is serialized so only one thread
39 * updates the shared cache at a time.
40 * - The millisecond field is patched in-place by @c update_milliseconds()
41 * without reformatting the entire string.
42 * - A @c std::mutex protects the shared buffer while formatting or patching
43 * the millisecond field.
44 *
45 * @note
46 * - The internal buffer is 32 bytes, which is sufficient for most strftime
47 * format strings. Using a format that produces a longer string results in
48 * truncated output.
49 * - The default format @c "%02d-%02d %02d:%02d:%02d.%03d" produces
50 * @c "MM-DD HH:MM:SS.mmm" (18 characters). Do not include year if character
51 * count matters.
52 * - This class is used internally by the VLink Logger. There is normally no need
53 * to instantiate it directly in application code.
54 *
55 * @par Example
56 * @code
57 * vlink::CachedTimestamp ts;
58 * for (int i = 0; i < 1000; ++i) {
59 * std::string_view sv = ts.get();
60 * write_to_log(sv); // sv points to internal buffer; copy if needed
61 * }
62 * @endcode
63 */
64
65#pragma once
66
67#include <atomic>
68#include <chrono>
69#include <cstdint>
70#include <mutex>
71#include <string_view>
72
73#include "./macros.h"
74
75namespace vlink {
76
77/**
78 * @class CachedTimestamp
79 * @brief Cached, thread-safe formatted timestamp generator.
80 *
81 * @details
82 * Reformats only the seconds portion of the timestamp once per second,
83 * patching the milliseconds in-place for all other calls. Used internally
84 * by the Logger to stamp each log line.
85 */
87 public:
88 /**
89 * @brief Constructs a @c CachedTimestamp with an empty internal cache.
90 *
91 * @details The cache is populated on the first call to @c get().
92 */
94
95 /**
96 * @brief Destructor.
97 */
99
100 /**
101 * @brief Returns a @c std::string_view of the current formatted timestamp.
102 *
103 * @details
104 * The view points into the internal 32-byte buffer. It is valid until the
105 * next call to @c get() from any thread that shares this instance. Copy the
106 * string if a persistent value is needed.
107 *
108 * The default format produces strings of the form @c "MM-DD HH:MM:SS.mmm".
109 *
110 * @param format A @c snprintf-compatible format string. Must include exactly
111 * one @c %03d placeholder for milliseconds. The resulting string
112 * must fit within 31 characters.
113 * Default: @c "%02d-%02d %02d:%02d:%02d.%03d"
114 * @param use_utc If @c true, formats in UTC; if @c false (default), in local time.
115 * @return A @c std::string_view into the internal buffer with the current timestamp.
116 *
117 * @note
118 * The returned view is invalidated on the next call from any thread that
119 * holds a reference to this @c CachedTimestamp instance.
120 */
121 [[nodiscard]] std::string_view get(const char* format = "%02d-%02d %02d:%02d:%02d.%03d", bool use_utc = false);
122
123 private:
124 void format_full_timestamp(const char* format, std::chrono::system_clock::time_point now, bool use_utc, int ms);
125
126 void update_milliseconds(int ms);
127
128 alignas(64) std::atomic<int64_t> last_sec_{0};
129 std::mutex mtx_;
130 char buffer_[32]{};
131 size_t buffer_len_{0};
132 size_t ms_offset_{0};
133 bool is_utc_{false};
134};
135
136} // namespace vlink
Platform-independent macro definitions for the VLink library.
#define VLINK_EXPORT
定义 macros.h:85