Branch data Line data Source code
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 : : #include "./base/cached_timestamp.h" 25 : : 26 : : #include <cstdio> 27 : : 28 : : namespace vlink { 29 : : 30 : 15 : CachedTimestamp::CachedTimestamp() = default; 31 : : 32 : 15 : CachedTimestamp::~CachedTimestamp() = default; 33 : : 34 : 1845 : std::string_view CachedTimestamp::get(const char* format, bool use_utc) { 35 : 1845 : auto now = std::chrono::system_clock::now(); 36 [ + - ]: 1850 : auto now_ms = std::chrono::duration_cast<std::chrono::milliseconds>(now.time_since_epoch()); 37 : : 38 : 1850 : int64_t sec = now_ms.count() / 1000; 39 : 1849 : int ms = now_ms.count() % 1000; 40 : : 41 [ + - ]: 1849 : std::lock_guard lock(mtx_); 42 : : 43 : 1851 : int64_t cached_sec = last_sec_.load(std::memory_order_relaxed); 44 : : 45 [ + + + - : 1851 : if VLIKELY (sec == cached_sec && is_utc_ == use_utc) { + + ] 46 [ + - ]: 1835 : update_milliseconds(ms); 47 : 1835 : return std::string_view(buffer_, buffer_len_); 48 : : } 49 : : 50 [ + - ]: 16 : format_full_timestamp(format, now, use_utc, ms); 51 : : 52 : 16 : last_sec_.store(sec, std::memory_order_release); 53 : 16 : is_utc_ = use_utc; 54 : : 55 : 16 : return std::string_view(buffer_, buffer_len_); 56 : 1851 : } 57 : : 58 : 16 : void CachedTimestamp::format_full_timestamp(const char* format, std::chrono::system_clock::time_point now, bool use_utc, 59 : : int ms) { 60 : 16 : std::time_t now_time_t = std::chrono::system_clock::to_time_t(now); 61 : 16 : std::tm now_tm{}; 62 : : 63 : : #if defined(_WIN32) 64 : : 65 : : if (use_utc) { 66 : : gmtime_s(&now_tm, &now_time_t); 67 : : } else { 68 : : localtime_s(&now_tm, &now_time_t); 69 : : } 70 : : #else 71 : : 72 [ + + ]: 16 : if (use_utc) { 73 : 2 : gmtime_r(&now_time_t, &now_tm); 74 : : } else { 75 : 14 : localtime_r(&now_time_t, &now_tm); 76 : : } 77 : : #endif 78 : : 79 : 16 : int len = std::snprintf(buffer_, sizeof(buffer_), format, now_tm.tm_mon + 1, now_tm.tm_mday, now_tm.tm_hour, 80 : : now_tm.tm_min, now_tm.tm_sec, ms); 81 : : 82 [ + - - + : 16 : if VUNLIKELY (len < 3 || len >= static_cast<int>(sizeof(buffer_))) { - + ] 83 : 0 : buffer_len_ = 0; 84 : 0 : ms_offset_ = 0; 85 : 0 : return; 86 : : } 87 : : 88 : 16 : buffer_len_ = static_cast<size_t>(len); 89 : 16 : ms_offset_ = buffer_len_ - 3; 90 : : } 91 : : 92 : 1835 : void CachedTimestamp::update_milliseconds(int ms) { 93 : 1835 : char* ms_ptr = buffer_ + ms_offset_; 94 : : 95 : 1835 : ms_ptr[0] = '0' + (ms / 100); 96 : 1835 : ms_ptr[1] = '0' + (ms / 10) % 10; 97 : 1835 : ms_ptr[2] = '0' + (ms % 10); 98 : 1835 : } 99 : : 100 : : } // namespace vlink