1 /* 2 * Copyright (C) 2020 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #pragma once 18 19 #include <sys/types.h> 20 21 #include "LogWriter.h" 22 #include "SerializedData.h" 23 #include "SerializedLogEntry.h" 24 25 class SerializedLogChunk { 26 public: SerializedLogChunk(size_t size)27 explicit SerializedLogChunk(size_t size) : contents_(size) {} 28 SerializedLogChunk(SerializedLogChunk&& other) noexcept = default; 29 ~SerializedLogChunk(); 30 31 void Compress(); 32 void IncReaderRefCount(); 33 void DecReaderRefCount(); 34 35 // Must have no readers referencing this. Return true if there are no logs left in this chunk. 36 bool ClearUidLogs(uid_t uid, log_id_t log_id, LogStatistics* stats); 37 38 bool CanLog(size_t len); 39 SerializedLogEntry* Log(uint64_t sequence, log_time realtime, uid_t uid, pid_t pid, pid_t tid, 40 const char* msg, uint16_t len); 41 42 // If this buffer has been compressed, we only consider its compressed size when accounting for 43 // memory consumption for pruning. This is since the uncompressed log is only by used by 44 // readers, and thus not a representation of how much these logs cost to keep in memory. PruneSize()45 size_t PruneSize() const { 46 return sizeof(*this) + (compressed_log_.size() ?: contents_.size()); 47 } 48 FinishWriting()49 void FinishWriting() { 50 writer_active_ = false; 51 Compress(); 52 if (reader_ref_count_ == 0) { 53 contents_.Resize(0); 54 } 55 } 56 log_entry(int offset)57 const SerializedLogEntry* log_entry(int offset) const { 58 return reinterpret_cast<const SerializedLogEntry*>(data() + offset); 59 } data()60 const uint8_t* data() const { return contents_.data(); } write_offset()61 int write_offset() const { return write_offset_; } highest_sequence_number()62 uint64_t highest_sequence_number() const { return highest_sequence_number_; } 63 64 // Exposed for testing reader_ref_count()65 uint32_t reader_ref_count() const { return reader_ref_count_; } 66 67 private: 68 // The decompressed contents of this log buffer. Deallocated when the ref_count reaches 0 and 69 // writer_active_ is false. 70 SerializedData contents_; 71 int write_offset_ = 0; 72 uint32_t reader_ref_count_ = 0; 73 bool writer_active_ = true; 74 uint64_t highest_sequence_number_ = 1; 75 SerializedData compressed_log_; 76 }; 77