diff --git a/runtime/src/main/kotlin/kotlin/collections/HashMap.kt b/runtime/src/main/kotlin/kotlin/collections/HashMap.kt index 7d56b7a517e..534f2134b20 100644 --- a/runtime/src/main/kotlin/kotlin/collections/HashMap.kt +++ b/runtime/src/main/kotlin/kotlin/collections/HashMap.kt @@ -13,9 +13,9 @@ class HashMap private constructor( override var size: Int = 0 private set - // private var keysView: HashSet? = null - // private var valuesView: HashMapValues? = null - // private var entriesView: HashMapEntrySet? = null + private var keysView: HashSet? = null + private var valuesView: HashMapValues? = null + private var entriesView: HashMapEntrySet? = null // ---------------------------- functions ---------------------------- @@ -90,45 +90,30 @@ class HashMap private constructor( } override val keys: MutableSet get() { - return HashSet(this) - - // Caching creates a reference cycle and thus leads to memory leaks; - // TODO: fix and enable. - - // val cur = keysView - // return if (cur == null) { - // val new = HashSet(this) - // keysView = new - // new - // } else cur + val cur = keysView + return if (cur == null) { + val new = HashSet(this) + keysView = new + new + } else cur } override val values: MutableCollection get() { - return HashMapValues(this) - - // Caching creates a reference cycle and thus leads to memory leaks; - // TODO: fix and enable. - - // val cur = valuesView - // return if (cur == null) { - // val new = HashMapValues(this) - // valuesView = new - // new - // } else cur + val cur = valuesView + return if (cur == null) { + val new = HashMapValues(this) + valuesView = new + new + } else cur } override val entries: MutableSet> get() { - return HashMapEntrySet(this) - - // Caching creates a reference cycle and thus leads to memory leaks; - // TODO: fix and enable. - - // val cur = entriesView - // return if (cur == null) { - // val new = HashMapEntrySet(this) - // entriesView = new - // return new - // } else cur + val cur = entriesView + return if (cur == null) { + val new = HashMapEntrySet(this) + entriesView = new + return new + } else cur } override fun equals(other: Any?): Boolean { @@ -246,7 +231,7 @@ class HashMap private constructor( private fun findKey(key: K): Int { var hash = hash(key) var probesLeft = maxProbeDistance - while (true) { + while (true) { val index = hashArray[hash] if (index == 0) return TOMBSTONE if (index > 0 && keysArray[index - 1] == key) return index - 1 @@ -265,7 +250,7 @@ class HashMap private constructor( } internal fun addKey(key: K): Int { - retry@ while (true) { + retry@ while (true) { var hash = hash(key) // put is allowed to grow maxProbeDistance with some limits (resize hash on reaching limits) val tentativeMaxProbeDistance = (maxProbeDistance * 2).coerceAtMost(hashSize / 2) diff --git a/runtime/src/main/kotlin/kotlin/collections/Maps.kt b/runtime/src/main/kotlin/kotlin/collections/Maps.kt index 997c502162d..ccb7bcb9bbf 100644 --- a/runtime/src/main/kotlin/kotlin/collections/Maps.kt +++ b/runtime/src/main/kotlin/kotlin/collections/Maps.kt @@ -417,14 +417,8 @@ public fun Iterable>.toMap(): Map { /** * Populates and returns the [destination] mutable map with key-value pairs from the given collection of pairs. */ -@Fixme -public fun > Iterable>.toMap(destination: M): M { - for (pair in this) { - destination.put(pair.first, pair.second) - } - return destination -} -// = destination.apply { putAll(this@toMap) } +public fun > Iterable>.toMap(destination: M): M + = destination.apply { putAll(this@toMap) } /** * Returns a new map containing all key-value pairs from the given array of pairs. @@ -440,14 +434,8 @@ public fun Array>.toMap(): Map = when(size) { /** * Populates and returns the [destination] mutable map with key-value pairs from the given array of pairs. */ -@Fixme -public fun > Array>.toMap(destination: M): M { -// = destination.apply { putAll(this@toMap) } - for (pair in this) { - destination.put(pair.first, pair.second) - } - return destination -} +public fun > Array>.toMap(destination: M): M + = destination.apply { putAll(this@toMap) } /** * Returns a new map containing all key-value pairs from the given sequence of pairs. @@ -459,14 +447,8 @@ public fun Sequence>.toMap(): Map = toMap(HashMap( /** * Populates and returns the [destination] mutable map with key-value pairs from the given sequence of pairs. */ -@Fixme -public fun > Sequence>.toMap(destination: M): M { - for (pair in this) { - destination.put(pair.first, pair.second) - } - return destination -} -// = destination.apply { putAll(this@toMap) } +public fun > Sequence>.toMap(destination: M): M + = destination.apply { putAll(this@toMap) } /** * Returns a new read-only map containing all key-value pairs from the original map. diff --git a/samples/csvparser/CsvParser.kt b/samples/csvparser/CsvParser.kt index b6035bfb08f..2e195b1e72c 100644 --- a/samples/csvparser/CsvParser.kt +++ b/samples/csvparser/CsvParser.kt @@ -3,7 +3,7 @@ import stdio.* fun parseLine(line: String, separator: Char) : List { val result = mutableListOf() - var builder = StringBuilder() + val builder = StringBuilder() var quotes = 0 for (ch in line) { when { @@ -14,7 +14,7 @@ fun parseLine(line: String, separator: Char) : List { (ch == '\n') || (ch == '\r') -> {} (ch == separator) && (quotes % 2 == 0) -> { result.add(builder.toString()) - builder = StringBuilder() + builder.length = 0 } else -> builder.append(ch) } @@ -37,6 +37,8 @@ fun main(args: Array) { return } + val keyValue = mutableMapOf() + try { memScoped { val bufferLength = 64 * 1024 @@ -47,10 +49,16 @@ fun main(args: Array) { if (nextLine == null || nextLine.isEmpty()) break val records = parseLine(nextLine, ',') - println(records[column]) + val key = records[column] + val current = keyValue[key] ?: 0 + keyValue[key] = current + 1 } } } finally { fclose(file) } -} \ No newline at end of file + + keyValue.forEach { + println("${it.key} -> ${it.value}") + } +} diff --git a/samples/csvparser/README.md b/samples/csvparser/README.md index 83d6ce628df..1305efecff6 100644 --- a/samples/csvparser/README.md +++ b/samples/csvparser/README.md @@ -10,4 +10,5 @@ To run use ./CsvParser.kexe ./European_Mammals_Red_List_Nov_2009.csv 4 100 -It will print fifth column (Family, zero-based index) in first 100 rows of the CSV file. +It will print number of all unique entries in fifth column +(Family, zero-based index) in first 100 rows of the CSV file.