Move ArrayDeque.newCapacity to AbstractList
This commit is contained in:
committed by
Space Team
parent
d8cfc79d92
commit
2ef50f8c34
@@ -183,7 +183,7 @@ internal class ListBuilder<E> private constructor(
|
|||||||
if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ListBuilder
|
if (backing != null) throw IllegalStateException() // just in case somebody casts subList to ListBuilder
|
||||||
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
||||||
if (minCapacity > array.size) {
|
if (minCapacity > array.size) {
|
||||||
val newSize = ArrayDeque.newCapacity(array.size, minCapacity)
|
val newSize = AbstractList.newCapacity(array.size, minCapacity)
|
||||||
array = array.copyOfUninitializedElements(newSize)
|
array = array.copyOfUninitializedElements(newSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -148,7 +148,7 @@ actual class ArrayList<E> private constructor(
|
|||||||
if (backingList != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList
|
if (backingList != null) throw IllegalStateException() // just in case somebody casts subList to ArrayList
|
||||||
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
if (minCapacity < 0) throw OutOfMemoryError() // overflow
|
||||||
if (minCapacity > backingArray.size) {
|
if (minCapacity > backingArray.size) {
|
||||||
val newSize = ArrayDeque.newCapacity(backingArray.size, minCapacity)
|
val newSize = AbstractList.newCapacity(backingArray.size, minCapacity)
|
||||||
backingArray = backingArray.copyOfUninitializedElements(newSize)
|
backingArray = backingArray.copyOfUninitializedElements(newSize)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -133,6 +133,19 @@ public abstract class AbstractList<out E> protected constructor() : AbstractColl
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private const val maxArraySize = Int.MAX_VALUE - 8
|
||||||
|
|
||||||
|
/** [oldCapacity] and [minCapacity] must be non-negative. */
|
||||||
|
internal fun newCapacity(oldCapacity: Int, minCapacity: Int): Int {
|
||||||
|
// overflow-conscious
|
||||||
|
var newCapacity = oldCapacity + (oldCapacity shr 1)
|
||||||
|
if (newCapacity - minCapacity < 0)
|
||||||
|
newCapacity = minCapacity
|
||||||
|
if (newCapacity - maxArraySize > 0)
|
||||||
|
newCapacity = if (minCapacity > maxArraySize) Int.MAX_VALUE else maxArraySize
|
||||||
|
return newCapacity
|
||||||
|
}
|
||||||
|
|
||||||
internal fun orderedHashCode(c: Collection<*>): Int {
|
internal fun orderedHashCode(c: Collection<*>): Int {
|
||||||
var hashCode = 1
|
var hashCode = 1
|
||||||
for (e in c) {
|
for (e in c) {
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ public class ArrayDeque<E> : AbstractMutableList<E> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
val newCapacity = newCapacity(elementData.size, minCapacity)
|
val newCapacity = AbstractList.newCapacity(elementData.size, minCapacity)
|
||||||
copyElements(newCapacity)
|
copyElements(newCapacity)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,18 +560,7 @@ public class ArrayDeque<E> : AbstractMutableList<E> {
|
|||||||
|
|
||||||
internal companion object {
|
internal companion object {
|
||||||
private val emptyElementData = emptyArray<Any?>()
|
private val emptyElementData = emptyArray<Any?>()
|
||||||
private const val maxArraySize = Int.MAX_VALUE - 8
|
|
||||||
private const val defaultMinCapacity = 10
|
private const val defaultMinCapacity = 10
|
||||||
|
|
||||||
internal fun newCapacity(oldCapacity: Int, minCapacity: Int): Int {
|
|
||||||
// overflow-conscious
|
|
||||||
var newCapacity = oldCapacity + (oldCapacity shr 1)
|
|
||||||
if (newCapacity - minCapacity < 0)
|
|
||||||
newCapacity = minCapacity
|
|
||||||
if (newCapacity - maxArraySize > 0)
|
|
||||||
newCapacity = if (minCapacity > maxArraySize) Int.MAX_VALUE else maxArraySize
|
|
||||||
return newCapacity
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// For testing only
|
// For testing only
|
||||||
|
|||||||
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2023 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.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package test.collections
|
||||||
|
|
||||||
|
import kotlin.random.Random
|
||||||
|
import kotlin.random.nextInt
|
||||||
|
import kotlin.test.*
|
||||||
|
|
||||||
|
class AbstractListTest {
|
||||||
|
@Suppress("INVISIBLE_MEMBER")
|
||||||
|
@Test
|
||||||
|
fun newCapacity() {
|
||||||
|
// oldCapacity < minCapacity < newCapacity
|
||||||
|
repeat(100) {
|
||||||
|
val oldCapacity = Random.nextInt(1 shl 30)
|
||||||
|
val newCapacity = oldCapacity + (oldCapacity shr 1)
|
||||||
|
val minCapacity = Random.nextInt(oldCapacity + 1 until newCapacity)
|
||||||
|
|
||||||
|
assertEquals(newCapacity, AbstractList.newCapacity(oldCapacity, minCapacity))
|
||||||
|
}
|
||||||
|
|
||||||
|
// oldCapacity < newCapacity < minCapacity
|
||||||
|
repeat(100) {
|
||||||
|
val oldCapacity = Random.nextInt(1 shl 30)
|
||||||
|
val newCapacity = oldCapacity + (oldCapacity shr 1)
|
||||||
|
val minCapacity = Random.nextInt(newCapacity..Int.MAX_VALUE)
|
||||||
|
|
||||||
|
assertEquals(minCapacity, AbstractList.newCapacity(oldCapacity, minCapacity))
|
||||||
|
}
|
||||||
|
|
||||||
|
// newCapacity overflow, oldCapacity < minCapacity <= maxArraySize
|
||||||
|
val maxArraySize = Int.MAX_VALUE - 8
|
||||||
|
repeat(100) {
|
||||||
|
val oldCapacity = Random.nextInt((1 shl 30) + (1 shl 29) until maxArraySize)
|
||||||
|
val minCapacity = Random.nextInt(oldCapacity..maxArraySize)
|
||||||
|
|
||||||
|
assertEquals(maxArraySize, AbstractList.newCapacity(oldCapacity, minCapacity))
|
||||||
|
}
|
||||||
|
|
||||||
|
// newCapacity overflow, minCapacity > maxArraySize
|
||||||
|
repeat(100) {
|
||||||
|
val oldCapacity = Random.nextInt((1 shl 30) + (1 shl 29)..maxArraySize)
|
||||||
|
val minCapacity = Random.nextInt(maxArraySize + 1..Int.MAX_VALUE)
|
||||||
|
|
||||||
|
assertEquals(Int.MAX_VALUE, AbstractList.newCapacity(oldCapacity, minCapacity))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -608,45 +608,6 @@ class ArrayDequeTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("INVISIBLE_MEMBER")
|
|
||||||
@Test
|
|
||||||
fun newCapacity() {
|
|
||||||
// oldCapacity < minCapacity < newCapacity
|
|
||||||
repeat(100) {
|
|
||||||
val oldCapacity = Random.nextInt(1 shl 30)
|
|
||||||
val newCapacity = oldCapacity + (oldCapacity shr 1)
|
|
||||||
val minCapacity = Random.nextInt(oldCapacity + 1 until newCapacity)
|
|
||||||
|
|
||||||
assertEquals(newCapacity, ArrayDeque.newCapacity(oldCapacity, minCapacity))
|
|
||||||
}
|
|
||||||
|
|
||||||
// oldCapacity < newCapacity < minCapacity
|
|
||||||
repeat(100) {
|
|
||||||
val oldCapacity = Random.nextInt(1 shl 30)
|
|
||||||
val newCapacity = oldCapacity + (oldCapacity shr 1)
|
|
||||||
val minCapacity = Random.nextInt(newCapacity..Int.MAX_VALUE)
|
|
||||||
|
|
||||||
assertEquals(minCapacity, ArrayDeque.newCapacity(oldCapacity, minCapacity))
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCapacity overflow, oldCapacity < minCapacity <= maxArraySize
|
|
||||||
val maxArraySize = Int.MAX_VALUE - 8
|
|
||||||
repeat(100) {
|
|
||||||
val oldCapacity = Random.nextInt((1 shl 30) + (1 shl 29) until maxArraySize)
|
|
||||||
val minCapacity = Random.nextInt(oldCapacity..maxArraySize)
|
|
||||||
|
|
||||||
assertEquals(maxArraySize, ArrayDeque.newCapacity(oldCapacity, minCapacity))
|
|
||||||
}
|
|
||||||
|
|
||||||
// newCapacity overflow, minCapacity > maxArraySize
|
|
||||||
repeat(100) {
|
|
||||||
val oldCapacity = Random.nextInt((1 shl 30) + (1 shl 29)..maxArraySize)
|
|
||||||
val minCapacity = Random.nextInt(maxArraySize + 1..Int.MAX_VALUE)
|
|
||||||
|
|
||||||
assertEquals(Int.MAX_VALUE, ArrayDeque.newCapacity(oldCapacity, minCapacity))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@Suppress("INVISIBLE_MEMBER")
|
@Suppress("INVISIBLE_MEMBER")
|
||||||
@Test
|
@Test
|
||||||
fun toArray() {
|
fun toArray() {
|
||||||
|
|||||||
Reference in New Issue
Block a user