update kotlinx-coroutines-core version

This commit is contained in:
tursom 2021-07-09 20:29:24 +08:00
parent 8fbb4ea929
commit 7a90928246
26 changed files with 6 additions and 1090 deletions

View File

@ -8,7 +8,7 @@ dependencies {
api(project(":ts-core"))
api(project(":ts-core:ts-buffer"))
implementation(project(":ts-core:ts-xml"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
api(group = "com.squareup.retrofit2", name = "converter-gson", version = "2.9.0")
// https://mvnrepository.com/artifact/com.squareup.retrofit2/retrofit
api(group = "com.squareup.retrofit2", name = "retrofit", version = "2.9.0")

View File

@ -5,7 +5,7 @@ plugins {
dependencies {
implementation(project(":ts-core"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
}
@kotlin.Suppress("UNCHECKED_CAST")

View File

@ -5,7 +5,7 @@ plugins {
dependencies {
implementation(project(":ts-core"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
}
@kotlin.Suppress("UNCHECKED_CAST")

View File

@ -8,7 +8,7 @@ dependencies {
implementation(project(":ts-core"))
implementation(project(":ts-core:ts-datastruct"))
implementation(project(":ts-core:ts-log"))
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
api("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
api(group = "org.mongodb", name = "mongodb-driver-reactivestreams", version = "4.0.5")
}

View File

@ -9,7 +9,7 @@ dependencies {
implementation(project(":ts-core:ts-buffer"))
implementation(project(":ts-core:ts-pool"))
implementation(project(":ts-core:ts-log"))
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
}
@kotlin.Suppress("UNCHECKED_CAST")

View File

@ -9,7 +9,7 @@ dependencies {
implementation(project(":ts-core:ts-buffer"))
implementation(project(":ts-core:ts-json"))
implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.29")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2")
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-core:1.5.0")
}
@kotlin.Suppress("UNCHECKED_CAST")

View File

@ -1,12 +0,0 @@
dependencies {
compile project(":")
api "com.google.code.gson:gson:2.8.2"
// kotlin
api 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.2'
// kotlin
api "org.jetbrains.kotlin:kotlin-reflect:$kotlinVersion"
//
api 'org.apache.lucene:lucene-core:4.0.0'
api group: "io.netty", name: "netty-all", version: "4.1.43.Final"
api group: "io.netty", name: "netty-all", version: "4.1.43.Final"
}

View File

@ -1,36 +0,0 @@
package cn.tursom.utils
import java.io.*
import java.util.zip.GZIPInputStream
import java.util.zip.GZIPOutputStream
object Gzip {
fun compress(data: ByteArray): ByteArray {
val out = ByteArrayOutputStream()
compress(data, out)
return out.toByteArray()
}
fun compress(data: ByteArray, out: OutputStream) {
val gzip = GZIPOutputStream(out)
gzip.write(data)
gzip.close()
}
fun uncompress(bytes: ByteArray): ByteArray {
return uncompress(ByteArrayInputStream(bytes)).readBytes()
}
fun uncompress(inputStream: InputStream): InputStream {
return GZIPInputStream(inputStream)
}
class GzipBuilder(private val out: OutputStream = ByteArrayOutputStream()) : Closeable {
private val gzip = GZIPOutputStream(out)
fun write(byte: Int) = gzip.write(byte)
fun write(bytes: ByteArray) = gzip.write(bytes)
fun write(bytes: ByteArray, offset: Int, len: Int) = gzip.write(bytes, offset, len)
fun get(): ByteArray = (out as ByteArrayOutputStream).toByteArray()
override fun close() = gzip.close()
}
}

View File

@ -1,73 +0,0 @@
package cn.tursom.utils
import cn.tursom.core.base64
import cn.tursom.core.base64decode
import cn.tursom.core.digest
import cn.tursom.core.toHexString
import java.lang.Exception
import kotlin.experimental.xor
open class TokenUtil {
@Suppress("MemberVisibilityCanBePrivate", "CanBeParameter")
enum class DigestType(val digest: String) {
MD5("MD5"), SHA256("SHA-256"), SHA512("SHA-512");
val digestBase64: String = digest.base64()
}
fun <T : Token> generate(secretKey: String, data: T, type: DigestType = DigestType.MD5): String {
val head = type.digestBase64
val body = toJson(data).base64()
val encryptSource = "$head.$body".toByteArray()
val encrypt = encrypt(secretKey, encryptSource, type.digest)
return "$head.$body.$encrypt"
}
@Throws(TokenException::class)
fun <T : Token> decode(secretKey: String, token: String, dataClazz: Class<T>): T {
val splitToken = token.split(".")
if (splitToken.size != 3) {
throw WrongTokenSyntaxException()
}
val signature = encrypt(secretKey, "${splitToken[0]}.${splitToken[1]}".toByteArray(), splitToken[0].base64decode())
if (signature != splitToken[2]) {
throw WrongSignatureException()
}
val decode = fromJson(splitToken[1].base64decode(), dataClazz)
if (decode.tim + decode.exp < System.currentTimeMillis()) {
throw TokenTimeoutException()
}
return decode
}
protected open fun encrypt(secretKey: String, encryptSource: ByteArray, type: String): String {
val inner = secretKey.toByteArray().digest(type)!!
encryptSource.forEachIndexed { index, _ ->
encryptSource[index] = encryptSource[index] xor inner[index % inner.size]
}
val digest1 = encryptSource.digest(type)!!
digest1.forEachIndexed { index, _ ->
digest1[index] = digest1[index] xor inner[index % inner.size]
}
return digest1.digest(type)!!.toHexString()!!
}
open fun toJson(bean: Any): String = gson.toJson(bean)
open fun <T> fromJson(json: String, clazz: Class<T>): T = gson.fromJson(json, clazz)
interface Token {
val tim: Long
val exp: Long
}
open class TokenException : Exception()
class WrongTokenSyntaxException : TokenException()
class WrongSignatureException : TokenException()
class TokenTimeoutException : TokenException()
companion object {
@JvmStatic
val gsonTokenUtil = TokenUtil()
}
}

View File

@ -1,52 +0,0 @@
package cn.tursom.utils
import com.google.gson.Gson
import com.google.gson.GsonBuilder
import com.google.gson.reflect.TypeToken
import kotlinx.coroutines.*
import java.util.concurrent.Executor
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException
import kotlin.coroutines.suspendCoroutine
@Suppress("unused", "SpellCheckingInspection")
val gson = GsonBuilder()
.registerTypeAdapterFactory(GsonDataTypeAdaptor.FACTORY)
.create()
@Suppress("unused", "SpellCheckingInspection")
val prettyGson = GsonBuilder()
.registerTypeAdapterFactory(GsonDataTypeAdaptor.FACTORY)
.setPrettyPrinting()
.create()
fun Any.toJson(): String = gson.toJson(this)
fun Any.toPrettyJson(): String = prettyGson.toJson(this)
//inline fun <reified T : Any> String.fromJson(): T = gson.fromJson(this, T::class.java)
inline fun <reified T : Any> Gson.fromJson(json: String) = this.fromJson<T>(json, object : TypeToken<T>() {}.type)
inline fun <reified T : Any> String.fromJson(gson: Gson = cn.tursom.utils.gson) = gson.fromJson<T>(this, object : TypeToken<T>() {}.type)!!
suspend fun <T> io(block: suspend CoroutineScope.() -> T): T {
return withContext(Dispatchers.IO, block)
}
fun background(block: suspend CoroutineScope.() -> Unit) {
GlobalScope.launch(block = block)
}
suspend fun <T> ui(block: suspend CoroutineScope.() -> T): T {
return withContext(Dispatchers.Main, block)
}
suspend operator fun <T> Executor.invoke(action: () -> T): T {
return suspendCoroutine { exec ->
execute {
try {
exec.resume(action())
} catch (e: Throwable) {
exec.resumeWithException(e)
}
}
}
}

View File

@ -1,112 +0,0 @@
package cn.tursom.utils.cache
import cn.tursom.utils.cache.interfaces.AsyncPotableCacheMap
import cn.tursom.utils.datastruct.async.ReadWriteLockHashMap
import cn.tursom.core.datastruct.async.interfaces.AsyncCollection
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
import cn.tursom.core.datastruct.async.interfaces.AsyncSet
import java.lang.ref.SoftReference
class AsyncSoftCacheMap<K, V>(
val timeout: Long,
private val valueMap: AsyncPotableMap<K, SoftReference<Pair<Long, V>>> = ReadWriteLockHashMap()
) : AsyncPotableCacheMap<K, V> {
override val size: Int
get() = valueMap.size
override val entries: AsyncSet<Map.Entry<K, V>> = Entries()
override val keys: AsyncSet<K> = valueMap.keys
override val values: AsyncCollection<V> = Values()
override suspend fun containsKey(key: K): Boolean = valueMap.containsKey(key)
override suspend fun containsValue(value: V): Boolean = !valueMap.forEach { it.value != value }
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun get(key: K): V? = getCache(key)
override suspend fun get(key: K, constructor: suspend () -> V): V {
return get(key) ?: run {
val newValue = constructor()
addCache(key, newValue)
newValue
}
}
override suspend fun set(key: K, value: V): V? {
valueMap.set(key, SoftReference(System.currentTimeMillis() to value))
return value
}
override suspend fun putIfAbsent(key: K, value: V): Boolean {
return valueMap.putIfAbsent(key, SoftReference(System.currentTimeMillis() to value))
}
override suspend fun putAll(from: Map<out K, V>) {
from.forEach { (k, v) ->
valueMap.set(k, SoftReference(System.currentTimeMillis() to v))
}
}
override suspend fun remove(key: K): V? = valueMap.remove(key)?.get()?.second
override suspend fun clear() {
valueMap.clear()
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return valueMap.forEach {
@Suppress("LABEL_NAME_CLASH")
action(Entry(it.key, it.value.get()?.second ?: return@forEach true))
}
}
private suspend fun getCache(key: K): V? {
val cache = valueMap.get(key)?.get() ?: return null
if (cache.first.isTimeOut()) {
delCache(key)
return null
}
return cache.second
}
private suspend fun delCache(key: K) {
valueMap.remove(key)
}
private suspend fun addCache(key: K, value: V) {
valueMap.set(key, SoftReference(System.currentTimeMillis() to value))
}
private fun Long?.isTimeOut() = this != null && timeout != 0L && System.currentTimeMillis() - this > timeout
data class Entry<K, V>(override val key: K, override val value: V) : Map.Entry<K, V>
inner class Entries : AsyncSet<Map.Entry<K, V>> {
override val size: Int get() = valueMap.size
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun contains(element: Map.Entry<K, V>): Boolean = contains(element)
override suspend fun containsAll(elements: AsyncCollection<Map.Entry<K, V>>): Boolean = containsAll(elements)
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean =
this@AsyncSoftCacheMap.forEach(action)
}
inner class Values : AsyncCollection<V> {
override val size: Int get() = valueMap.size
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun contains(element: V): Boolean = containsValue(element)
override suspend fun containsAll(elements: AsyncCollection<V>): Boolean {
return elements.forEach { contains(it) }
}
override suspend fun forEach(action: suspend (V) -> Boolean): Boolean {
return valueMap.forEach {
@Suppress("LABEL_NAME_CLASH")
action(it.value.get()?.second ?: return@forEach true)
}
}
}
}

View File

@ -1,109 +0,0 @@
package cn.tursom.utils.cache
import cn.tursom.utils.cache.interfaces.AsyncPotableCacheMap
import cn.tursom.utils.datastruct.async.ReadWriteLockHashMap
import cn.tursom.core.datastruct.async.interfaces.AsyncCollection
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
import cn.tursom.core.datastruct.async.interfaces.AsyncSet
open class DefaultAsyncPotableCacheMap<K, V>(
val timeout: Long,
private val valueMap: AsyncPotableMap<K, Pair<Long, V>> = ReadWriteLockHashMap()
) : AsyncPotableCacheMap<K, V> {
override val size: Int
get() = valueMap.size
override val entries: AsyncSet<Map.Entry<K, V>> = Entries()
override val keys: AsyncSet<K> = valueMap.keys
override val values: AsyncCollection<V> = Values()
override suspend fun containsKey(key: K): Boolean = valueMap.containsKey(key)
override suspend fun containsValue(value: V): Boolean = !valueMap.forEach { it.value != value }
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun get(key: K): V? {
val value = getCache(key) ?: return null
return value
}
override suspend fun get(key: K, constructor: suspend () -> V): V {
val value = get(key) ?: run {
val newValue = constructor()
addCache(key, newValue)
newValue
}
return value
}
override suspend fun set(key: K, value: V): V? {
valueMap.set(key, System.currentTimeMillis() to value)
return value
}
override suspend fun putIfAbsent(key: K, value: V): Boolean {
return valueMap.putIfAbsent(key, System.currentTimeMillis() to value)
}
override suspend fun putAll(from: Map<out K, V>) {
from.forEach { (k, v) ->
valueMap.set(k, System.currentTimeMillis() to v)
}
}
override suspend fun remove(key: K): V? = valueMap.remove(key)?.second
override suspend fun clear() {
valueMap.clear()
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return valueMap.forEach { action(Entry(it.key, it.value.second)) }
}
private suspend fun getCache(key: K): V? {
val cache = valueMap.get(key) ?: return null
if (cache.first.isTimeOut()) {
delCache(key)
return null
}
return cache.second
}
private suspend fun delCache(key: K) {
valueMap.remove(key)
}
private suspend fun addCache(key: K, value: V) {
valueMap.set(key, System.currentTimeMillis() to value)
}
private fun Long.isTimeOut() = timeout != 0L && System.currentTimeMillis() - this > timeout
data class Entry<K, V>(override val key: K, override val value: V) : Map.Entry<K, V>
inner class Entries : AsyncSet<Map.Entry<K, V>> {
override val size: Int get() = valueMap.size
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun contains(element: Map.Entry<K, V>): Boolean = contains(element)
override suspend fun containsAll(elements: AsyncCollection<Map.Entry<K, V>>): Boolean = containsAll(elements)
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean =
this@DefaultAsyncPotableCacheMap.forEach(action)
}
inner class Values : AsyncCollection<V> {
override val size: Int get() = valueMap.size
override suspend fun isEmpty(): Boolean = valueMap.isEmpty()
override suspend fun contains(element: V): Boolean = containsValue(element)
override suspend fun containsAll(elements: AsyncCollection<V>): Boolean {
return elements.forEach { contains(it) }
}
override suspend fun forEach(action: suspend (V) -> Boolean): Boolean {
return valueMap.forEach { action(it.value.second) }
}
}
}

View File

@ -1,7 +0,0 @@
package cn.tursom.utils.cache.interfaces
import cn.tursom.core.datastruct.async.interfaces.AsyncMap
interface AsyncCacheMap<K, V> : AsyncMap<K, V> {
suspend fun get(key: K, constructor: suspend () -> V): V
}

View File

@ -1,5 +0,0 @@
package cn.tursom.utils.cache.interfaces
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
interface AsyncPotableCacheMap<K, V> : AsyncCacheMap<K, V>, AsyncPotableMap<K, V>

View File

@ -1,18 +0,0 @@
package cn.tursom.utils.datastruct.async
import cn.tursom.utils.asynclock.AsyncReadFirstRWLock
import cn.tursom.utils.asynclock.AsyncWriteFirstRWLock
import cn.tursom.utils.datastruct.async.collections.AsyncMapSet
import cn.tursom.utils.datastruct.async.collections.AsyncRWLockAbstractMap
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
val <K : Comparable<K>> AsyncPotableMap<K, Unit>.keySet
get() = AsyncMapSet(this)
@Suppress("FunctionName")
fun <K, V> ReadWriteLockHashMap() = AsyncRWLockAbstractMap<K, V>(AsyncWriteFirstRWLock())
@Suppress("FunctionName")
fun <K, V> WriteLockHashMap() =
AsyncRWLockAbstractMap<K, V>(AsyncReadFirstRWLock())

View File

@ -1,115 +0,0 @@
package cn.tursom.utils.datastruct.async
import cn.tursom.utils.asynclock.AsyncReadFirstRWLock
class AsyncLinkSlot<K, V> {
private val lock = AsyncReadFirstRWLock()
@Volatile
private var node: Node<K, V>? = null
@Volatile
private var rSize = 0
val size: Int
get() = rSize
suspend fun clear() {
lock.doWrite {
node = null
rSize = 0
}
}
suspend fun put(key: K, value: V) {
node?.forEach {
if (it.key == key) {
it.value = value
return
}
}
lock.doWrite {
node = Node(key, value, node)
node?.prev = node
rSize++
}
}
suspend fun remove(key: K): V? {
return lock doWrite@{
node?.forEach {
if (it.key == key) {
if (it == node) {
node = it.next
it.next?.prev = null
} else {
it.prev?.next = it.next
it.next?.prev = it.prev
}
rSize--
return@doWrite it.value
}
}
null
}
}
suspend fun containsKey(key: K): Boolean {
return lock.doRead {
node?.forEach {
if (it.key == key) {
return@doRead true
}
}
false
}
}
suspend fun containsValue(value: V): Boolean {
return lock.doRead {
node?.forEach {
if (it.value == value) {
return@doRead true
}
}
false
}
}
suspend fun get(key: K): V? {
return lock.doRead {
node?.forEach {
if (it.key == key) {
return@doRead it.value
}
}
null
}
}
fun isEmpty(): Boolean {
return node == null
}
private data class Node<K, V>(
val key: K,
var value: V,
var next: Node<K, V>?,
var prev: Node<K, V>? = null
) : Iterable<Node<K, V>> {
override fun iterator(): Iterator<Node<K, V>> {
return NodeIterator(this)
}
}
private class NodeIterator<K, V>(private var node: Node<K, V>?) : Iterator<Node<K, V>> {
override fun hasNext(): Boolean {
return node != null
}
override fun next(): Node<K, V> {
val thisNode = node!!
node = node?.next
return thisNode
}
}
}

View File

@ -1,138 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncWriteFirstRWLock
import cn.tursom.core.datastruct.ArrayMap
import cn.tursom.core.datastruct.async.interfaces.AsyncCollection
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
import cn.tursom.core.datastruct.async.interfaces.AsyncSet
class AsyncArrayMap<K : Comparable<K>, V> : AsyncPotableMap<K, V> {
private val lock = AsyncWriteFirstRWLock()
private val map = ArrayMap<K, V>()
override val size: Int get() = map.size
override val entries: AsyncSet<Map.Entry<K, V>> = AsyncEntrySet(this)
override val keys: AsyncSet<K> = AsyncKeySet(this)
override val values: AsyncCollection<V> = AsyncValueCollection(this)
override suspend fun containsKey(key: K): Boolean {
return lock.doRead { map.containsKey(key) }
}
override suspend fun containsValue(value: V): Boolean {
return lock.doRead { map.containsValue(value) }
}
override suspend fun get(key: K): V? {
return lock.doRead { map[key] }
}
override suspend fun isEmpty(): Boolean {
return lock.doRead { map.isEmpty() }
}
override suspend fun clear() {
lock.doWrite { map.clear() }
}
override suspend fun set(key: K, value: V): V? {
return lock { map.setAndGet(key, value) }
}
override suspend fun putIfAbsent(key: K, value: V): Boolean {
return lock {
if (containsKey(key)) false
else {
map.setAndGet(key, value)
true
}
}
}
override suspend fun putAll(from: Map<out K, V>) {
return lock { map.putAll(from) }
}
override suspend fun remove(key: K): V? {
return lock { map.delete(key) }
}
override suspend fun contains(element: Map.Entry<K, V>): Boolean {
return get(element.key) == element.value
}
override suspend fun containsAll(elements: AsyncCollection<Map.Entry<K, V>>): Boolean {
return elements.forEach { contains(it) }
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return lock {
map.forEach { !action(it) }
true
}
}
class AsyncEntrySet<K : Comparable<K>, V>(private val map: AsyncArrayMap<K, V>) : AsyncSet<Map.Entry<K, V>> {
override val size: Int
get() = map.size
override suspend fun contains(element: Map.Entry<K, V>): Boolean {
return map.get(element.key) == element.value
}
override suspend fun containsAll(elements: AsyncCollection<Map.Entry<K, V>>): Boolean {
return elements.forEach { contains(it) }
}
override suspend fun isEmpty(): Boolean {
return map.isEmpty()
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return map.forEach(action)
}
}
class AsyncKeySet<K : Comparable<K>>(private val map: AsyncArrayMap<K, *>) : AsyncSet<K> {
override val size: Int
get() = map.size
override suspend fun contains(element: K): Boolean {
return map.containsKey(element)
}
override suspend fun containsAll(elements: AsyncCollection<K>): Boolean {
return elements.forEach { map.containsKey(it) }
}
override suspend fun isEmpty(): Boolean {
return size == 0
}
override suspend fun forEach(action: suspend (K) -> Boolean): Boolean {
return map.forEach { action(it.key) }
}
}
class AsyncValueCollection<V>(private val map: AsyncArrayMap<*, V>) : AsyncCollection<V> {
override val size: Int
get() = map.size
override suspend fun contains(element: V): Boolean {
return map.containsValue(element)
}
override suspend fun containsAll(elements: AsyncCollection<V>): Boolean {
return elements.forEach { !map.containsValue(it) }
}
override suspend fun isEmpty(): Boolean {
return size == 0
}
override suspend fun forEach(action: suspend (V) -> Boolean): Boolean {
return map.forEach { action(it.value) }
}
}
}

View File

@ -1,3 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
class AsyncArrayMapSet<K : Comparable<K>> : AsyncMapSet<K>(AsyncArrayMap())

View File

@ -1,44 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncLock
import cn.tursom.utils.asynclock.AsyncRWLock
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
class AsyncLockAbstractMap<K, V>(
override val lock: AsyncLock,
override val map: java.util.AbstractMap<K, V> = HashMap()
) : AsyncLockMap<K, V>(lock, map), AsyncPotableMap<K, V> {
override suspend fun clear() {
lock { map.clear() }
}
override suspend fun putIfAbsent(key: K, value: V): Boolean {
return lock {
if (map.containsKey(key)) false
else {
map[key] = value
true
}
}
}
override suspend fun putAll(from: Map<out K, V>) {
lock {
map.putAll(from)
}
}
constructor(lock: AsyncRWLock) : this(lock, HashMap())
override suspend fun set(key: K, value: V): V? {
return lock {
map.put(key, value)
}
}
override suspend fun remove(key: K): V? {
return lock { map.remove(key) }
}
override fun toString(): String = map.toString()
}

View File

@ -1,105 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncLock
import cn.tursom.core.datastruct.async.interfaces.AsyncCollection
import cn.tursom.core.datastruct.async.interfaces.AsyncMap
import cn.tursom.core.datastruct.async.interfaces.AsyncSet
open class AsyncLockMap<K, V>(
protected open val lock: AsyncLock,
protected open val map: Map<K, V>
) : AsyncMap<K, V> {
override val size: Int get() = map.size
override val entries: AsyncSet<Map.Entry<K, V>> = Entries()
override val keys: AsyncSet<K> = Keys()
override val values: AsyncCollection<V> = Values()
override suspend fun containsKey(key: K): Boolean {
return lock { map.containsKey(key) }
}
override suspend fun containsValue(value: V): Boolean {
return lock { map.containsValue(value) }
}
override suspend fun isEmpty(): Boolean {
return lock { map.isEmpty() }
}
override suspend fun get(key: K): V? {
return lock { map[key] }
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return lock {
map.forEach {
if (!action(it)) return@lock false
}
true
}
}
override fun toString(): String = map.toString()
inner class Entries : AsyncSet<Map.Entry<K, V>> {
override val size: Int get() = this@AsyncLockMap.size
override suspend fun isEmpty(): Boolean {
return this@AsyncLockMap.isEmpty()
}
override suspend fun contains(element: Map.Entry<K, V>): Boolean {
return contains(element)
}
override suspend fun containsAll(elements: AsyncCollection<Map.Entry<K, V>>): Boolean {
return containsAll(elements)
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return this@AsyncLockMap.forEach { action(it) }
}
}
inner class Keys : AsyncSet<K> {
override val size: Int
get() = this@AsyncLockMap.size
override suspend fun isEmpty(): Boolean {
return this@AsyncLockMap.isEmpty()
}
override suspend fun contains(element: K): Boolean {
return containsKey(element)
}
override suspend fun containsAll(elements: AsyncCollection<K>): Boolean {
return elements.forEach { containsKey(it) }
}
override suspend fun forEach(action: suspend (K) -> Boolean): Boolean {
return this@AsyncLockMap.forEach { action(it.key) }
}
}
inner class Values : AsyncCollection<V> {
override val size: Int
get() = this@AsyncLockMap.size
override suspend fun isEmpty(): Boolean {
return this@AsyncLockMap.isEmpty()
}
override suspend fun contains(element: V): Boolean {
return containsValue(element)
}
override suspend fun containsAll(elements: AsyncCollection<V>): Boolean {
return elements.forEach { containsValue(it) }
}
override suspend fun forEach(action: suspend (V) -> Boolean): Boolean {
return this@AsyncLockMap.forEach { action(it.value) }
}
}
}

View File

@ -1,52 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncWriteFirstRWLock
import cn.tursom.core.datastruct.SetMap
import cn.tursom.core.datastruct.async.interfaces.AsyncCollection
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableSet
open class AsyncMapSet<K>(private val map: AsyncPotableMap<K, Unit> = AsyncRWLockAbstractMap(AsyncWriteFirstRWLock())) : AsyncPotableSet<K> {
override val size: Int get() = map.size
override suspend fun isEmpty(): Boolean {
return size == 0
}
override suspend fun contains(element: K): Boolean {
return map.containsKey(element)
}
override suspend fun containsAll(elements: AsyncCollection<K>): Boolean {
return elements.forEach { map.containsKey(it) }
}
override suspend fun clear(): AsyncPotableSet<K> {
map.clear()
return this
}
override suspend fun put(key: K): AsyncPotableSet<K> {
map.set(key, Unit)
return this
}
override suspend fun putIfAbsent(key: K): Boolean {
return map.putIfAbsent(key, Unit)
}
override suspend fun putAll(from: Set<K>): AsyncPotableSet<K> {
map.putAll(SetMap(from))
return this
}
override suspend fun remove(key: K): AsyncPotableSet<K> {
map.remove(key)
return this
}
override suspend fun forEach(action: suspend (K) -> Boolean): Boolean {
return map.forEach { action(it.key) }
}
}

View File

@ -1,45 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncRWLock
import cn.tursom.core.datastruct.async.interfaces.AsyncPotableMap
class AsyncRWLockAbstractMap<K, V>(
lock: AsyncRWLock,
override val map: java.util.AbstractMap<K, V> = HashMap()
) : AsyncRWLockMap<K, V>(lock, map), AsyncPotableMap<K, V> {
constructor(lock: AsyncRWLock) : this(lock, HashMap())
override suspend fun set(key: K, value: V): V? {
return lock.doWrite {
map.put(key, value)
}
}
override suspend fun remove(key: K): V? {
return lock.doWrite { map.remove(key) }
}
override suspend fun clear() {
lock { map.clear() }
}
override suspend fun putIfAbsent(key: K, value: V): Boolean {
return lock {
if (map.containsKey(key)) false
else {
map[key] = value
true
}
}
}
override suspend fun putAll(from: Map<out K, V>) {
lock {
from.forEach { (k, u) ->
map[k] = u
}
}
}
override fun toString(): String = map.toString()
}

View File

@ -1,37 +0,0 @@
package cn.tursom.utils.datastruct.async.collections
import cn.tursom.utils.asynclock.AsyncRWLock
open class AsyncRWLockMap<K, V>(
override val lock: AsyncRWLock,
map: Map<K, V>
) : AsyncLockMap<K, V>(lock, map) {
override suspend fun isEmpty(): Boolean {
return lock.doRead { map.isEmpty() }
}
override suspend fun isNotEmpty(): Boolean {
return lock.doRead { map.isNotEmpty() }
}
override suspend fun get(key: K): V? {
return lock.doRead { map[key] }
}
override suspend fun containsKey(key: K): Boolean {
return lock.doRead { map.containsKey(key) }
}
override suspend fun containsValue(value: V): Boolean {
return lock.doRead { map.containsValue(value) }
}
override suspend fun forEach(action: suspend (Map.Entry<K, V>) -> Boolean): Boolean {
return lock.doRead {
map.forEach {
if (!action(it)) return@doRead false
}
true
}
}
}

View File

@ -1,58 +0,0 @@
package cn.tursom.utils.storage
import cn.tursom.core.storage.StorageHandler
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.concurrent.atomic.AtomicBoolean
class AsyncBufferedStorageHandler<T>(
// 最小缓冲时间
private val minBufTime: Long = 500,
private val singleThreadWrite: Boolean = true,
// 数据批量写入处理器
private val writeHandler: suspend (list: Collection<T>) -> Unit
) : StorageHandler<T> {
private val onWrite = AtomicBoolean(false)
@Volatile
private var msgList = ConcurrentLinkedQueue<T>()
private val write = object {
suspend operator fun invoke() {
val list = msgList
delay(minBufTime)
msgList = ConcurrentLinkedQueue()
// 可能还有未释放 msgList 对象的线程,要稍微等待一下
delay(1)
if (singleThreadWrite) {
try {
writeHandler(list)
} finally {
if (msgList.isNotEmpty()) {
val write = this
GlobalScope.launch { write() }
} else {
onWrite.set(false)
}
}
} else {
onWrite.set(false)
writeHandler(list)
}
}
}
/**
* 向缓冲中添加一个写入对象
*/
override fun add(obj: T) {
msgList.add(obj)
if (onWrite.compareAndSet(false, true)) {
GlobalScope.launch {
write()
}
}
}
}

View File

@ -1 +0,0 @@
cn.tursom.utils.coroutine.MainDispatcherFactory

View File

@ -1,62 +0,0 @@
package cn.tursom.utils.coroutine
import kotlinx.coroutines.*
import kotlin.coroutines.ContinuationInterceptor
import kotlin.coroutines.coroutineContext
val testCoroutineLocal = CoroutineLocal<Int>()
suspend fun testCustomContext() {
testCoroutineLocal.set(1)
testInlineCustomContext()
}
suspend fun testInlineCustomContext() {
println(coroutineContext)
println("===================")
}
annotation class Request(val url: String, val method: String = "GET")
interface CoroutineLocalTest {
@Request("http://tursom.cn:15015/living")
suspend fun test(): String
}
class Test : CoroutineScope by MainScope() {
suspend fun test() {
testCoroutineLocal.set(1)
println(coroutineContext)
coroutineScope {
println(coroutineContext)
delay(1)
}
}
}
object R : () -> R {
override fun invoke(): R = this
}
val threadLocal = ThreadLocal<String>()
fun main() = runBlocking {
println(coroutineContext[ContinuationInterceptor])
MainDispatcher.init()
runOnUiThread(threadLocal.asContextElement()) {
threadLocal.set("hello")
//Test().test()
//println(testCoroutineLocal.get())
println(threadLocal.get())
println(coroutineContext)
launch(Dispatchers.Main) {
println(threadLocal.get())
println(coroutineContext)
}
//runOnUiThread {
// println(coroutineContext)
// println(testCoroutineLocal.get())
//}
}
MainDispatcher.close()
}