Skip to content

Commit 59caa7a

Browse files
author
Tom Cherry
committed
logd: always compress SerializedLogChunk in FinishWriting()
When calculating the space used for pruning, if a log chunk is compressed, that size is used otherwise the uncompressed size is used. This is intended to reach a steady state where 1/4 of the log buffer is the uncompressed log chunk that is being written to and the other 3/4 of the log buffer is compressed logs. If we wait until there are no readers referencing the log chunk before compressing it, we end up with 2 uncompressed logs (the one that was just filled, that readers are still referencing, and the new one that was allocated to fit the most recent log), which take up 1/2 of the log buffer's allotted size and will thus cause prune to delete more compressed logs than it should. Instead, we should always compress the log chunks in FinishWriting() such that the compressed size will always be used for log chunks other than the one that is not actively written to. Decompressed logs due to readers are ephemeral by their nature and thus don't add to the log buffer size for pruning. Test: observe that log buffers can be filled in the presence of a reader. Change-Id: Ie21ccff032e41c4a0e51710cc435c5ab316563cb
1 parent b371af9 commit 59caa7a

5 files changed

+18
-20
lines changed

logd/SerializedFlushToState.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ SerializedFlushToState::SerializedFlushToState(uint64_t start, LogMask log_mask)
3131
SerializedFlushToState::~SerializedFlushToState() {
3232
log_id_for_each(i) {
3333
if (log_positions_[i]) {
34-
log_positions_[i]->buffer_it->DecReaderRefCount(true);
34+
log_positions_[i]->buffer_it->DecReaderRefCount();
3535
}
3636
}
3737
}
@@ -78,7 +78,7 @@ void SerializedFlushToState::AddMinHeapEntry(log_id_t log_id) {
7878
logs_needed_from_next_position_[log_id] = true;
7979
} else {
8080
// Otherwise, if there is another buffer piece, move to that and do the same check.
81-
buffer_it->DecReaderRefCount(true);
81+
buffer_it->DecReaderRefCount();
8282
++buffer_it;
8383
buffer_it->IncReaderRefCount();
8484
log_positions_[log_id]->read_offset = 0;
@@ -134,7 +134,7 @@ void SerializedFlushToState::Prune(log_id_t log_id,
134134
}
135135

136136
// // Decrease the ref count since we're deleting our reference.
137-
buffer_it->DecReaderRefCount(false);
137+
buffer_it->DecReaderRefCount();
138138

139139
// Delete in the reference.
140140
log_positions_[log_id].reset();

logd/SerializedLogBuffer.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ void SerializedLogBuffer::RemoveChunkFromStats(log_id_t log_id, SerializedLogChu
123123
stats_->Subtract(entry->ToLogStatisticsElement(log_id));
124124
read_offset += entry->total_len();
125125
}
126-
chunk.DecReaderRefCount(false);
126+
chunk.DecReaderRefCount();
127127
}
128128

129129
void SerializedLogBuffer::NotifyReadersOfPrune(

logd/SerializedLogChunk.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,6 @@ void SerializedLogChunk::Compress() {
3131
<< " size used: " << write_offset_
3232
<< " compressed size: " << compressed_log_.size();
3333
}
34-
contents_.Resize(0);
3534
}
3635

3736
// TODO: Develop a better reference counting strategy to guard against the case where the writer is
@@ -44,13 +43,13 @@ void SerializedLogChunk::IncReaderRefCount() {
4443
CompressionEngine::GetInstance().Decompress(compressed_log_, contents_);
4544
}
4645

47-
void SerializedLogChunk::DecReaderRefCount(bool compress) {
46+
void SerializedLogChunk::DecReaderRefCount() {
4847
CHECK_NE(reader_ref_count_, 0U);
4948
if (--reader_ref_count_ != 0) {
5049
return;
5150
}
52-
if (compress && !writer_active_) {
53-
Compress();
51+
if (!writer_active_) {
52+
contents_.Resize(0);
5453
}
5554
}
5655

@@ -83,18 +82,19 @@ bool SerializedLogChunk::ClearUidLogs(uid_t uid, log_id_t log_id, LogStatistics*
8382
}
8483

8584
if (new_write_offset == 0) {
86-
DecReaderRefCount(false);
85+
DecReaderRefCount();
8786
return true;
8887
}
8988

90-
// Clear the old compressed logs and set write_offset_ appropriately for DecReaderRefCount()
91-
// to compress the new partially cleared log.
89+
// Clear the old compressed logs and set write_offset_ appropriately to compress the new
90+
// partially cleared log.
9291
if (new_write_offset != write_offset_) {
9392
compressed_log_.Resize(0);
9493
write_offset_ = new_write_offset;
94+
Compress();
9595
}
9696

97-
DecReaderRefCount(true);
97+
DecReaderRefCount();
9898

9999
return false;
100100
}

logd/SerializedLogChunk.h

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,7 @@ class SerializedLogChunk {
3030

3131
void Compress();
3232
void IncReaderRefCount();
33-
// Decrease the reader ref count and compress the log if appropriate. `compress` should only be
34-
// set to false in the case that the log buffer will be deleted afterwards.
35-
void DecReaderRefCount(bool compress);
33+
void DecReaderRefCount();
3634

3735
// Must have no readers referencing this. Return true if there are no logs left in this chunk.
3836
bool ClearUidLogs(uid_t uid, log_id_t log_id, LogStatistics* stats);
@@ -50,8 +48,9 @@ class SerializedLogChunk {
5048

5149
void FinishWriting() {
5250
writer_active_ = false;
51+
Compress();
5352
if (reader_ref_count_ == 0) {
54-
Compress();
53+
contents_.Resize(0);
5554
}
5655
}
5756

logd/SerializedLogChunkTest.cpp

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,7 @@ TEST(SerializedLogChunk, three_logs) {
113113
TEST(SerializedLogChunk, catch_DecCompressedRef_CHECK) {
114114
size_t chunk_size = 10 * 4096;
115115
auto chunk = SerializedLogChunk{chunk_size};
116-
EXPECT_DEATH({ chunk.DecReaderRefCount(true); }, "");
117-
EXPECT_DEATH({ chunk.DecReaderRefCount(false); }, "");
116+
EXPECT_DEATH({ chunk.DecReaderRefCount(); }, "");
118117
}
119118

120119
// Check that the CHECK() in ClearUidLogs() if the ref count is greater than 0 is caught.
@@ -123,7 +122,7 @@ TEST(SerializedLogChunk, catch_ClearUidLogs_CHECK) {
123122
auto chunk = SerializedLogChunk{chunk_size};
124123
chunk.IncReaderRefCount();
125124
EXPECT_DEATH({ chunk.ClearUidLogs(1000, LOG_ID_MAIN, nullptr); }, "");
126-
chunk.DecReaderRefCount(false);
125+
chunk.DecReaderRefCount();
127126
}
128127

129128
class UidClearTest : public testing::TestWithParam<bool> {
@@ -144,7 +143,7 @@ class UidClearTest : public testing::TestWithParam<bool> {
144143
check(chunk_);
145144

146145
if (finish_writing) {
147-
chunk_.DecReaderRefCount(false);
146+
chunk_.DecReaderRefCount();
148147
}
149148
}
150149

0 commit comments

Comments
 (0)