some fixes in merge3

This commit is contained in:
sergeych committed 2023-03-21 05:27:24 +01:00
1 parent 2262c66b63
commit 08ce64796b
4 files changed
+41 -23

No files matched your search

@@ -5,9 +5,6 @@ import dev.gitlive.difflib.patch.AbstractDelta
import dev.gitlive.difflib.patch.ChangeDelta
import dev.gitlive.difflib.patch.DeleteDelta
import dev.gitlive.difflib.patch.InsertDelta
import net.sergeych.mp_logger.Log
import net.sergeych.mp_logger.LogTag
import net.sergeych.mp_logger.debug
import net.sergeych.sprintf.sprintf
/**
@@ -77,14 +74,18 @@ sealed class MergedBlock<T> {
/**
* Perform 3-way merge. See [merge3] for details.
*/
private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB: List<T>) :
LogTag("MRG3", Log.Level.INFO) {
private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB: List<T>,
val showDebug: Boolean = false) {
private val reindex = source.indices.toMutableList()
private val changeCount = MutableList(source.size) { 0 }
val result = source.toMutableList()
private fun debug( f: ()-> String ) {
if( showDebug ) println(f())
}
private fun trace() {
debug { result.indices.joinToString("") { "%3d".sprintf(it) } }
@@ -139,15 +140,20 @@ private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB
debug { "deleting $count elements @$sourcePosition" }
val position = findPosition(sourcePosition)
var sp = sourcePosition
// how much to shoft reindex, depends on actual deletions count:
var shift = count
for (i in position until position + count) {
// it this position is already removed, do nothing
if (reindex[sp] < 0) continue
if (reindex[sp] < 0) {
shift--
continue
}
reindex[sp++] = -1
result.removeAt(position)
changeCount.removeAt(position)
}
while (sp < reindex.size) {
reindex[sp].let { if (it > 0) reindex[sp] = it - count }
reindex[sp].let { if (it > 0) reindex[sp] = it - shift }
sp++
}
}
@@ -257,6 +263,4 @@ private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB
* See [MergeResult] for interpreting results
*/
fun <T> merge3(source: List<T>, a: List<T>, b: List<T>, showDebug: Boolean = false): MergeResult<T> =
Merge3(source, a, b).also {
if (showDebug) it.logLevel = Log.Level.DEBUG
}.perform()
Merge3(source, a, b, showDebug).perform()
+14
View File
@@ -19,6 +19,20 @@ class BasicTest {
assertEquals("Bye cruel world!!!", m.merged.str)
// assertTrue(m.noConflicts)
}
@Test
fun testMergeNoConflicts3() {
Log.connectConsole()
val src = "1Hello, world!".toList()
val a = "Hello, friend!".toList()
val b = "Bye world!".toList()
val m = merge3(src, a, b, true)
println(m.merged.str)
// println(m.conflicts)
println(m.changedAreas)
assertEquals("Bye friend!", m.merged.str)
// assertTrue(m.noConflicts)
}
@Test
fun testMergeNoConflicts2() {