KT-57617 Delegate iterators of reversed list views to underlying list iterators
Improve the performance of reversed list view iterators by delegating to underlying list iterators instead of using implementations provided by the AbstractList. Latter use AbstractList::get(index: Int) to implement next() and previous() methods and depending on the underlying list's implementation it may lead to worse performance. The change also improves reversed list views test coverage.
This commit is contained in:
committed by
Space Team
parent
247f5529d2
commit
d0847f2519
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2010-2018 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* 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.
|
||||
*/
|
||||
|
||||
@@ -11,6 +11,19 @@ package kotlin.collections
|
||||
private open class ReversedListReadOnly<out T>(private val delegate: List<T>) : AbstractList<T>() {
|
||||
override val size: Int get() = delegate.size
|
||||
override fun get(index: Int): T = delegate[reverseElementIndex(index)]
|
||||
|
||||
override fun iterator(): Iterator<T> = listIterator(0)
|
||||
override fun listIterator(): ListIterator<T> = listIterator(0)
|
||||
|
||||
override fun listIterator(index: Int): ListIterator<T> = object : ListIterator<T> {
|
||||
val delegateIterator = delegate.listIterator(reversePositionIndex(index))
|
||||
override fun hasNext(): Boolean = delegateIterator.hasPrevious()
|
||||
override fun hasPrevious(): Boolean = delegateIterator.hasNext()
|
||||
override fun next(): T = delegateIterator.previous()
|
||||
override fun nextIndex(): Int = reverseIteratorIndex(delegateIterator.previousIndex())
|
||||
override fun previous(): T = delegateIterator.next()
|
||||
override fun previousIndex(): Int = reverseIteratorIndex(delegateIterator.nextIndex())
|
||||
}
|
||||
}
|
||||
|
||||
private class ReversedList<T>(private val delegate: MutableList<T>) : AbstractMutableList<T>() {
|
||||
@@ -24,6 +37,28 @@ private class ReversedList<T>(private val delegate: MutableList<T>) : AbstractMu
|
||||
override fun add(index: Int, element: T) {
|
||||
delegate.add(reversePositionIndex(index), element)
|
||||
}
|
||||
|
||||
override fun iterator(): MutableIterator<T> = listIterator(0)
|
||||
override fun listIterator(): MutableListIterator<T> = listIterator(0)
|
||||
|
||||
override fun listIterator(index: Int): MutableListIterator<T> = object : MutableListIterator<T> {
|
||||
val delegateIterator = delegate.listIterator(reversePositionIndex(index))
|
||||
override fun hasNext(): Boolean = delegateIterator.hasPrevious()
|
||||
override fun hasPrevious(): Boolean = delegateIterator.hasNext()
|
||||
override fun next(): T = delegateIterator.previous()
|
||||
override fun nextIndex(): Int = reverseIteratorIndex(delegateIterator.previousIndex())
|
||||
override fun previous(): T = delegateIterator.next()
|
||||
override fun previousIndex(): Int = reverseIteratorIndex(delegateIterator.nextIndex())
|
||||
override fun add(element: T) {
|
||||
delegateIterator.add(element)
|
||||
// After an insertion previous() will return an inserted element.
|
||||
// Moving a cursor back by one element to return a correct value from next().
|
||||
delegateIterator.previous()
|
||||
}
|
||||
|
||||
override fun remove() = delegateIterator.remove()
|
||||
override fun set(element: T) = delegateIterator.set(element)
|
||||
}
|
||||
}
|
||||
|
||||
private fun List<*>.reverseElementIndex(index: Int) =
|
||||
@@ -32,6 +67,7 @@ private fun List<*>.reverseElementIndex(index: Int) =
|
||||
private fun List<*>.reversePositionIndex(index: Int) =
|
||||
if (index in 0..size) size - index else throw IndexOutOfBoundsException("Position index $index must be in range [${0..size}].")
|
||||
|
||||
private fun List<*>.reverseIteratorIndex(index: Int) = lastIndex - index
|
||||
|
||||
/**
|
||||
* Returns a reversed read-only view of the original List.
|
||||
|
||||
Reference in New Issue
Block a user