Remove early maps problems (#408)

This commit is contained in:
Nikolay Igotti
2017-03-29 12:10:52 +03:00
committed by GitHub
parent 9e15aa7204
commit b6e488b210
4 changed files with 43 additions and 67 deletions
@@ -13,9 +13,9 @@ class HashMap<K, V> private constructor(
override var size: Int = 0 override var size: Int = 0
private set private set
// private var keysView: HashSet<K>? = null private var keysView: HashSet<K>? = null
// private var valuesView: HashMapValues<V>? = null private var valuesView: HashMapValues<V>? = null
// private var entriesView: HashMapEntrySet<K, V>? = null private var entriesView: HashMapEntrySet<K, V>? = null
// ---------------------------- functions ---------------------------- // ---------------------------- functions ----------------------------
@@ -90,45 +90,30 @@ class HashMap<K, V> private constructor(
} }
override val keys: MutableSet<K> get() { override val keys: MutableSet<K> get() {
return HashSet(this) val cur = keysView
return if (cur == null) {
// Caching creates a reference cycle and thus leads to memory leaks; val new = HashSet(this)
// TODO: fix and enable. keysView = new
new
// val cur = keysView } else cur
// return if (cur == null) {
// val new = HashSet(this)
// keysView = new
// new
// } else cur
} }
override val values: MutableCollection<V> get() { override val values: MutableCollection<V> get() {
return HashMapValues(this) val cur = valuesView
return if (cur == null) {
// Caching creates a reference cycle and thus leads to memory leaks; val new = HashMapValues(this)
// TODO: fix and enable. valuesView = new
new
// val cur = valuesView } else cur
// return if (cur == null) {
// val new = HashMapValues(this)
// valuesView = new
// new
// } else cur
} }
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() { override val entries: MutableSet<MutableMap.MutableEntry<K, V>> get() {
return HashMapEntrySet(this) val cur = entriesView
return if (cur == null) {
// Caching creates a reference cycle and thus leads to memory leaks; val new = HashMapEntrySet(this)
// TODO: fix and enable. entriesView = new
return new
// val cur = entriesView } else cur
// return if (cur == null) {
// val new = HashMapEntrySet(this)
// entriesView = new
// return new
// } else cur
} }
override fun equals(other: Any?): Boolean { override fun equals(other: Any?): Boolean {
@@ -246,7 +231,7 @@ class HashMap<K, V> private constructor(
private fun findKey(key: K): Int { private fun findKey(key: K): Int {
var hash = hash(key) var hash = hash(key)
var probesLeft = maxProbeDistance var probesLeft = maxProbeDistance
while (true) { while (true) {
val index = hashArray[hash] val index = hashArray[hash]
if (index == 0) return TOMBSTONE if (index == 0) return TOMBSTONE
if (index > 0 && keysArray[index - 1] == key) return index - 1 if (index > 0 && keysArray[index - 1] == key) return index - 1
@@ -265,7 +250,7 @@ class HashMap<K, V> private constructor(
} }
internal fun addKey(key: K): Int { internal fun addKey(key: K): Int {
retry@ while (true) { retry@ while (true) {
var hash = hash(key) var hash = hash(key)
// put is allowed to grow maxProbeDistance with some limits (resize hash on reaching limits) // put is allowed to grow maxProbeDistance with some limits (resize hash on reaching limits)
val tentativeMaxProbeDistance = (maxProbeDistance * 2).coerceAtMost(hashSize / 2) val tentativeMaxProbeDistance = (maxProbeDistance * 2).coerceAtMost(hashSize / 2)
@@ -417,14 +417,8 @@ public fun <K, V> Iterable<Pair<K, V>>.toMap(): Map<K, V> {
/** /**
* Populates and returns the [destination] mutable map with key-value pairs from the given collection of pairs. * Populates and returns the [destination] mutable map with key-value pairs from the given collection of pairs.
*/ */
@Fixme public fun <K, V, M : MutableMap<in K, in V>> Iterable<Pair<K, V>>.toMap(destination: M): M
public fun <K, V, M : MutableMap<in K, in V>> Iterable<Pair<K, V>>.toMap(destination: M): M { = destination.apply { putAll(this@toMap) }
for (pair in this) {
destination.put(pair.first, pair.second)
}
return destination
}
// = destination.apply { putAll(this@toMap) }
/** /**
* Returns a new map containing all key-value pairs from the given array of pairs. * Returns a new map containing all key-value pairs from the given array of pairs.
@@ -440,14 +434,8 @@ public fun <K, V> Array<out Pair<K, V>>.toMap(): Map<K, V> = when(size) {
/** /**
* Populates and returns the [destination] mutable map with key-value pairs from the given array of pairs. * Populates and returns the [destination] mutable map with key-value pairs from the given array of pairs.
*/ */
@Fixme public fun <K, V, M : MutableMap<in K, in V>> Array<out Pair<K, V>>.toMap(destination: M): M
public fun <K, V, M : MutableMap<in K, in V>> Array<out Pair<K, V>>.toMap(destination: M): M { = destination.apply { putAll(this@toMap) }
// = destination.apply { putAll(this@toMap) }
for (pair in this) {
destination.put(pair.first, pair.second)
}
return destination
}
/** /**
* Returns a new map containing all key-value pairs from the given sequence of pairs. * Returns a new map containing all key-value pairs from the given sequence of pairs.
@@ -459,14 +447,8 @@ public fun <K, V> Sequence<Pair<K, V>>.toMap(): Map<K, V> = toMap(HashMap<K, V>(
/** /**
* Populates and returns the [destination] mutable map with key-value pairs from the given sequence of pairs. * Populates and returns the [destination] mutable map with key-value pairs from the given sequence of pairs.
*/ */
@Fixme public fun <K, V, M : MutableMap<in K, in V>> Sequence<Pair<K, V>>.toMap(destination: M): M
public fun <K, V, M : MutableMap<in K, in V>> Sequence<Pair<K, V>>.toMap(destination: M): M { = destination.apply { putAll(this@toMap) }
for (pair in this) {
destination.put(pair.first, pair.second)
}
return destination
}
// = destination.apply { putAll(this@toMap) }
/** /**
* Returns a new read-only map containing all key-value pairs from the original map. * Returns a new read-only map containing all key-value pairs from the original map.
+12 -4
View File
@@ -3,7 +3,7 @@ import stdio.*
fun parseLine(line: String, separator: Char) : List<String> { fun parseLine(line: String, separator: Char) : List<String> {
val result = mutableListOf<String>() val result = mutableListOf<String>()
var builder = StringBuilder() val builder = StringBuilder()
var quotes = 0 var quotes = 0
for (ch in line) { for (ch in line) {
when { when {
@@ -14,7 +14,7 @@ fun parseLine(line: String, separator: Char) : List<String> {
(ch == '\n') || (ch == '\r') -> {} (ch == '\n') || (ch == '\r') -> {}
(ch == separator) && (quotes % 2 == 0) -> { (ch == separator) && (quotes % 2 == 0) -> {
result.add(builder.toString()) result.add(builder.toString())
builder = StringBuilder() builder.length = 0
} }
else -> builder.append(ch) else -> builder.append(ch)
} }
@@ -37,6 +37,8 @@ fun main(args: Array<String>) {
return return
} }
val keyValue = mutableMapOf<String, Int>()
try { try {
memScoped { memScoped {
val bufferLength = 64 * 1024 val bufferLength = 64 * 1024
@@ -47,10 +49,16 @@ fun main(args: Array<String>) {
if (nextLine == null || nextLine.isEmpty()) break if (nextLine == null || nextLine.isEmpty()) break
val records = parseLine(nextLine, ',') val records = parseLine(nextLine, ',')
println(records[column]) val key = records[column]
val current = keyValue[key] ?: 0
keyValue[key] = current + 1
} }
} }
} finally { } finally {
fclose(file) fclose(file)
} }
}
keyValue.forEach {
println("${it.key} -> ${it.value}")
}
}
+2 -1
View File
@@ -10,4 +10,5 @@ To run use
./CsvParser.kexe ./European_Mammals_Red_List_Nov_2009.csv 4 100 ./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.