Swap between two log buffers to save on copying

This commit is contained in:
Jordan Rose
2025-08-04 11:01:16 -07:00
committed by Cody Henthorne
parent 7074684474
commit 0726c29528

View File

@@ -121,11 +121,11 @@ class PersistentLogger private constructor(application: Application) : Log.Logge
) : Thread("signal-logger") {
private val dateFormat = SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS zzz", Locale.US)
private val buffer = mutableListOf<LogRequest>()
override fun run() {
var buffer = mutableListOf<LogRequest>()
while (true) {
requests.blockForRequests(buffer)
buffer = requests.blockForRequests(buffer)
db.logs.insert(buffer.asSequence().flatMap { requestToEntries(it) }, System.currentTimeMillis())
buffer.clear()
requests.notifyFlushed()
@@ -172,7 +172,8 @@ class PersistentLogger private constructor(application: Application) : Log.Logge
}
private class LogRequests {
val logs = mutableListOf<LogRequest>()
// Mutable because it gets replaced in blockForRequests, to save a copy operation.
var logs = mutableListOf<LogRequest>()
val logLock = Object()
var flushed = false
@@ -186,18 +187,21 @@ class PersistentLogger private constructor(application: Application) : Log.Logge
}
/**
* Blocks until requests are available. When they are, the [buffer] will be populated with all pending requests.
* Note: This method gets hit a *lot*, which is why we're using a buffer instead of spamming out new lists every time.
* Blocks until requests are available. When they are, returns all pending requests and swaps `swapBuffer` with the internal storage for future requests.
*
* Note: This method gets hit a *lot*, which is why we're using a pair of buffers instead of spamming out new lists every time.
* `swapBuffer` should already be empty upon entry to this method.
*/
fun blockForRequests(buffer: MutableList<LogRequest>) {
fun blockForRequests(swapBuffer: MutableList<LogRequest>): MutableList<LogRequest> {
synchronized(logLock) {
while (logs.isEmpty()) {
logLock.wait()
}
buffer.addAll(logs)
logs.clear()
val result = logs
logs = swapBuffer
flushed = false
return result
}
}