Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

1.0.87 #92

Merged
merged 3 commits into from
Aug 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package com.simiacryptus.skyenet.core

import java.io.ByteArrayOutputStream
import java.io.IOException
import java.io.PrintStream
import java.util.*
import java.util.concurrent.atomic.AtomicBoolean

object OutputInterceptor {
private val originalOut: PrintStream = System.out
private val originalErr: PrintStream = System.err
private val isSetup = AtomicBoolean(false)
private val globalStreamLock = Any()

fun setupInterceptor() {
if (isSetup.getAndSet(true)) return
System.setOut(PrintStream(OutputStreamRouter(originalOut)))
System.setErr(PrintStream(OutputStreamRouter(originalErr)))
}

private val globalStream = ByteArrayOutputStream()

private val threadLocalBuffer = WeakHashMap<Thread, ByteArrayOutputStream>()

private fun getThreadOutputStream(): ByteArrayOutputStream {
val currentThread = Thread.currentThread()
synchronized(threadLocalBuffer) {
return threadLocalBuffer.getOrPut(currentThread) { ByteArrayOutputStream() }
}
}

fun getThreadOutput(): String {
val outputStream = getThreadOutputStream()
try {
outputStream.flush()
} catch (e: IOException) {
throw RuntimeException(e)
}
return outputStream.toString()
}

fun clearThreadOutput() {
getThreadOutputStream().reset()
}

fun getGlobalOutput(): String {
synchronized(globalStreamLock) {
return globalStream.toString()
}
}

fun clearGlobalOutput() {
synchronized(globalStreamLock) {
globalStream.reset()
}
}

private class OutputStreamRouter(private val originalStream: PrintStream) : ByteArrayOutputStream() {
private val maxGlobalBuffer = 8 * 1024 * 1024
private val maxThreadBuffer = 1024 * 1024

override fun write(b: Int) {
originalStream.write(b)
synchronized(globalStreamLock) {
if (globalStream.size() > maxGlobalBuffer) {
globalStream.reset()
}
globalStream.write(b)
}
val threadOutputStream = getThreadOutputStream()
if (threadOutputStream.size() > maxThreadBuffer) {
threadOutputStream.reset()
}
threadOutputStream.write(b)
}

override fun write(b: ByteArray, off: Int, len: Int) {
originalStream.write(b, off, len)
synchronized(globalStreamLock) {
if (globalStream.size() > maxGlobalBuffer) {
globalStream.reset()
}
globalStream.write(b, off, len)
}
val threadOutputStream = getThreadOutputStream()
if (threadOutputStream.size() > maxThreadBuffer) {
threadOutputStream.reset()
}
threadOutputStream.write(b, off, len)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,12 @@ public class OutputInterceptorThreadedTest {

@Test
public void testThreadedInterceptor() throws InterruptedException {
OutputInterceptor.setupInterceptor();
OutputInterceptor.INSTANCE.setupInterceptor();
AtomicInteger successCounter = new AtomicInteger(0);
ExecutorService executorService = Executors.newFixedThreadPool(5);
Object lock = new Object();
Runnable task = () -> {
OutputInterceptor.clearThreadOutput();
OutputInterceptor.INSTANCE.clearThreadOutput();
String threadName = Thread.currentThread().getName();
System.out.println("Thread: " + threadName + " output");
System.err.println("Thread: " + threadName + " error");
Expand All @@ -28,7 +28,7 @@ public void testThreadedInterceptor() throws InterruptedException {
Thread.currentThread().interrupt();
}
String expectedOutput = ("Thread: " + threadName + " output\nThread: " + threadName + " error\n").trim();
String threadOutput = OutputInterceptor.getThreadOutput().replace("\r", "").trim();
String threadOutput = OutputInterceptor.INSTANCE.getThreadOutput().replace("\r", "").trim();
if (threadOutput.trim().equals(expectedOutput.trim())) {
successCounter.incrementAndGet();
} else {
Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Gradle Releases -> https://github.com/gradle/gradle/releases
libraryGroup = com.simiacryptus.skyenet
libraryVersion = 1.0.86
libraryVersion = 1.0.87
gradleVersion = 7.6.1
kotlin.daemon.jvmargs=-Xmx2g
97 changes: 51 additions & 46 deletions webui/src/main/kotlin/com/simiacryptus/diff/IterativePatchUtil.kt
Original file line number Diff line number Diff line change
Expand Up @@ -332,52 +332,57 @@ object IterativePatchUtil {
}
}

private fun generatePatchedText(
sourceLines: List<LineRecord>,
patchLines: List<LineRecord>,
): List<String> {
log.debug("Starting to generate patched text")
val patchedText: MutableList<String> = mutableListOf()
val usedPatchLines = mutableSetOf<LineRecord>()
var sourceIndex = -1
var lastMatchedPatchIndex = -1
while (sourceIndex < sourceLines.size - 1) {
val codeLine = sourceLines[++sourceIndex]
when {
codeLine.matchingLine?.type == DELETE -> {
val patchLine = codeLine.matchingLine!!
log.debug("Deleting line: {}", codeLine)
// Delete the line -- do not add to patched text
usedPatchLines.add(patchLine)
checkAfterForInserts(patchLine, usedPatchLines, patchedText)
lastMatchedPatchIndex = patchLine.index
}

codeLine.matchingLine != null -> {
val patchLine: LineRecord = codeLine.matchingLine!!
log.debug("Patching line: {} <-> {}", codeLine, patchLine)
checkBeforeForInserts(patchLine, usedPatchLines, patchedText)
usedPatchLines.add(patchLine)
patchedText.add(patchLine.line ?: "") // Add the patched line
checkAfterForInserts(patchLine, usedPatchLines, patchedText)
lastMatchedPatchIndex = patchLine.index
}

else -> {
log.debug("Added unmatched source line: {}", codeLine)
patchedText.add(codeLine.line ?: "")
}

}
}
if (lastMatchedPatchIndex == -1) patchLines.filter { it.type == ADD && !usedPatchLines.contains(it) }
.forEach { line ->
log.debug("Added patch line: {}", line)
patchedText.add(line.line ?: "")
}
log.debug("Generated patched text with ${patchedText.size} lines")
return patchedText
}
private fun generatePatchedText(
sourceLines: List<LineRecord>,
patchLines: List<LineRecord>,
): List<String> {
log.debug("Starting to generate patched text")
val patchedText: MutableList<String> = mutableListOf()
val usedPatchLines = mutableSetOf<LineRecord>()
var sourceIndex = -1
var lastMatchedPatchIndex = -1
while (sourceIndex < sourceLines.size - 1) {
val codeLine = sourceLines[++sourceIndex]
when {
codeLine.matchingLine?.type == DELETE -> {
val patchLine = codeLine.matchingLine!!
log.debug("Deleting line: {}", codeLine)
// Delete the line -- do not add to patched text
usedPatchLines.add(patchLine)
checkAfterForInserts(patchLine, usedPatchLines, patchedText)
lastMatchedPatchIndex = patchLine.index
}

codeLine.matchingLine != null -> {
val patchLine: LineRecord = codeLine.matchingLine!!
log.debug("Patching line: {} <-> {}", codeLine, patchLine)
checkBeforeForInserts(patchLine, usedPatchLines, patchedText)
usedPatchLines.add(patchLine)
// Use the source line if it matches the patch line (ignoring whitespace)
if (normalizeLine(codeLine.line ?: "") == normalizeLine(patchLine.line ?: "")) {
patchedText.add(codeLine.line ?: "")
} else {
patchedText.add(patchLine.line ?: "")
}
checkAfterForInserts(patchLine, usedPatchLines, patchedText)
lastMatchedPatchIndex = patchLine.index
}

else -> {
log.debug("Added unmatched source line: {}", codeLine)
patchedText.add(codeLine.line ?: "")
}

}
}
if (lastMatchedPatchIndex == -1) patchLines.filter { it.type == ADD && !usedPatchLines.contains(it) }
.forEach { line ->
log.debug("Added patch line: {}", line)
patchedText.add(line.line ?: "")
}
log.debug("Generated patched text with ${patchedText.size} lines")
return patchedText
}

private fun checkBeforeForInserts(
patchLine: LineRecord,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
package com.simiacryptus.diff

import org.junit.jupiter.api.Assertions
import org.junit.jupiter.api.Assertions.assertEquals
import org.junit.jupiter.api.Test

Expand Down Expand Up @@ -106,7 +105,7 @@ class IterativePatchUtilTest {
""".trimIndent()
val expected = """
line1
line3
line3
""".trimIndent()
val result = IterativePatchUtil.applyPatch(source, patch)
assertEquals(expected.trim().replace("\r\n", "\n"), result.replace("\r\n", "\n"))
Expand All @@ -130,13 +129,13 @@ class IterativePatchUtilTest {
line3
""".trimIndent()
val expected = """
line1
lineA
lineB
line2
line3
""".trimIndent()
|line1
| lineA
| lineB
|
|line2
|line3
""".trimMargin()
val result = IterativePatchUtil.applyPatch(source, patch)
assertEquals(expected.trim().replace("\r\n", "\n"), result.replace("\r\n", "\n"))
}
Expand All @@ -159,13 +158,13 @@ class IterativePatchUtilTest {
line3
""".trimIndent()
val expected = """
line1
lineA
lineB
line2
line3
""".trimIndent()
|line1
| lineA
| lineB
|
|line2
|line3
""".trimMargin()
val result = IterativePatchUtil.applyPatch(source, patch)
assertEquals(expected.trim().replace("\r\n", "\n"), result.replace("\r\n", "\n"))
}
Expand Down
Loading