JDevlieghere updated this revision to Diff 437695.
JDevlieghere added a comment.

- Use dynamic array instead of vector.
- Rebase


CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D127937/new/

https://reviews.llvm.org/D127937

Files:
  lldb/include/lldb/Utility/Log.h
  lldb/source/Utility/Log.cpp
  lldb/unittests/Utility/LogTest.cpp

Index: lldb/unittests/Utility/LogTest.cpp
===================================================================
--- lldb/unittests/Utility/LogTest.cpp
+++ lldb/unittests/Utility/LogTest.cpp
@@ -104,6 +104,13 @@
 public:
   void SetUp() override;
 };
+
+static std::string GetDumpAsString(const RotatingLogHandler &handler) {
+  std::string buffer;
+  llvm::raw_string_ostream stream(buffer);
+  handler.Dump(stream);
+  return stream.str();
+}
 } // end anonymous namespace
 
 void LogChannelEnabledTest::SetUp() {
@@ -171,6 +178,21 @@
   EXPECT_EQ(1u, callback_count);
 }
 
+TEST(LogHandlerTest, RotatingLogHandler) {
+  RotatingLogHandler handler(3);
+
+  handler.Emit("foo");
+  handler.Emit("bar");
+  EXPECT_EQ(GetDumpAsString(handler), "foobar");
+
+  handler.Emit("baz");
+  handler.Emit("qux");
+  EXPECT_EQ(GetDumpAsString(handler), "barbazqux");
+
+  handler.Emit("quux");
+  EXPECT_EQ(GetDumpAsString(handler), "bazquxquux");
+}
+
 TEST_F(LogChannelTest, Enable) {
   EXPECT_EQ(nullptr, GetLog(TestChannel::FOO));
   std::string message;
Index: lldb/source/Utility/Log.cpp
===================================================================
--- lldb/source/Utility/Log.cpp
+++ lldb/source/Utility/Log.cpp
@@ -365,3 +365,37 @@
 CallbackLogHandler::Create(lldb::LogOutputCallback callback, void *baton) {
   return std::make_shared<CallbackLogHandler>(callback, baton);
 }
+
+RotatingLogHandler::RotatingLogHandler(size_t size)
+    : m_messages(std::make_unique<std::string[]>(size)), m_size(size) {}
+
+void RotatingLogHandler::Emit(llvm::StringRef message) {
+  ++m_total_count;
+  const size_t index = m_next_index;
+  m_next_index = NormalizeIndex(index + 1);
+  m_messages[index] = message.str();
+}
+
+size_t RotatingLogHandler::NormalizeIndex(size_t i) const { return i % m_size; }
+
+size_t RotatingLogHandler::GetNumMessages() const {
+  return m_total_count < m_size ? m_total_count : m_size;
+}
+
+size_t RotatingLogHandler::GetFirstMessageIndex() const {
+  return m_total_count < m_size ? 0 : m_next_index;
+}
+
+void RotatingLogHandler::Dump(llvm::raw_ostream &stream) const {
+  const size_t start_idx = GetFirstMessageIndex();
+  const size_t stop_idx = start_idx + GetNumMessages();
+  for (size_t i = start_idx; i < stop_idx; ++i) {
+    const size_t idx = NormalizeIndex(i);
+    stream << m_messages[idx];
+  }
+  stream.flush();
+}
+
+std::shared_ptr<RotatingLogHandler> RotatingLogHandler::Create(size_t size) {
+  return std::make_shared<RotatingLogHandler>(size);
+}
Index: lldb/include/lldb/Utility/Log.h
===================================================================
--- lldb/include/lldb/Utility/Log.h
+++ lldb/include/lldb/Utility/Log.h
@@ -82,6 +82,26 @@
   void *m_baton;
 };
 
+class RotatingLogHandler : public LogHandler {
+public:
+  RotatingLogHandler(size_t size);
+
+  void Emit(llvm::StringRef message) override;
+  void Dump(llvm::raw_ostream &stream) const;
+
+  static std::shared_ptr<RotatingLogHandler> Create(size_t size);
+
+private:
+  size_t NormalizeIndex(size_t i) const;
+  size_t GetNumMessages() const;
+  size_t GetFirstMessageIndex() const;
+
+  std::unique_ptr<std::string[]> m_messages;
+  const size_t m_size = 0;
+  size_t m_next_index = 0;
+  size_t m_total_count = 0;
+};
+
 class Log final {
 public:
   /// The underlying type of all log channel enums. Declare them as:
_______________________________________________
lldb-commits mailing list
lldb-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits

Reply via email to