KT-54739 Return single empty instance from collection builders on JVM

- return single instance of emptySet for build method from SetBuilder
- return single instance of emptyMap for build method from MapBuilder
- return single instance of emptyList for build method from ListBuilder

^KT-54739 fixed
This commit is contained in:
Ivan Kochurkin
2022-10-14 22:54:21 +02:00
committed by Space Team
parent faad7306fb
commit 0c1d957711
3 changed files with 13 additions and 4 deletions
@@ -17,6 +17,9 @@ internal class ListBuilder<E> private constructor(
private val backing: ListBuilder<E>?,
private val root: ListBuilder<E>?
) : MutableList<E>, RandomAccess, AbstractMutableList<E>(), Serializable {
private companion object {
private val Empty = ListBuilder<Nothing>(0).also { it.isReadOnly = true }
}
constructor() : this(10)
@@ -27,7 +30,7 @@ internal class ListBuilder<E> private constructor(
if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ListBuilder
checkIsMutable()
isReadOnly = true
return this
return if (length > 0) this else Empty
}
private fun writeReplace(): Any =
@@ -50,7 +50,8 @@ internal class MapBuilder<K, V> private constructor(
fun build(): Map<K, V> {
checkIsMutable()
isReadOnly = true
return this
@Suppress("UNCHECKED_CAST")
return if (size > 0) this else (Empty as Map<K, V>)
}
private fun writeReplace(): Any =
@@ -459,12 +460,14 @@ internal class MapBuilder<K, V> private constructor(
internal fun valuesIterator() = ValuesItr(this)
internal fun entriesIterator() = EntriesItr(this)
private companion object {
internal companion object {
private const val MAGIC = -1640531527 // 2654435769L.toInt(), golden ratio
private const val INITIAL_CAPACITY = 8
private const val INITIAL_MAX_PROBE_DISTANCE = 2
private const val TOMBSTONE = -1
internal val Empty = MapBuilder<Nothing, Nothing>(0).also { it.isReadOnly = true }
private fun computeHashSize(capacity: Int): Int = (capacity.coerceAtLeast(1) * 3).takeHighestOneBit()
private fun computeShift(hashSize: Int): Int = hashSize.countLeadingZeroBits() + 1
@@ -10,6 +10,9 @@ import java.io.NotSerializableException
internal class SetBuilder<E> internal constructor(
private val backing: MapBuilder<E, *>
) : MutableSet<E>, AbstractMutableSet<E>(), Serializable {
private companion object {
private val Empty = SetBuilder(MapBuilder.Empty)
}
constructor() : this(MapBuilder<E, Nothing>())
@@ -17,7 +20,7 @@ internal class SetBuilder<E> internal constructor(
fun build(): Set<E> {
backing.build()
return this
return if (size > 0) this else Empty
}
private fun writeReplace(): Any =