[kotlin-tooling-core] Implement generic Interner
^KT-55475 Verification Pending
This commit is contained in:
committed by
Space Team
parent
84fdc5e3df
commit
71fac797ee
@@ -142,6 +142,17 @@ public abstract interface class org/jetbrains/kotlin/tooling/core/HasMutableExtr
|
|||||||
public abstract fun getExtras ()Lorg/jetbrains/kotlin/tooling/core/MutableExtras;
|
public abstract fun getExtras ()Lorg/jetbrains/kotlin/tooling/core/MutableExtras;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public abstract interface class org/jetbrains/kotlin/tooling/core/Interner {
|
||||||
|
public abstract fun getOrPut (Ljava/lang/Object;)Ljava/lang/Object;
|
||||||
|
}
|
||||||
|
|
||||||
|
public final class org/jetbrains/kotlin/tooling/core/InternerKt {
|
||||||
|
public static final fun Interner (Ljava/util/concurrent/locks/Lock;)Lorg/jetbrains/kotlin/tooling/core/Interner;
|
||||||
|
public static synthetic fun Interner$default (Ljava/util/concurrent/locks/Lock;ILjava/lang/Object;)Lorg/jetbrains/kotlin/tooling/core/Interner;
|
||||||
|
public static final fun WeakInterner (Ljava/util/concurrent/locks/Lock;)Lorg/jetbrains/kotlin/tooling/core/Interner;
|
||||||
|
public static synthetic fun WeakInterner$default (Ljava/util/concurrent/locks/Lock;ILjava/lang/Object;)Lorg/jetbrains/kotlin/tooling/core/Interner;
|
||||||
|
}
|
||||||
|
|
||||||
public final class org/jetbrains/kotlin/tooling/core/KotlinToolingVersion : java/io/Serializable, java/lang/Comparable {
|
public final class org/jetbrains/kotlin/tooling/core/KotlinToolingVersion : java/io/Serializable, java/lang/Comparable {
|
||||||
public fun <init> (IIILjava/lang/String;)V
|
public fun <init> (IIILjava/lang/String;)V
|
||||||
public synthetic fun compareTo (Ljava/lang/Object;)I
|
public synthetic fun compareTo (Ljava/lang/Object;)I
|
||||||
|
|||||||
+56
@@ -0,0 +1,56 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("FunctionName")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tooling.core
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.tooling.core.InternerImpl.Store.Strong
|
||||||
|
import org.jetbrains.kotlin.tooling.core.InternerImpl.Store.Weak
|
||||||
|
import java.lang.ref.WeakReference
|
||||||
|
import java.util.*
|
||||||
|
import java.util.concurrent.locks.Lock
|
||||||
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
|
fun WeakInterner(lock: Lock? = null): Interner = InternerImpl(Weak(), lock)
|
||||||
|
|
||||||
|
fun Interner(lock: Lock? = null): Interner = InternerImpl(Strong(), lock)
|
||||||
|
|
||||||
|
interface Interner {
|
||||||
|
fun <T : Any> getOrPut(value: T): T
|
||||||
|
}
|
||||||
|
|
||||||
|
private class InternerImpl(
|
||||||
|
private val store: Store,
|
||||||
|
private val lock: Lock? = null
|
||||||
|
) : Interner {
|
||||||
|
|
||||||
|
interface Store {
|
||||||
|
fun <T : Any> getOrPut(value: T): T
|
||||||
|
|
||||||
|
class Weak : Store {
|
||||||
|
private val references = WeakHashMap<Any, WeakReference<Any>>()
|
||||||
|
override fun <T : Any> getOrPut(value: T): T {
|
||||||
|
@Suppress("unchecked_cast")
|
||||||
|
return (references.getOrPut(value) { WeakReference(value) }.get() ?: run {
|
||||||
|
references[value] = WeakReference(value)
|
||||||
|
value
|
||||||
|
}) as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
class Strong : Store {
|
||||||
|
private val references = hashMapOf<Any, Any>()
|
||||||
|
override fun <T : Any> getOrPut(value: T): T {
|
||||||
|
return references.getOrPut(value) { value } as T
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun <T : Any> getOrPut(value: T): T {
|
||||||
|
return lock?.withLock { store.getOrPut(value) } ?: store.getOrPut(value)
|
||||||
|
}
|
||||||
|
}
|
||||||
+40
@@ -0,0 +1,40 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
@file:Suppress("UNUSED_VALUE")
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.tooling.core
|
||||||
|
|
||||||
|
import org.junit.Test
|
||||||
|
import kotlin.test.assertSame
|
||||||
|
|
||||||
|
class InternerTest {
|
||||||
|
|
||||||
|
data class Sample(val value: Int)
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - weak interner`() {
|
||||||
|
doTest(WeakInterner())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `test - strong interner`() {
|
||||||
|
doTest(Interner())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun doTest(interner: Interner) {
|
||||||
|
val sample0A = Sample(0)
|
||||||
|
val sample0B = Sample(0)
|
||||||
|
val sample1A = Sample(1)
|
||||||
|
val sample1B = Sample(1)
|
||||||
|
|
||||||
|
assertSame(sample0A, interner.getOrPut(sample0A))
|
||||||
|
assertSame(sample0A, interner.getOrPut(sample0B))
|
||||||
|
assertSame(sample1A, interner.getOrPut(sample1A))
|
||||||
|
assertSame(sample1A, interner.getOrPut(sample1B))
|
||||||
|
assertSame(sample0A, interner.getOrPut(sample0A))
|
||||||
|
assertSame(sample0A, interner.getOrPut(sample0B))
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user