]> git.proxmox.com Git - ceph.git/blob - ceph/src/seastar/include/seastar/util/log-impl.hh
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / seastar / include / seastar / util / log-impl.hh
1 /*
2 * This file is open source software, licensed to you under the terms
3 * of the Apache License, Version 2.0 (the "License"). See the NOTICE file
4 * distributed with this work for additional information regarding copyright
5 * ownership. You may not use this file except in compliance with the License.
6 *
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing,
12 * software distributed under the License is distributed on an
13 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14 * KIND, either express or implied. See the License for the
15 * specific language governing permissions and limitations
16 * under the License.
17 */
18 /*
19 * Copyright (C) 2020 Cloudius Systems, Ltd.
20 */
21
22 #pragma once
23
24 #include <iterator>
25
26 /// \addtogroup logging
27 /// @{
28
29 namespace seastar {
30
31 /// \cond internal
32 namespace internal {
33
34 /// A buffer to format log messages into.
35 ///
36 /// It was designed to allow formatting the entire message into it, without any
37 /// intermediary buffers. To minimize the amount of reallocations it supports
38 /// using an external buffer. When this is full it moves to using buffers
39 /// allocated by itself.
40 /// To accommodate the most widely used way of formatting messages -- fmt --,
41 /// it provides an output iterator interface for writing into it.
42 class log_buf {
43 char* _begin;
44 char* _end;
45 char* _current;
46 bool _own_buf;
47 bool _alloc_failure = false;
48 private:
49 void free_buffer() noexcept;
50 void realloc_buffer_and_append(char c) noexcept;
51
52 public:
53 // inserter_iterator is designed like std::back_insert_iterator:
54 // operator*, operator++ and operator++(int) are no-ops,
55 // and all the work happens in operator=, which pushes a character
56 // to the buffer.
57 // The iterator stores no state of its own.
58 //
59 // inserter_iterator is supposed to be used as an output_iterator.
60 // That is, assignment is expected to alternate with incrementing.
61 class inserter_iterator {
62 public:
63 using iterator_category = std::output_iterator_tag;
64 using difference_type = std::ptrdiff_t;
65 using value_type = void;
66 using pointer = void;
67 using reference = void;
68
69 private:
70 log_buf* _buf;
71
72 public:
73 explicit inserter_iterator(log_buf& buf) noexcept : _buf(&buf) { }
74
75 inserter_iterator& operator=(char c) noexcept {
76 if (__builtin_expect(_buf->_current == _buf->_end, false)) {
77 _buf->realloc_buffer_and_append(c);
78 return *this;
79 }
80 *_buf->_current++ = c;
81 return *this;
82 }
83 inserter_iterator& operator*() noexcept {
84 return *this;
85 }
86 inserter_iterator& operator++() noexcept {
87 return *this;
88 }
89 inserter_iterator operator++(int) noexcept {
90 return *this;
91 }
92 };
93
94 /// Default ctor.
95 ///
96 /// Allocates an internal buffer of 512 bytes.
97 log_buf();
98 /// External buffer ctor.
99 ///
100 /// Use the external buffer until its full, then switch to internally
101 /// allocated buffer. log_buf doesn't take ownership of the buffer.
102 log_buf(char* external_buf, size_t size) noexcept;
103 ~log_buf();
104 /// Clear the buffer, setting its position back to the start, but does not
105 /// free any buffers (after this called, size is zero, capacity is unchanged).
106 /// Any existing iterators are invalidated.
107 void clear() { _current = _begin; }
108 /// Create an output iterator which allows writing into the buffer.
109 inserter_iterator back_insert_begin() noexcept { return inserter_iterator(*this); }
110 /// The amount of data written so far.
111 size_t size() const noexcept { return _current - _begin; }
112 /// The size of the buffer.
113 size_t capacity() const noexcept { return _end - _begin; }
114 /// Read only pointer to the buffer.
115 /// Note that the buffer is not guaranteed to be null terminated. The writer
116 /// has to ensure that, should it wish to.
117 const char* data() const noexcept { return _begin; }
118 /// A view of the buffer content.
119 std::string_view view() const noexcept { return std::string_view(_begin, size()); }
120 };
121
122 } // namespace internal
123 /// \endcond
124
125 } // namespace seastar