
jvmMain.io.ktor.util.AttributesJvm.kt Maven / Gradle / Ivy
/*
* Copyright 2014-2019 JetBrains s.r.o and contributors. Use of this source code is governed by the Apache 2.0 license.
*/
package io.ktor.util
import java.util.concurrent.*
/**
* Create JVM specific attributes instance.
*/
public actual fun Attributes(concurrent: Boolean): Attributes =
if (concurrent) ConcurrentSafeAttributes() else HashMapAttributes()
private abstract class AttributesJvmBase : Attributes {
protected abstract val map: MutableMap, Any?>
@Suppress("UNCHECKED_CAST")
public final override fun getOrNull(key: AttributeKey): T? = map[key] as T?
public final override operator fun contains(key: AttributeKey<*>): Boolean = map.containsKey(key)
public final override fun put(key: AttributeKey, value: T) {
map[key] = value
}
public final override fun remove(key: AttributeKey) {
map.remove(key)
}
public final override val allKeys: List>
get() = map.keys.toList()
}
private class ConcurrentSafeAttributes : AttributesJvmBase() {
override val map: ConcurrentHashMap, Any?> = ConcurrentHashMap()
/**
* Gets a value of the attribute for the specified [key], or calls supplied [block] to compute its value.
* Note: [block] could be eventually evaluated twice for the same key.
* TODO: To be discussed. Workaround for android < API 24.
*/
override fun computeIfAbsent(key: AttributeKey, block: () -> T): T {
@Suppress("UNCHECKED_CAST")
map[key]?.let { return it as T }
val result = block()
@Suppress("UNCHECKED_CAST")
return (map.putIfAbsent(key, result) ?: result) as T
}
}
private class HashMapAttributes : AttributesJvmBase() {
override val map: MutableMap, Any?> = HashMap()
/**
* Gets a value of the attribute for the specified [key], or calls supplied [block] to compute its value.
* Note: [block] could be eventually evaluated twice for the same key.
* TODO: To be discussed. Workaround for android < API 24.
*/
override fun computeIfAbsent(key: AttributeKey, block: () -> T): T {
@Suppress("UNCHECKED_CAST")
map[key]?.let { return it as T }
val result = block()
@Suppress("UNCHECKED_CAST")
return (map.put(key, result) ?: result) as T
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy