Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit af311506 authored by Juan Sebastian Martinez's avatar Juan Sebastian Martinez
Browse files

Using an efficient circular buffer as a logging structure.

ArrayDequeue maintains an internal variable-size array that can grow
unnecessarily when adding elements. This could lead to performance
issues and crashes such as the ones reported in the bugs below. We can
avoid this overhead by implementing a minimal ring buffer to log MSDL
events.

Test: Unit tests
Flag: com.android.systemui.msdl_feedback
Bug: 421673110
Bug: 422056230
Change-Id: I54625ff7f1b2ebc4f78bc6329bd1a9790759d0e2
parent 5cc433e3
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -34,7 +34,7 @@ interface MSDLHistoryLogger {

    companion object {

        const val HISTORY_SIZE = 20
        const val HISTORY_SIZE = 50
        val DATE_FORMAT = SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.US)
    }
}
+14 −10
Original line number Diff line number Diff line
@@ -18,22 +18,26 @@ package com.google.android.msdl.logging

import androidx.annotation.VisibleForTesting
import androidx.annotation.VisibleForTesting.Companion.PACKAGE_PRIVATE
import java.util.ArrayDeque
import java.util.Deque

@VisibleForTesting(otherwise = PACKAGE_PRIVATE)
class MSDLHistoryLoggerImpl(private val maxHistorySize: Int) : MSDLHistoryLogger {

    // Use an [ArrayDequeue] with a fixed size as the history structure
    private val history: Deque<MSDLEvent> = ArrayDeque(maxHistorySize)
    // Use an Array with a fixed size as the history structure. This will work as a ring buffer
    private val history: Array<MSDLEvent?> = arrayOfNulls(size = maxHistorySize)
    // The head will point to the next available position in the structure to add a new event
    private var head = 0

    override fun addEvent(event: MSDLEvent) {
        // Keep the history as a FIFO structure
        if (history.size == maxHistorySize) {
            history.removeFirst()
        }
        history.addLast(event)
        history[head] = event
        // Move the head pointer, wrapping if necessary
        head = (head + 1) % maxHistorySize
    }

    override fun getHistory(): List<MSDLEvent> = history.toList()
    override fun getHistory(): List<MSDLEvent> {
        val result = mutableListOf<MSDLEvent>()
        repeat(times = maxHistorySize) { i ->
            history[(i + head) % maxHistorySize]?.let { result.add(it) }
        }
        return result
    }
}