diff --git a/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/ArrayMap.kt b/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/ArrayMap.kt index c1ea0b4f..620239d5 100644 --- a/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/ArrayMap.kt +++ b/selfie-lib/src/commonMain/kotlin/com/diffplug/selfie/ArrayMap.kt @@ -49,29 +49,28 @@ class ArrayMap, V : Any>(private val data: Array) : Map(data.size - indicesToRemove.size * 2) var newDataIdx = 0 - var currentDataIdx = 0 + var currentPairIdx = 0 // Index for key-value pairs var toRemoveIdx = 0 - while (newDataIdx < newData.size) { - if (toRemoveIdx < indicesToRemove.size && currentDataIdx == indicesToRemove[toRemoveIdx]) { - ++toRemoveIdx - ++currentDataIdx + while (currentPairIdx < data.size / 2) { + if (toRemoveIdx < indicesToRemove.size && currentPairIdx == indicesToRemove[toRemoveIdx]) { + toRemoveIdx++ } else { - newData[newDataIdx++] = data[2 * currentDataIdx] - newData[newDataIdx++] = data[2 * currentDataIdx + 1] - ++currentDataIdx + check(newDataIdx < newData.size) { + "The indices weren't sorted or were >= size=$size: $indicesToRemove" + } + newData[newDataIdx++] = data[2 * currentPairIdx] // Copy key + newData[newDataIdx++] = data[2 * currentPairIdx + 1] // Copy value } + currentPairIdx++ } - val tailRemoval = - if (indicesToRemove.contains((data.size / 2) - 1)) { - 1 - } else { - 0 - } - check(toRemoveIdx + tailRemoval == indicesToRemove.size) { - "The indices weren't sorted or were too big: $indicesToRemove" + + // Ensure all indices to remove have been processed + check(toRemoveIdx == indicesToRemove.size) { + "The indices weren't sorted or were >= size($size): $indicesToRemove" } return ArrayMap(newData as Array) } + /** * Returns a new ArrayMap which has added the given key. Throws an exception if the key already * exists. @@ -169,6 +168,7 @@ class ArrayMap, V : Any>(private val data: Array) : Map(arrayOf()) diff --git a/selfie-lib/src/commonTest/kotlin/com/diffplug/selfie/ArrayMapTest.kt b/selfie-lib/src/commonTest/kotlin/com/diffplug/selfie/ArrayMapTest.kt index 68132feb..45d68b70 100644 --- a/selfie-lib/src/commonTest/kotlin/com/diffplug/selfie/ArrayMapTest.kt +++ b/selfie-lib/src/commonTest/kotlin/com/diffplug/selfie/ArrayMapTest.kt @@ -158,11 +158,18 @@ class ArrayMapTest { arrayMap.minusSortedIndices(listOf(0, 2)) shouldBe mapOf("second" to "2") + // arrayMap.minusSortedIndices(listOf(1, 0)) assertFails { arrayMap.minusSortedIndices(listOf(1, 0)) }.message shouldBe - "The indices weren't sorted or were too big: [1, 0]" + "The indices weren't sorted or were >= size=3: [1, 0]" assertFails { arrayMap.minusSortedIndices(listOf(2, 1)) }.message shouldBe - "The indices weren't sorted or were too big: [2, 1]" + "The indices weren't sorted or were >= size=3: [2, 1]" assertFails { arrayMap.minusSortedIndices(listOf(3)) }.message shouldBe - "The indices weren't sorted or were too big: [3]" + "The indices weren't sorted or were >= size=3: [3]" + } + + @Test + fun wasBroken() { + val map = ArrayMap.of(0.rangeTo(8).map { it to it.toString() }.toMutableList()) + map.minusSortedIndices(listOf(0, 2, 3, 6, 7, 8)).toString() shouldBe "{1=1, 4=4, 5=5}" } }