Fix: Avoid eager List allocation in countDiffLineStats for large diffs
Replaced `diff.split("\n")` with `diff.lineSequence()` in `FileRenderers.kt`'s `countDiffLineStats()` method. This prevents massive `ArrayList` allocations on the heap when processing multi-thousand-line diffs during tool card rendering, improving memory efficiency by evaluating the lines lazily.
Added comprehensive unit tests in `FileEditSupportTest.kt` covering empty diffs, header filtering, CRLF handling, and large multi-line diffs.
This commit is contained in:
1 parent
f520cf2dce
commit
304a90186a
2 files changed
+55
-1
No files matched your search
@@ -79,7 +79,7 @@ internal object FileEditSupport {
|
|||||||
var added = 0
|
var added = 0
|
||||||
var removed = 0
|
var removed = 0
|
||||||
|
|
||||||
for (line in diff.split("\n")) {
|
for (line in diff.lineSequence()) {
|
||||||
when {
|
when {
|
||||||
line.startsWith("+") && !line.startsWith("+++") -> added += 1
|
line.startsWith("+") && !line.startsWith("+++") -> added += 1
|
||||||
line.startsWith("-") && !line.startsWith("---") -> removed += 1
|
line.startsWith("-") && !line.startsWith("---") -> removed += 1
|
||||||
|
|||||||
@@ -0,0 +1,54 @@
|
|||||||
|
package com.m57.hermescontrol.ui.chat.tool.render
|
||||||
|
|
||||||
|
import org.junit.Assert.assertEquals
|
||||||
|
import org.junit.Test
|
||||||
|
|
||||||
|
class FileEditSupportTest {
|
||||||
|
@Test
|
||||||
|
fun testCountDiffLineStats_emptyDiff() {
|
||||||
|
val stats = FileEditSupport.countDiffLineStats("")
|
||||||
|
assertEquals(0, stats.added)
|
||||||
|
assertEquals(0, stats.removed)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCountDiffLineStats_headerFiltering() {
|
||||||
|
val diff =
|
||||||
|
"""
|
||||||
|
--- a/file.txt
|
||||||
|
+++ b/file.txt
|
||||||
|
@@ -1,5 +1,5 @@
|
||||||
|
unchanged
|
||||||
|
-removed line
|
||||||
|
+added line
|
||||||
|
""".trimIndent()
|
||||||
|
val stats = FileEditSupport.countDiffLineStats(diff)
|
||||||
|
assertEquals(1, stats.added)
|
||||||
|
assertEquals(1, stats.removed)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCountDiffLineStats_crlfHandling() {
|
||||||
|
val diff = "---\r\n+++\r\n+added\r\n-removed\r\n+another\r\n"
|
||||||
|
val stats = FileEditSupport.countDiffLineStats(diff)
|
||||||
|
assertEquals(2, stats.added)
|
||||||
|
assertEquals(1, stats.removed)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCountDiffLineStats_largeDiff() {
|
||||||
|
val sb = java.lang.StringBuilder()
|
||||||
|
sb.append("--- a/file.txt\n")
|
||||||
|
sb.append("+++ b/file.txt\n")
|
||||||
|
|
||||||
|
val count = 5000
|
||||||
|
for (i in 0 until count) {
|
||||||
|
sb.append("-old line $i\n")
|
||||||
|
sb.append("+new line $i\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
val stats = FileEditSupport.countDiffLineStats(sb.toString())
|
||||||
|
assertEquals(count, stats.added)
|
||||||
|
assertEquals(count, stats.removed)
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in new issue
Block a user