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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user