From 6d3a71c691c03e190351dd65bcf7204f70bbd654 Mon Sep 17 00:00:00 2001 From: Ilya Gorbunov Date: Thu, 29 Dec 2016 19:04:03 +0300 Subject: [PATCH] Minor refactoring: use mapValuesInPlace optimization, delegate aggregate implementation to aggregateTo. --- .../stdlib/src/kotlin/collections/Grouping.kt | 30 +++++++++++-------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/libraries/stdlib/src/kotlin/collections/Grouping.kt b/libraries/stdlib/src/kotlin/collections/Grouping.kt index d72aa4333b5..58282872754 100644 --- a/libraries/stdlib/src/kotlin/collections/Grouping.kt +++ b/libraries/stdlib/src/kotlin/collections/Grouping.kt @@ -40,13 +40,7 @@ public interface Grouping { public inline fun Grouping.aggregate( operation: (key: K, value: R?, element: T, first: Boolean) -> R ): Map { - val result = mutableMapOf() - for (e in this.elementIterator()) { - val key = keyOf(e) - val value = result[key] - result[key] = operation(key, value, e, value == null && !result.containsKey(key)) - } - return result + return aggregateTo(mutableMapOf(), operation) } /** @@ -73,8 +67,8 @@ public inline fun > Grouping.aggregateTo( ): M { for (e in this.elementIterator()) { val key = keyOf(e) - val acc = destination[key] - destination[key] = operation(key, acc, e, acc == null && !destination.containsKey(key)) + val accumulator = destination[key] + destination[key] = operation(key, accumulator, e, accumulator == null && !destination.containsKey(key)) } return destination } @@ -222,10 +216,10 @@ public inline fun > Grouping.reduceTo @JvmVersion public fun Grouping.eachCount(): Map = // fold(0) { acc, e -> acc + 1 } optimized for boxing - fold( + foldTo( destination = mutableMapOf(), initialValueSelector = { k, e -> kotlin.jvm.internal.Ref.IntRef() }, operation = { k, acc, e -> acc.apply { element += 1 } }) - .mapValues { it.value.element } + .mapValuesInPlace { it.value.element } /** * Groups elements from the [Grouping] source by key and counts elements in each group to the given [destination] map. @@ -245,10 +239,10 @@ public fun > Grouping.eachCountTo(destinat @JvmVersion public inline fun Grouping.eachSumOf(valueSelector: (T) -> Int): Map = // fold(0) { acc, e -> acc + valueSelector(e)} optimized for boxing - fold( + foldTo( destination = mutableMapOf(), initialValueSelector = { k, e -> kotlin.jvm.internal.Ref.IntRef() }, operation = { k, acc, e -> acc.apply { element += valueSelector(e) } }) - .mapValues { it.value.element } + .mapValuesInPlace { it.value.element } /** * Groups elements from the [Grouping] source by key and sums values provided by the [valueSelector] function for elements in each group @@ -261,6 +255,16 @@ public inline fun > Grouping.eachSumOfTo(d foldTo(destination, 0) { acc, e -> acc + valueSelector(e)} +@JvmVersion +@PublishedApi +@kotlin.internal.InlineOnly +internal inline fun MutableMap.mapValuesInPlace(f: (Map.Entry) -> R): MutableMap { + entries.forEach { + (it as MutableMap.MutableEntry).setValue(f(it)) + } + return (this as MutableMap) +} + /* // TODO: sum by long and by double overloads