logd: replay the entire log when UID clearing

SerializedLogChunk::ClearUidLogs() has long been a source of pain, as
it attempts to modify log chunks in-place, leading to various edge
cases.  Worse, there are pathological cases that can cause many small
chunks, which will not compress cleanly, defeating the purpose of
SerializedLogBuffer.

Recently a bug was discovered that when the last-most chunk in a log
buffer is deleted during UID clearing, the new last-most chunk isn't
set up correctly for writing and triggers a CHECK.

This CL attempts to rectify both problems by rethinking UID clearing.
Instead of modifying chunks in place, this CL iterates through all log
messages and logs the messages that won't be cleared into a parallel
log buffer.

This prevents edge cases, replaces the error prone in-place
modification with the logging mechanism as logging naturally.

This solves the pathological cases, since the log buffers will be
re-packed during the clear.

This contains an optimization that chunks are copied to the new log
buffer as-is until a message from the UID to be cleared is found, such
that back-to-back UID clears of the same UID are no less efficient
than the previous algorithm.

Lastly, old chunks are either spliced into the new list or erased as
soon as they're handled to keep memory usage low during clearing.

Bug: 188858988
Test: unit tests
Change-Id: I2bd51aa4309f3ac48e4f523fb18d67de5e7234c7
7 files changed
tree: 220d35d07d504c38a457ee23d60136663ea46872
  1. liblog/
  2. logcat/
  3. logd/
  4. logwrapper/
  5. rust/
  6. OWNERS
  7. PREUPLOAD.cfg
  8. TEST_MAPPING