File tree Expand file tree Collapse file tree 3 files changed +76
-0
lines changed Expand file tree Collapse file tree 3 files changed +76
-0
lines changed Original file line number Diff line number Diff line change @@ -82,6 +82,26 @@ class CallbackLogHandler : public LogHandler {
82
82
void *m_baton;
83
83
};
84
84
85
+ class RotatingLogHandler : public LogHandler {
86
+ public:
87
+ RotatingLogHandler (size_t size);
88
+
89
+ void Emit (llvm::StringRef message) override ;
90
+ void Dump (llvm::raw_ostream &stream) const ;
91
+
92
+ static std::shared_ptr<RotatingLogHandler> Create (size_t size);
93
+
94
+ private:
95
+ size_t NormalizeIndex (size_t i) const ;
96
+ size_t GetNumMessages () const ;
97
+ size_t GetFirstMessageIndex () const ;
98
+
99
+ std::unique_ptr<std::string[]> m_messages;
100
+ const size_t m_size = 0 ;
101
+ size_t m_next_index = 0 ;
102
+ size_t m_total_count = 0 ;
103
+ };
104
+
85
105
class Log final {
86
106
public:
87
107
// / The underlying type of all log channel enums. Declare them as:
Original file line number Diff line number Diff line change @@ -365,3 +365,37 @@ std::shared_ptr<CallbackLogHandler>
365
365
CallbackLogHandler::Create (lldb::LogOutputCallback callback, void *baton) {
366
366
return std::make_shared<CallbackLogHandler>(callback, baton);
367
367
}
368
+
369
+ RotatingLogHandler::RotatingLogHandler (size_t size)
370
+ : m_messages(std::make_unique<std::string[]>(size)), m_size(size) {}
371
+
372
+ void RotatingLogHandler::Emit (llvm::StringRef message) {
373
+ ++m_total_count;
374
+ const size_t index = m_next_index;
375
+ m_next_index = NormalizeIndex (index + 1 );
376
+ m_messages[index] = message.str ();
377
+ }
378
+
379
+ size_t RotatingLogHandler::NormalizeIndex (size_t i) const { return i % m_size; }
380
+
381
+ size_t RotatingLogHandler::GetNumMessages () const {
382
+ return m_total_count < m_size ? m_total_count : m_size;
383
+ }
384
+
385
+ size_t RotatingLogHandler::GetFirstMessageIndex () const {
386
+ return m_total_count < m_size ? 0 : m_next_index;
387
+ }
388
+
389
+ void RotatingLogHandler::Dump (llvm::raw_ostream &stream) const {
390
+ const size_t start_idx = GetFirstMessageIndex ();
391
+ const size_t stop_idx = start_idx + GetNumMessages ();
392
+ for (size_t i = start_idx; i < stop_idx; ++i) {
393
+ const size_t idx = NormalizeIndex (i);
394
+ stream << m_messages[idx];
395
+ }
396
+ stream.flush ();
397
+ }
398
+
399
+ std::shared_ptr<RotatingLogHandler> RotatingLogHandler::Create (size_t size) {
400
+ return std::make_shared<RotatingLogHandler>(size);
401
+ }
Original file line number Diff line number Diff line change @@ -104,6 +104,13 @@ class LogChannelEnabledTest : public LogChannelTest {
104
104
public:
105
105
void SetUp () override ;
106
106
};
107
+
108
+ static std::string GetDumpAsString (const RotatingLogHandler &handler) {
109
+ std::string buffer;
110
+ llvm::raw_string_ostream stream (buffer);
111
+ handler.Dump (stream);
112
+ return buffer;
113
+ }
107
114
} // end anonymous namespace
108
115
109
116
void LogChannelEnabledTest::SetUp () {
@@ -171,6 +178,21 @@ TEST(LogTest, CallbackLogHandler) {
171
178
EXPECT_EQ (1u , callback_count);
172
179
}
173
180
181
+ TEST (LogHandlerTest, RotatingLogHandler) {
182
+ RotatingLogHandler handler (3 );
183
+
184
+ handler.Emit (" foo" );
185
+ handler.Emit (" bar" );
186
+ EXPECT_EQ (GetDumpAsString (handler), " foobar" );
187
+
188
+ handler.Emit (" baz" );
189
+ handler.Emit (" qux" );
190
+ EXPECT_EQ (GetDumpAsString (handler), " barbazqux" );
191
+
192
+ handler.Emit (" quux" );
193
+ EXPECT_EQ (GetDumpAsString (handler), " bazquxquux" );
194
+ }
195
+
174
196
TEST_F (LogChannelTest, Enable) {
175
197
EXPECT_EQ (nullptr , GetLog (TestChannel::FOO));
176
198
std::string message;
You can’t perform that action at this time.
0 commit comments