[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 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 fun <init> (IIILjava/lang/String;)V
|
||||
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