Improve utils
parent
60f1fb1f70
commit
3b173dc6fc
@ -1,37 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.parsers.util
|
|
||||||
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
import java.lang.ref.SoftReference
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Like a [SuspendLazy] but with [SoftReference] under the hood
|
|
||||||
*/
|
|
||||||
public class SoftSuspendLazy<T : Any>(
|
|
||||||
private val initializer: suspend () -> T,
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val mutex = Mutex()
|
|
||||||
private var cachedValue: SoftReference<T>? = null
|
|
||||||
|
|
||||||
public suspend fun get(): T {
|
|
||||||
// fast way
|
|
||||||
cachedValue?.get()?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
return mutex.withLock {
|
|
||||||
cachedValue?.get()?.let {
|
|
||||||
return it
|
|
||||||
}
|
|
||||||
val result = initializer()
|
|
||||||
cachedValue = SoftReference(result)
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public suspend fun tryGet(): Result<T> = runCatchingCancellable { get() }
|
|
||||||
|
|
||||||
public fun peek(): T? {
|
|
||||||
return cachedValue?.get()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,41 +0,0 @@
|
|||||||
package org.koitharu.kotatsu.parsers.util
|
|
||||||
|
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
import kotlinx.coroutines.sync.withLock
|
|
||||||
|
|
||||||
public class SuspendLazy<T>(
|
|
||||||
private val initializer: suspend () -> T,
|
|
||||||
) {
|
|
||||||
|
|
||||||
private val mutex = Mutex()
|
|
||||||
private var cachedValue: Any? = Uninitialized
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public suspend fun get(): T {
|
|
||||||
// fast way
|
|
||||||
cachedValue.let {
|
|
||||||
if (it !== Uninitialized) {
|
|
||||||
return it as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return mutex.withLock {
|
|
||||||
cachedValue.let {
|
|
||||||
if (it !== Uninitialized) {
|
|
||||||
return it as T
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val result = initializer()
|
|
||||||
cachedValue = result
|
|
||||||
result
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public suspend fun tryGet(): Result<T> = runCatchingCancellable { get() }
|
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
|
||||||
public fun peek(): T? {
|
|
||||||
return cachedValue?.takeUnless { it === Uninitialized } as T?
|
|
||||||
}
|
|
||||||
|
|
||||||
private object Uninitialized
|
|
||||||
}
|
|
||||||
@ -0,0 +1,41 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.util.suspendlazy
|
||||||
|
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import java.lang.ref.SoftReference
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Like a [SuspendLazy] but with [SoftReference] under the hood
|
||||||
|
*/
|
||||||
|
internal class SoftSuspendLazyImpl<T : Any>(
|
||||||
|
private val coroutineContext: CoroutineContext,
|
||||||
|
private val initializer: SuspendLazyInitializer<T>,
|
||||||
|
) : SuspendLazy<T> {
|
||||||
|
|
||||||
|
private val mutex: Mutex = Mutex()
|
||||||
|
private var cachedValue: SoftReference<T>? = null
|
||||||
|
|
||||||
|
override val isInitialized: Boolean
|
||||||
|
get() = cachedValue?.get() != null
|
||||||
|
|
||||||
|
override suspend fun get(): T {
|
||||||
|
// fast way
|
||||||
|
cachedValue?.get()?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
return mutex.withLock {
|
||||||
|
cachedValue?.get()?.let {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
val result = withContext(coroutineContext) {
|
||||||
|
initializer()
|
||||||
|
}
|
||||||
|
cachedValue = SoftReference(result)
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun peek(): T? = cachedValue?.get()
|
||||||
|
}
|
||||||
@ -0,0 +1,33 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.util.suspendlazy
|
||||||
|
|
||||||
|
import org.koitharu.kotatsu.parsers.util.runCatchingCancellable
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
import kotlin.coroutines.EmptyCoroutineContext
|
||||||
|
|
||||||
|
internal typealias SuspendLazyInitializer<T> = suspend () -> T
|
||||||
|
|
||||||
|
public interface SuspendLazy<T> {
|
||||||
|
|
||||||
|
public val isInitialized: Boolean
|
||||||
|
|
||||||
|
public suspend fun get(): T
|
||||||
|
|
||||||
|
public fun peek(): T?
|
||||||
|
}
|
||||||
|
|
||||||
|
public suspend fun <T> SuspendLazy<T>.getOrNull(): T? = runCatchingCancellable { get() }.getOrNull()
|
||||||
|
|
||||||
|
public fun <T> suspendLazy(
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext,
|
||||||
|
initializer: SuspendLazyInitializer<T>,
|
||||||
|
): SuspendLazy<T> = SuspendLazyImpl(context, initializer)
|
||||||
|
|
||||||
|
public fun <T : Any> suspendLazy(
|
||||||
|
context: CoroutineContext = EmptyCoroutineContext,
|
||||||
|
soft: Boolean,
|
||||||
|
initializer: SuspendLazyInitializer<T>,
|
||||||
|
): SuspendLazy<T> = if (soft) {
|
||||||
|
SoftSuspendLazyImpl(context, initializer)
|
||||||
|
} else {
|
||||||
|
SuspendLazyImpl(context, initializer)
|
||||||
|
}
|
||||||
@ -0,0 +1,47 @@
|
|||||||
|
package org.koitharu.kotatsu.parsers.util.suspendlazy
|
||||||
|
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
|
import kotlinx.coroutines.sync.withLock
|
||||||
|
import kotlinx.coroutines.withContext
|
||||||
|
import kotlin.coroutines.CoroutineContext
|
||||||
|
|
||||||
|
internal class SuspendLazyImpl<T>(
|
||||||
|
private val coroutineContext: CoroutineContext,
|
||||||
|
private val initializer: SuspendLazyInitializer<T>,
|
||||||
|
) : SuspendLazy<T> {
|
||||||
|
|
||||||
|
private val mutex: Mutex = Mutex()
|
||||||
|
private var cachedValue: Any? = Uninitialized
|
||||||
|
|
||||||
|
override val isInitialized: Boolean
|
||||||
|
get() = cachedValue !== Uninitialized
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override suspend fun get(): T {
|
||||||
|
// fast way
|
||||||
|
cachedValue.let {
|
||||||
|
if (it !== Uninitialized) {
|
||||||
|
return it as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return mutex.withLock {
|
||||||
|
cachedValue.let {
|
||||||
|
if (it !== Uninitialized) {
|
||||||
|
return it as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val result = withContext(coroutineContext) {
|
||||||
|
initializer()
|
||||||
|
}
|
||||||
|
cachedValue = result
|
||||||
|
result
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
override fun peek(): T? {
|
||||||
|
return cachedValue?.takeUnless { it === Uninitialized } as T?
|
||||||
|
}
|
||||||
|
|
||||||
|
private object Uninitialized
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue