added source indexes to merge3 results
This commit is contained in:
parent
a1c5d9ee88
commit
485afbbace
@ -4,7 +4,7 @@ plugins {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "net.sergeych"
|
group = "net.sergeych"
|
||||||
version = "0.0.4-SNAPSHOT"
|
version = "0.0.5-SNAPSHOT"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
@ -43,7 +43,7 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("dev.gitlive:kotlin-diff-utils:4.1.4")
|
implementation("dev.gitlive:kotlin-diff-utils:4.1.4")
|
||||||
implementation("net.sergeych:mp_stools:[1.3.3,)")
|
implementation("net.sergeych:mp_stools:[1.3.4,)")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val commonTest by getting {
|
val commonTest by getting {
|
||||||
|
@ -13,20 +13,23 @@ import net.sergeych.sprintf.sprintf
|
|||||||
*
|
*
|
||||||
* @param merged the best merged data. In the case of the conflict usually has both variants concatennated in place
|
* @param merged the best merged data. In the case of the conflict usually has both variants concatennated in place
|
||||||
* @param changedAreas ranges where data were altered. could be used to highlight changes
|
* @param changedAreas ranges where data were altered. could be used to highlight changes
|
||||||
|
* @param sourceIndices indexes of items in source array (not included in result) in new result [merged]. If source
|
||||||
|
* item is not included int the merged array, its index will be -1
|
||||||
*/
|
*/
|
||||||
class MergeResult<T>(
|
class MergeResult<T>(
|
||||||
val merged: List<T>,
|
val merged: MutableList<T>,
|
||||||
val changedAreas: List<IntRange>,
|
val changedAreas: List<IntRange>,
|
||||||
|
val sourceIndices: MutableList<Int>,
|
||||||
) {
|
) {
|
||||||
val blocks: List<MergedBlock<T>> by lazy {
|
val blocks: List<MergedBlock<T>> by lazy {
|
||||||
if (changedAreas.isEmpty())
|
if (changedAreas.isEmpty())
|
||||||
listOf(MergedBlock.Unchanged(merged))
|
listOf(MergedBlock.Unchanged(merged, sourceIndices[0]))
|
||||||
else {
|
else {
|
||||||
val result = mutableListOf<MergedBlock<T>>()
|
val result = mutableListOf<MergedBlock<T>>()
|
||||||
var start = 0
|
var start = 0
|
||||||
for (r in changedAreas) {
|
for (r in changedAreas) {
|
||||||
if (start != r.start) {
|
if (start != r.start) {
|
||||||
result.add(MergedBlock.Unchanged(merged.slice(start until r.start)))
|
result.add(MergedBlock.Unchanged(merged.slice(start until r.start), sourceIndices[start]))
|
||||||
}
|
}
|
||||||
if (!r.isEmpty()) {
|
if (!r.isEmpty()) {
|
||||||
result.add(MergedBlock.Resolved(merged.slice(r)))
|
result.add(MergedBlock.Resolved(merged.slice(r)))
|
||||||
@ -34,11 +37,21 @@ class MergeResult<T>(
|
|||||||
start = r.endInclusive + 1
|
start = r.endInclusive + 1
|
||||||
}
|
}
|
||||||
if (start < merged.size) {
|
if (start < merged.size) {
|
||||||
result.add(MergedBlock.Unchanged(merged.slice(start until merged.size)))
|
result.add(MergedBlock.Unchanged(merged.slice(start until merged.size), sourceIndices[start]))
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun toTrace(source: List<T>): String {
|
||||||
|
val r = StringBuilder()
|
||||||
|
r.append(merged.indices.joinToString("") { "%3d".sprintf(it) } + "\n")
|
||||||
|
r.append(merged.joinToString("") { "%3s".sprintf(it) } + "\n")
|
||||||
|
r.append("---- source ----\n")
|
||||||
|
r.append(source.joinToString("") { "%3s".sprintf(it) } + "\n")
|
||||||
|
r.append(sourceIndices.joinToString("") { "%3s".sprintf(it) } + "\n")
|
||||||
|
return r.toString()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -52,8 +65,9 @@ sealed class MergedBlock<T> {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Data that are equals in both variants and therefore was not altered
|
* Data that are equals in both variants and therefore was not altered
|
||||||
|
* @param referenceIndex index if the first item of the unchanged data as it was in source array.
|
||||||
*/
|
*/
|
||||||
data class Unchanged<T>(override val data: List<T>) : MergedBlock<T>()
|
data class Unchanged<T>(override val data: List<T>, val referenceIndex: Int) : MergedBlock<T>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The portion of data that was merged without conflicts
|
* The portion of data that was merged without conflicts
|
||||||
@ -74,16 +88,18 @@ sealed class MergedBlock<T> {
|
|||||||
/**
|
/**
|
||||||
* Perform 3-way merge. See [merge3] for details.
|
* Perform 3-way merge. See [merge3] for details.
|
||||||
*/
|
*/
|
||||||
private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB: List<T>,
|
private class Merge3<T>(
|
||||||
val showDebug: Boolean = false) {
|
val source: List<T>, val variantA: List<T>, val variantB: List<T>,
|
||||||
|
val showDebug: Boolean = false,
|
||||||
|
) {
|
||||||
|
|
||||||
private val reindex = source.indices.toMutableList()
|
private val reindex = source.indices.toMutableList()
|
||||||
private val changeCount = MutableList(source.size) { 0 }
|
private val changeCount = MutableList(source.size) { 0 }
|
||||||
|
|
||||||
val result = source.toMutableList()
|
val result = source.toMutableList()
|
||||||
|
|
||||||
private fun debug( f: ()-> String ) {
|
private fun debug(f: () -> String) {
|
||||||
if( showDebug ) println(f())
|
if (showDebug) println(f())
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun trace() {
|
private fun trace() {
|
||||||
@ -253,7 +269,7 @@ private class Merge3<T>(val source: List<T>, val variantA: List<T>, val variantB
|
|||||||
// closeConflict(changeCount.size)
|
// closeConflict(changeCount.size)
|
||||||
closeUpdate(changeCount.size)
|
closeUpdate(changeCount.size)
|
||||||
|
|
||||||
return MergeResult<T>(result, updates)
|
return MergeResult<T>(result, updates, reindex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ class BasicTest {
|
|||||||
@Test
|
@Test
|
||||||
fun testMergeNoConflicts3() {
|
fun testMergeNoConflicts3() {
|
||||||
Log.connectConsole()
|
Log.connectConsole()
|
||||||
val src = "1Hello, world!".toList()
|
val src = "Hello, world!".toList()
|
||||||
val a = "Hello, friend!".toList()
|
val a = "Hello, friend!".toList()
|
||||||
val b = "Bye world!".toList()
|
val b = "Bye world!".toList()
|
||||||
|
|
||||||
@ -31,6 +31,7 @@ class BasicTest {
|
|||||||
// println(m.conflicts)
|
// println(m.conflicts)
|
||||||
println(m.changedAreas)
|
println(m.changedAreas)
|
||||||
assertEquals("Bye friend!", m.merged.str)
|
assertEquals("Bye friend!", m.merged.str)
|
||||||
|
println(m.toTrace(src))
|
||||||
// assertTrue(m.noConflicts)
|
// assertTrue(m.noConflicts)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user