some fixes in merge3
This commit is contained in:
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()
|
||||
@@ -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() {
|
||||
|
||||
Reference in new issue
Block a user