blob: 972ed6c2438e427a18510dcf83c17a8b5998ac05 [file] [log] [blame]
Brian Silvermanf59fe3f2020-09-22 21:04:09 -07001#ifndef AOS_EVENTS_LOGGING_LZMA_ENCODER_H_
2#define AOS_EVENTS_LOGGING_LZMA_ENCODER_H_
3
Tyler Chatow7df60832021-07-15 21:18:36 -07004#include <condition_variable>
5#include <mutex>
6#include <thread>
Brian Silvermanf59fe3f2020-09-22 21:04:09 -07007
Tyler Chatow7df60832021-07-15 21:18:36 -07008#include "absl/types/span.h"
Brian Silvermanf59fe3f2020-09-22 21:04:09 -07009#include "aos/containers/resizeable_buffer.h"
10#include "aos/events/logging/buffer_encoder.h"
11#include "aos/events/logging/logger_generated.h"
Tyler Chatow7df60832021-07-15 21:18:36 -070012#include "flatbuffers/flatbuffers.h"
13#include "lzma.h"
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070014
15namespace aos::logger {
16
17// Encodes buffers using liblzma.
18class LzmaEncoder final : public DetachedBufferEncoder {
19 public:
20 // Initializes the LZMA stream and encoder.
21 explicit LzmaEncoder(uint32_t compression_preset);
Austin Schuhc41603c2020-10-11 16:17:37 -070022 LzmaEncoder(const LzmaEncoder &) = delete;
23 LzmaEncoder(LzmaEncoder &&other) = delete;
24 LzmaEncoder &operator=(const LzmaEncoder &) = delete;
25 LzmaEncoder &operator=(LzmaEncoder &&other) = delete;
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070026 // Gracefully shuts down the encoder.
27 ~LzmaEncoder() final;
28
29 void Encode(flatbuffers::DetachedBuffer &&in) final;
30 void Finish() final;
31 void Clear(int n) final;
32 std::vector<absl::Span<const uint8_t>> queue() const final;
33 size_t queued_bytes() const final;
34 size_t total_bytes() const final { return total_bytes_; }
35 size_t queue_size() const final { return queue_.size(); }
36
37 private:
Austin Schuhc07d4fb2020-12-13 16:40:04 -080038 static constexpr size_t kEncodedBufferSizeBytes{4096};
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070039
40 void RunLzmaCode(lzma_action action);
41
42 lzma_stream stream_;
43 uint32_t compression_preset_;
44 std::vector<ResizeableBuffer> queue_;
45 bool finished_ = false;
46 // Total bytes that resulted from encoding raw data since the last call to
47 // Reset.
48 size_t total_bytes_ = 0;
49};
50
51// Decompresses data with liblzma.
52class LzmaDecoder final : public DataDecoder {
53 public:
54 explicit LzmaDecoder(std::string_view filename);
Austin Schuhc41603c2020-10-11 16:17:37 -070055 LzmaDecoder(const LzmaDecoder &) = delete;
56 LzmaDecoder(LzmaDecoder &&other) = delete;
57 LzmaDecoder &operator=(const LzmaDecoder &) = delete;
58 LzmaDecoder &operator=(LzmaDecoder &&other) = delete;
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070059 ~LzmaDecoder();
60
61 size_t Read(uint8_t *begin, uint8_t *end) final;
62
63 private:
64 // Size of temporary buffer to use.
65 static constexpr size_t kBufSize{256 * 1024};
66
67 // Temporary buffer for storing compressed data.
68 ResizeableBuffer compressed_data_;
69 // Used for reading data from the file.
70 DummyDecoder dummy_decoder_;
71 // Stream for decompression.
72 lzma_stream stream_;
73 // The current action. This is LZMA_RUN until we've run out of data to read
74 // from the file.
75 lzma_action action_ = LZMA_RUN;
76 // Flag that represents whether or not all the data from the file has been
77 // successfully decoded.
78 bool finished_ = false;
Austin Schuh3bd4c402020-11-06 18:19:06 -080079
80 // Filename we are decompressing.
81 std::string filename_;
Brian Silvermanf59fe3f2020-09-22 21:04:09 -070082};
83
Tyler Chatow7df60832021-07-15 21:18:36 -070084// Decompresses data with liblzma in a new thread, up to a maximum queue
85// size. Calls to Read() will return data from the queue if available,
86// or block until more data is queued or the stream finishes.
87class ThreadedLzmaDecoder : public DataDecoder {
88 public:
89 explicit ThreadedLzmaDecoder(std::string_view filename);
90 ThreadedLzmaDecoder(const ThreadedLzmaDecoder &) = delete;
91 ThreadedLzmaDecoder &operator=(const ThreadedLzmaDecoder &) = delete;
92
93 ~ThreadedLzmaDecoder();
94
95 size_t Read(uint8_t *begin, uint8_t *end) final;
96
97 private:
98 static constexpr size_t kBufSize{256 * 1024};
99 static constexpr size_t kQueueSize{8};
100
101 LzmaDecoder decoder_;
102
103 // Queue of decompressed data to return on calls to Read
104 std::vector<ResizeableBuffer> decoded_queue_;
105
106 // Mutex to control access to decoded_queue_.
107 std::mutex decode_mutex_;
108 std::condition_variable continue_decoding_;
109 std::condition_variable queue_filled_;
110
111 bool finished_ = false;
112
113 std::thread decode_thread_;
114};
115
Brian Silvermanf59fe3f2020-09-22 21:04:09 -0700116} // namespace aos::logger
117
118#endif // AOS_EVENTS_LOGGING_LZMA_ENCODER_H_