add CoroutineLocal

This commit is contained in:
tursom 2020-07-18 01:46:34 +08:00
parent e8b6d29c4e
commit 2f953dc35b
7 changed files with 618 additions and 246 deletions

View File

@ -1,271 +1,284 @@
package cn.tursom.core.datastruct
import cn.tursom.core.cast
@Suppress("MemberVisibilityCanBePrivate")
class ArrayMap<K : Comparable<K>, V>(initialCapacity: Int = 16) : SimpMap<K, V> {
@Volatile
private var arr: Array<Node<K, V>?> = Array(initialCapacity) { null }
@Volatile
private var end = 0
open class ArrayMap<K, V>(initialCapacity: Int = 16) : SimpMap<K, V> {
@Volatile
protected var arr: Array<Node<K, V>?> = Array(initialCapacity) { null }
override val size: Int get() = end
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = EntrySet(this)
override val keys: MutableSet<K> = KeySet(this)
override val values: MutableCollection<V> = ValueCollection(this)
@Volatile
protected var end = 0
/**
* @param key 查找的键
* @return 键所在的下标
* @return < 0 如果键不存在, -${return} - 1 为如果插入应插入的下标
*/
fun search(key: K): Int {
if (end == 0) return -1
return arr.binarySearch(key, 0, end)
override val size: Int get() = end
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = EntrySet(this)
override val keys: MutableSet<K> = KeySet(this)
override val values: MutableCollection<V> = ValueCollection(this)
/**
* @param key 查找的键
* @return 键所在的下标
* @return < 0 如果键不存在, -${return} - 1 为如果插入应插入的下标
*/
open fun search(key: K): Int {
if (end == 0) return -1
for (index in 0 until end) {
if ((arr[index] ?: continue).key == key) {
return index
}
}
return -1
}
infix fun getFromIndex(index: Int): V? {
return if (index < 0) null
else arr[index]?.value
}
override fun first(): V? = getFromIndex(0)
override fun clear() {
end = 0
}
override operator fun set(key: K, value: V) {
setAndGet(key, value)
}
override fun setAndGet(key: K, value: V): V? {
@Suppress("SENSELESS_COMPARISON")
if (key == null) return null
// 首先查找得到目标所在的下标
val index = search(key)
var prev: V? = null
if (index < 0) {
// 下标小于零表示不存在,直接插入数据
insert(key, value, -index - 1)
} else {
val node = arr[index]
if (node != null) {
prev = node.value
node.value = value
} else arr[index] = Node(key, value)
}
return prev
}
override infix fun putAll(from: Map<out K, V>) {
from.forEach { (key, value) ->
val index = search(key)
if (index < 0) arr[end++] = Node(key, value)
else {
val node = arr[index]
if (node != null) node.value = value
else arr[index] = Node(key, value)
}
}
}
override infix fun delete(key: K): V? {
val index = search(key)
return delete(index)
}
override infix fun containsKey(key: K): Boolean = search(key) >= 0
override infix fun containsValue(value: V): Boolean {
arr.forEach {
if (it?.value == value) return true
}
return false
}
override infix operator fun get(key: K): V? = getNode(key)?.value
override fun isEmpty(): Boolean = end == 0
fun copy(): ArrayMap<K, V> {
val clone = ArrayMap<K, V>(0)
clone.arr = Array(end) { arr[it]?.let { Node(it.key, it.value) } }
clone.end = end
return clone
}
override fun toString(): String {
if (end == 0) return "{}"
val sb = StringBuilder("{${arr[0]}")
for (i in 1 until end) {
sb.append(", ")
sb.append(arr[i])
}
sb.append("}")
return sb.toString()
}
private fun getNode(key: K): Node<K, V>? {
@Suppress("SENSELESS_COMPARISON")
if (key == null) return null
val index = search(key)
return if (index < 0) null
else arr[index]
}
private fun resize(newSize: Int = if (arr.isNotEmpty()) arr.size * 2 else 1) {
arr = arr.copyOf(newSize)
}
private fun insert(key: K, value: V, index: Int): V? {
if (end == arr.size) resize()
System.arraycopy(arr, index, arr, index + 1, end - index)
arr[index] = Node(key, value)
end++
return value
}
private infix fun delete(index: Int): V? {
if (index in 0 until end) {
val oldNode = arr[index]
System.arraycopy(arr, index + 1, arr, index, end - index - 1)
end--
return oldNode?.value
}
return null
}
class Node<K, V>(
override val key: K,
@Volatile override var value: V
) : MutableMap.MutableEntry<K, V>, Comparable<K> {
override fun toString(): String = "$key=$value"
override fun setValue(newValue: V): V = value.also { value = newValue }
override fun compareTo(other: K): Int {
return if (key is Comparable<*>) {
key.cast<Comparable<K>>().compareTo(other)
} else {
-1
}
}
}
class EntrySet<K, V>(private val map: ArrayMap<K, V>) : MutableSet<MutableMap.MutableEntry<K, V>> {
override val size: Int get() = map.size
override fun contains(element: MutableMap.MutableEntry<K, V>): Boolean = map[element.key] == element.value
override fun isEmpty(): Boolean = map.isEmpty()
override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> = MapIterator(map)
override fun clear() = map.clear()
override fun containsAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach {
if (!contains(it)) return false
}
return true
}
infix fun getFromIndex(index: Int): V? {
return if (index < 0) null
else arr[index]?.value
override fun add(element: MutableMap.MutableEntry<K, V>): Boolean {
map[element.key] = element.value
return true
}
override fun first(): V? = getFromIndex(0)
override fun clear() {
end = 0
override fun addAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { add(it) }
return true
}
override operator fun set(key: K, value: V) {
setAndGet(key, value)
override fun remove(element: MutableMap.MutableEntry<K, V>): Boolean {
val index = map.search(element.key)
val value = map.getFromIndex(index)
return if (value == element.value) {
map.delete(index)
true
} else {
false
}
}
override fun setAndGet(key: K, value: V): V? {
@Suppress("SENSELESS_COMPARISON")
if (key == null) return null
// 首先查找得到目标所在的下标
val index = search(key)
var prev: V? = null
if (index < 0) {
// 下标小于零表示不存在,直接插入数据
insert(key, value, -index - 1)
} else {
val node = arr[index]
if (node != null) {
prev = node.value
node.value = value
} else arr[index] = Node(key, value)
}
return prev
override fun removeAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { remove(it) }
return true
}
override infix fun putAll(from: Map<out K, V>) {
from.forEach { (key, value) ->
val index = search(key)
if (index < 0) arr[end++] = Node(key, value)
else {
val node = arr[index]
if (node != null) node.value = value
else arr[index] = Node(key, value)
}
}
arr.sort()
override fun retainAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
val contains = elements.filter { map[it.key] == it.value }
map.clear()
map.resize(contains.size)
addAll(contains)
return true
}
}
class MapIterator<K, V>(private val map: ArrayMap<K, V>) : MutableIterator<MutableMap.MutableEntry<K, V>> {
private var index = 0
override fun hasNext(): Boolean {
@Suppress("ControlFlowWithEmptyBody")
while (++index < map.arr.size && index < map.end && map.arr[index] == null);
index--
return index < map.end
}
override infix fun delete(key: K): V? {
val index = search(key)
return delete(index)
override fun next(): MutableMap.MutableEntry<K, V> = map.arr[index++]!!
override fun remove() {
map.delete(index)
index--
}
}
class KeySet<K>(private val map: ArrayMap<K, *>) : MutableSet<K> {
override val size: Int get() = map.size
override fun contains(element: K): Boolean = map.containsKey(element)
override fun isEmpty(): Boolean = size == 0
override fun iterator(): MutableIterator<K> = KeyIterator(map)
override fun containsAll(elements: Collection<K>): Boolean {
elements.forEach {
if (!map.containsKey(it)) return false
}
return true
}
override infix fun containsKey(key: K): Boolean = search(key) >= 0
override infix fun containsValue(value: V): Boolean {
arr.forEach {
if (it?.value == value) return true
}
return false
override fun add(element: K): Boolean = false
override fun addAll(elements: Collection<K>): Boolean = false
override fun clear() = map.clear()
override fun retainAll(elements: Collection<K>): Boolean = map.entries.retainAll(elements.map { map.getNode(it) }.filterNotNull())
override fun remove(element: K): Boolean = map.remove(element) != null
override fun removeAll(elements: Collection<K>): Boolean {
elements.forEach { remove(it) }
return true
}
}
override infix operator fun get(key: K): V? = getNode(key)?.value
override fun isEmpty(): Boolean = end == 0
class KeyIterator<K>(map: ArrayMap<K, *>) : MutableIterator<K> {
private val iterator = map.iterator()
override fun hasNext(): Boolean = iterator.hasNext()
override fun next(): K = iterator.next().key
override fun remove() = iterator.remove()
}
fun copy(): ArrayMap<K, V> {
val clone = ArrayMap<K, V>(0)
clone.arr = Array(end) { arr[it]?.let { Node(it.key, it.value) } }
clone.end = end
return clone
class ValueCollection<V>(private val map: ArrayMap<*, V>) : MutableCollection<V> {
override val size: Int get() = map.size
override fun contains(element: V): Boolean = map.containsValue(element)
override fun isEmpty(): Boolean = size == 0
override fun iterator(): MutableIterator<V> = ValueIterator(map)
override fun add(element: V): Boolean = false
override fun addAll(elements: Collection<V>): Boolean = false
override fun clear() = map.clear()
override fun remove(element: V): Boolean = false
override fun removeAll(elements: Collection<V>): Boolean = false
override fun retainAll(elements: Collection<V>): Boolean = false
override fun containsAll(elements: Collection<V>): Boolean {
elements.forEach {
if (!map.containsValue(it)) return false
}
return true
}
}
override fun toString(): String {
if (end == 0) return "{}"
val sb = StringBuilder("{${arr[0]}")
for (i in 1 until end) {
sb.append(", ")
sb.append(arr[i])
}
sb.append("}")
return sb.toString()
}
private fun getNode(key: K): Node<K, V>? {
@Suppress("SENSELESS_COMPARISON")
if (key == null) return null
val index = search(key)
return if (index < 0) null
else arr[index]
}
private fun resize(newSize: Int = if (arr.isNotEmpty()) arr.size * 2 else 1) {
arr = arr.copyOf(newSize)
}
private fun insert(key: K, value: V, index: Int): V? {
if (end == arr.size) resize()
System.arraycopy(arr, index, arr, index + 1, end - index)
arr[index] = Node(key, value)
end++
return value
}
private infix fun delete(index: Int): V? {
if (index in 0 until end) {
val oldNode = arr[index]
System.arraycopy(arr, index + 1, arr, index, end - index - 1)
end--
return oldNode?.value
}
return null
}
class Node<K : Comparable<K>, V>(
override val key: K,
@Volatile override var value: V
) : Comparable<K>, MutableMap.MutableEntry<K, V> {
override fun compareTo(other: K): Int = key.compareTo(other)
override fun toString(): String = "$key=$value"
override fun setValue(newValue: V): V = value.also { value = newValue }
}
class EntrySet<K : Comparable<K>, V>(private val map: ArrayMap<K, V>) : MutableSet<MutableMap.MutableEntry<K, V>> {
override val size: Int get() = map.size
override fun contains(element: MutableMap.MutableEntry<K, V>): Boolean = map[element.key] == element.value
override fun isEmpty(): Boolean = map.isEmpty()
override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> = MapIterator(map)
override fun clear() = map.clear()
override fun containsAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach {
if (!contains(it)) return false
}
return true
}
override fun add(element: MutableMap.MutableEntry<K, V>): Boolean {
map[element.key] = element.value
return true
}
override fun addAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { add(it) }
return true
}
override fun remove(element: MutableMap.MutableEntry<K, V>): Boolean {
val index = map.search(element.key)
val value = map.getFromIndex(index)
return if (value == element.value) {
map.delete(index)
true
} else {
false
}
}
override fun removeAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { remove(it) }
return true
}
override fun retainAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
val contains = elements.filter { map[it.key] == it.value }
map.clear()
map.resize(contains.size)
addAll(contains)
return true
}
}
class MapIterator<K : Comparable<K>, V>(private val map: ArrayMap<K, V>) : MutableIterator<MutableMap.MutableEntry<K, V>> {
private var index = 0
override fun hasNext(): Boolean {
@Suppress("ControlFlowWithEmptyBody")
while (++index < map.arr.size && index < map.end && map.arr[index] == null);
index--
return index < map.end
}
override fun next(): MutableMap.MutableEntry<K, V> = map.arr[index++]!!
override fun remove() {
map.delete(index)
index--
}
}
class KeySet<K : Comparable<K>>(private val map: ArrayMap<K, *>) : MutableSet<K> {
override val size: Int get() = map.size
override fun contains(element: K): Boolean = map.containsKey(element)
override fun isEmpty(): Boolean = size == 0
override fun iterator(): MutableIterator<K> = KeyIterator(map)
override fun containsAll(elements: Collection<K>): Boolean {
elements.forEach {
if (!map.containsKey(it)) return false
}
return true
}
override fun add(element: K): Boolean = false
override fun addAll(elements: Collection<K>): Boolean = false
override fun clear() = map.clear()
override fun retainAll(elements: Collection<K>): Boolean = map.entries.retainAll(elements.map { map.getNode(it) }.filterNotNull())
override fun remove(element: K): Boolean = map.remove(element) != null
override fun removeAll(elements: Collection<K>): Boolean {
elements.forEach { remove(it) }
return true
}
}
class KeyIterator<K : Comparable<K>>(map: ArrayMap<K, *>) : MutableIterator<K> {
private val iterator = map.iterator()
override fun hasNext(): Boolean = iterator.hasNext()
override fun next(): K = iterator.next().key
override fun remove() = iterator.remove()
}
class ValueCollection<V>(private val map: ArrayMap<*, V>) : MutableCollection<V> {
override val size: Int get() = map.size
override fun contains(element: V): Boolean = map.containsValue(element)
override fun isEmpty(): Boolean = size == 0
override fun iterator(): MutableIterator<V> = ValueIterator(map)
override fun add(element: V): Boolean = false
override fun addAll(elements: Collection<V>): Boolean = false
override fun clear() = map.clear()
override fun remove(element: V): Boolean = false
override fun removeAll(elements: Collection<V>): Boolean = false
override fun retainAll(elements: Collection<V>): Boolean = false
override fun containsAll(elements: Collection<V>): Boolean {
elements.forEach {
if (!map.containsValue(it)) return false
}
return true
}
}
class ValueIterator<V>(map: ArrayMap<*, V>) : MutableIterator<V> {
private val iterator = map.iterator()
override fun hasNext(): Boolean = iterator.hasNext()
override fun next(): V = iterator.next().value
override fun remove() = iterator.remove()
}
class ValueIterator<V>(map: ArrayMap<*, V>) : MutableIterator<V> {
private val iterator = map.iterator()
override fun hasNext(): Boolean = iterator.hasNext()
override fun next(): V = iterator.next().value
override fun remove() = iterator.remove()
}
}

View File

@ -0,0 +1,27 @@
package cn.tursom.core.datastruct
@Suppress("MemberVisibilityCanBePrivate")
class ComparableArrayMap<K : Comparable<K>, V>(initialCapacity: Int = 16) : ArrayMap<K, V>(initialCapacity) {
/**
* @param key 查找的键
* @return 键所在的下标
* @return < 0 如果键不存在, -${return} - 1 为如果插入应插入的下标
*/
override fun search(key: K): Int {
if (end == 0) return -1
return arr.binarySearch(key, 0, end)
}
override infix fun putAll(from: Map<out K, V>) {
from.forEach { (key, value) ->
val index = search(key)
if (index < 0) arr[end++] = Node(key, value)
else {
val node = arr[index]
if (node != null) node.value = value
else arr[index] = Node(key, value)
}
}
arr.sort()
}
}

View File

@ -0,0 +1,203 @@
package cn.tursom.core.datastruct
import cn.tursom.core.cast
@Suppress("MemberVisibilityCanBePrivate")
open class ParallelArrayMap<K, V>(initialCapacity: Int = 16) : SimpMap<K, V> {
@Volatile
protected var arr: Array<Any?> = Array(initialCapacity) { null }
@Volatile
protected var arrValue: Array<Any?> = Array(initialCapacity) { null }
@Volatile
protected var end = 0
override val size: Int get() = end
@Suppress("LeakingThis")
override val entries: MutableSet<MutableMap.MutableEntry<K, V>> = EntrySet(this)
override val keys: MutableSet<K> get() = arrValue.asList().subList(0, end).toMutableSet().cast()
override val values: MutableCollection<V> get() = arrValue.asList().cast<MutableList<V>>().subList(0, end)
/**
* @param key 查找的键
* @return 键所在的下标
* @return < 0 如果键不存在, -${return} - 1 为如果插入应插入的下标
*/
open fun search(key: K): Int {
if (end == 0) return -1
for (index in 0 until end) {
if ((arr[index] ?: continue) == key) {
return index
}
}
return -1
}
private fun resize(newSize: Int = if (arr.isNotEmpty()) arr.size * 2 else 1) {
arr = arr.copyOf(newSize)
arrValue = arrValue.copyOf(newSize)
}
override fun setAndGet(key: K, value: V): V? {
var index = search(key)
if (index < 0 || index >= end) {
if (end == arr.size) {
resize()
}
index = end++
arr[index] = key
}
return setByIndex(index, value)
}
override fun set(key: K, value: V) {
setAndGet(key, value)
}
fun setByIndex(index: Int, value: V): V? {
val oldValue = arrValue[end]
arrValue[index] = value
return oldValue.cast()
}
override fun delete(key: K): V? {
return deleteByIndex(search(key))
}
fun deleteByIndex(index: Int): V? {
if (index < 0 || index >= end) return null
val oldValue = arrValue[index]
System.arraycopy(arr, index + 1, arr, index, end - index - 1)
System.arraycopy(arrValue, index + 1, arrValue, index, end - index - 1)
end--
return oldValue.cast()
}
override fun clear() {
end = 0
}
override fun first(): V? {
return if (end <= 0) {
null
} else {
arrValue[0].cast()
}
}
override fun containsKey(key: K): Boolean {
return search(key) >= 0
}
override fun containsValue(value: V): Boolean {
if (end == 0) return false
for (index in 0 until end) {
if ((arrValue[index] ?: continue) == value) {
return true
}
}
return false
}
override fun get(key: K): V? {
return getByIndex(search(key))
}
fun getKeyByIndex(index: Int): K? {
return if (index < 0 || index >= end) {
null
} else {
arr[index].cast()
}
}
fun getByIndex(index: Int): V? {
return if (index < 0 || index >= end) {
null
} else {
arrValue[index].cast()
}
}
override fun isEmpty(): Boolean = end <= 0
class EntrySet<K, V>(private val map: ParallelArrayMap<K, V>) : MutableSet<MutableMap.MutableEntry<K, V>> {
override val size: Int get() = map.size
override fun contains(element: MutableMap.MutableEntry<K, V>): Boolean = map[element.key] == element.value
override fun isEmpty(): Boolean = map.isEmpty()
override fun iterator(): MutableIterator<MutableMap.MutableEntry<K, V>> = MapIterator(map)
override fun clear() = map.clear()
override fun containsAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach {
if (!contains(it)) return false
}
return true
}
override fun add(element: MutableMap.MutableEntry<K, V>): Boolean {
map[element.key] = element.value
return true
}
override fun addAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { add(it) }
return true
}
override fun remove(element: MutableMap.MutableEntry<K, V>): Boolean {
val index = map.search(element.key)
val value = map.getByIndex(index)
return if (value == element.value) {
map.deleteByIndex(index)
true
} else {
false
}
}
override fun removeAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
elements.forEach { remove(it) }
return true
}
override fun retainAll(elements: Collection<MutableMap.MutableEntry<K, V>>): Boolean {
val contains = elements.filter { map[it.key] == it.value }
map.clear()
map.resize(contains.size)
addAll(contains)
return true
}
}
class MapIterator<K, V>(private val map: ParallelArrayMap<K, V>) : MutableIterator<MutableMap.MutableEntry<K, V>> {
private var index = 0
override fun hasNext(): Boolean {
@Suppress("ControlFlowWithEmptyBody")
while (++index < map.arr.size && index < map.end && map.arr[index] == null);
index--
return index < map.end
}
override fun next(): MutableMap.MutableEntry<K, V> = ParallelArrayMapEntry(map, index++)
override fun remove() {
map.deleteByIndex(index)
index--
}
}
class ParallelArrayMapEntry<K, V>(
val map: ParallelArrayMap<K, V>,
val index: Int
) : MutableMap.MutableEntry<K, V> {
override val key: K get() = map.getKeyByIndex(index).cast()
override val value: V get() = map.getByIndex(index).cast()
override fun setValue(newValue: V): V {
return map.setByIndex(index, newValue).cast()
}
}
}

View File

@ -0,0 +1,15 @@
package cn.tursom.core.stream.impl
import java.io.InputStream
class JavaInputStreamProxy(
val inputStream: cn.tursom.core.stream.InputStream
) : InputStream() {
override fun read(): Int = inputStream.read()
override fun read(b: ByteArray, off: Int, len: Int): Int = inputStream.read(b, off, len)
override fun skip(n: Long): Long {
inputStream.skip(n)
return n
}
}

View File

@ -0,0 +1,39 @@
package cn.tursom.utils.coroutine
import cn.tursom.core.cast
import kotlinx.coroutines.Job
import java.util.concurrent.ConcurrentHashMap
import kotlin.coroutines.coroutineContext
open class CoroutineLocal<T> {
open suspend fun get(): T? {
var attach: MutableMap<CoroutineLocal<*>, Any?>? = coroutineContext[CoroutineLocalContext]
if (attach == null) {
val job = coroutineContext[Job] ?: return null
attach = attachMap[job]
}
return attach?.get(this)?.cast()
}
open suspend infix fun set(value: T): Boolean {
var attach: MutableMap<CoroutineLocal<*>, Any?>? = coroutineContext[CoroutineLocalContext]
if (attach == null) {
val job = coroutineContext[Job] ?: return false
attach = attachMap[job]
if (attach == null) {
attach = HashMap()
attachMap[job] = attach
job.invokeOnCompletion {
attachMap.remove(job)
}
}
}
attach[this] = value
return true
}
companion object {
private val attachMap = ConcurrentHashMap<Job, MutableMap<CoroutineLocal<*>, Any?>>()
override fun toString(): String = attachMap.toString()
}
}

View File

@ -0,0 +1,43 @@
package cn.tursom.utils.coroutine
import kotlinx.coroutines.*
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext
open class CoroutineLocalContext(
private val map: MutableMap<CoroutineLocal<*>, Any?> = HashMap(4)
) : CoroutineContext.Element, MutableMap<CoroutineLocal<*>, Any?> by map {
override val key: CoroutineContext.Key<*> get() = Companion
override fun toString(): String {
return map.toString()
}
companion object : CoroutineContext.Key<CoroutineLocalContext>
}
fun CoroutineScope.launchWithCoroutineLocalContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
map: MutableMap<CoroutineLocal<*>, Any?> = HashMap(4),
block: suspend CoroutineScope.() -> Unit
): Job {
return launch(context + CoroutineLocalContext(map), start, block)
}
@Suppress("DeferredIsResult")
fun <T> CoroutineScope.asyncWithCoroutineLocalContext(
context: CoroutineContext = EmptyCoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
map: MutableMap<CoroutineLocal<*>, Any?> = HashMap(4),
block: suspend CoroutineScope.() -> T
): Deferred<T> {
return async(context + CoroutineLocalContext(map), start, block)
}
suspend fun <T> withCoroutineLocalContext(
map: MutableMap<CoroutineLocal<*>, Any?> = HashMap(4),
block: suspend CoroutineScope.() -> T
): T {
return withContext(CoroutineLocalContext(map), block)
}

View File

@ -0,0 +1,32 @@
package cn.tursom.utils.coroutine
import cn.tursom.core.usingTime
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.coroutineScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
val testCoroutineLocal = CoroutineLocal<Int>()
val testCoroutineLocalList = Array(100000) {
CoroutineLocal<Int>()
}.asList()
suspend fun main() {
println(testCoroutineLocal.set(1))
GlobalScope.launch {
coroutineScope { }
coroutineContext
testCoroutineLocal set 0
testCoroutineLocal set 0
testCoroutineLocalList.forEachIndexed { index, coroutineLocal ->
coroutineLocal set index
}
println(usingTime {
repeat(1000000000) {
testCoroutineLocal.get()
}
})
}.join()
delay(1000)
println(CoroutineLocal)
}