mirror of
https://github.com/tursom/TursomServer.git
synced 2025-01-01 16:00:26 +08:00
add concurrent list
This commit is contained in:
parent
2773e20eda
commit
ee9b6cd87f
@ -250,7 +250,7 @@ fun <T> T.println(): T {
|
||||
}
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
fun <T> Any.cast(): T = this as T
|
||||
fun <T> Any?.cast(): T = this as T
|
||||
|
||||
inline fun loop(`continue`: () -> Boolean = { true }, action: () -> Unit) {
|
||||
while (`continue`()) action()
|
||||
|
131
src/main/kotlin/cn/tursom/core/datastruct/AbstractMutableList.kt
Normal file
131
src/main/kotlin/cn/tursom/core/datastruct/AbstractMutableList.kt
Normal file
@ -0,0 +1,131 @@
|
||||
package cn.tursom.core.datastruct
|
||||
|
||||
interface AbstractMutableList<T> : MutableList<T> {
|
||||
override fun contains(element: T): Boolean {
|
||||
forEach {
|
||||
if (it == element) return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
override fun subList(fromIndex: Int, toIndex: Int): MutableList<T> {
|
||||
return SubList(this, fromIndex, toIndex)
|
||||
}
|
||||
|
||||
override fun clear() {
|
||||
repeat(size) {
|
||||
removeAt(size - 1)
|
||||
}
|
||||
}
|
||||
|
||||
override fun containsAll(elements: Collection<T>): Boolean {
|
||||
elements.forEach {
|
||||
if (contains(it).not()) {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun indexOf(element: T): Int {
|
||||
forEachIndexed { i, t ->
|
||||
if (element == t) return i
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
override fun isEmpty(): Boolean = size == 0
|
||||
|
||||
override fun lastIndexOf(element: T): Int {
|
||||
var last = -1
|
||||
forEachIndexed { index, t ->
|
||||
if (t == element) last = index
|
||||
}
|
||||
return last
|
||||
}
|
||||
|
||||
override fun addAll(index: Int, elements: Collection<T>): Boolean {
|
||||
elements.forEachIndexed { i, t ->
|
||||
add(index + i, t)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun addAll(elements: Collection<T>): Boolean {
|
||||
elements.forEach {
|
||||
add(it)
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
override fun retainAll(elements: Collection<T>): Boolean {
|
||||
val iterator = iterator()
|
||||
var changed = false
|
||||
while (iterator.hasNext()) {
|
||||
val value = iterator.next()
|
||||
if (elements.contains(value).not()) {
|
||||
iterator.remove()
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
override fun listIterator(): MutableListIterator<T> = listIterator(0)
|
||||
|
||||
override fun remove(element: T): Boolean {
|
||||
val index = indexOf(element)
|
||||
return if (index < 0) {
|
||||
false
|
||||
} else {
|
||||
removeAt(index)
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
override fun removeAll(elements: Collection<T>): Boolean {
|
||||
var changed = false
|
||||
elements.forEach {
|
||||
if (remove(it)) {
|
||||
changed = true
|
||||
}
|
||||
}
|
||||
return changed
|
||||
}
|
||||
|
||||
override fun iterator(): MutableIterator<T> = listIterator()
|
||||
|
||||
override fun listIterator(index: Int): MutableListIterator<T> = AbstractListIterator(this, index)
|
||||
|
||||
class AbstractListIterator<T>(val list: MutableList<T>, var index: Int = 0) : MutableListIterator<T> {
|
||||
init {
|
||||
index--
|
||||
}
|
||||
|
||||
override fun hasPrevious(): Boolean = index > 0
|
||||
|
||||
override fun previousIndex(): Int = index - 1
|
||||
override fun previous(): T {
|
||||
return list[--index]
|
||||
}
|
||||
|
||||
override fun add(element: T) {
|
||||
list.add(index, element)
|
||||
}
|
||||
|
||||
override fun hasNext(): Boolean = index < list.size
|
||||
override fun nextIndex(): Int = index + 1
|
||||
override fun next(): T {
|
||||
return list[++index]
|
||||
}
|
||||
|
||||
override fun remove() {
|
||||
list.removeAt(index)
|
||||
}
|
||||
|
||||
override fun set(element: T) {
|
||||
list[index] = element
|
||||
}
|
||||
}
|
||||
}
|
||||
|
20
src/main/kotlin/cn/tursom/core/datastruct/SubList.kt
Normal file
20
src/main/kotlin/cn/tursom/core/datastruct/SubList.kt
Normal file
@ -0,0 +1,20 @@
|
||||
package cn.tursom.core.datastruct
|
||||
|
||||
class SubList<T>(
|
||||
val parent: MutableList<T>,
|
||||
val fromIndex: Int,
|
||||
val toIndex: Int
|
||||
) : AbstractMutableList<T> {
|
||||
override val size: Int get() = toIndex - fromIndex
|
||||
|
||||
override fun add(element: T): Boolean {
|
||||
parent.add(toIndex, element)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun add(index: Int, element: T) = parent.add(fromIndex + index, element)
|
||||
override fun removeAt(index: Int): T = parent.removeAt(fromIndex + index)
|
||||
override fun retainAll(elements: Collection<T>): Boolean = parent.retainAll(elements)
|
||||
override fun set(index: Int, element: T): T = parent.set(fromIndex + index, element)
|
||||
override fun get(index: Int): T = parent[fromIndex + index]
|
||||
}
|
@ -0,0 +1,3 @@
|
||||
package cn.tursom.core.datastruct.concurrent
|
||||
|
||||
class BlockingArrayList<T> : BlockingList<T>(ArrayList<T>())
|
@ -0,0 +1,5 @@
|
||||
package cn.tursom.core.datastruct.concurrent
|
||||
|
||||
import java.util.*
|
||||
|
||||
class BlockingLinkedList<T> : BlockingList<T>(LinkedList<T>())
|
@ -0,0 +1,33 @@
|
||||
package cn.tursom.core.datastruct.concurrent
|
||||
|
||||
import cn.tursom.core.datastruct.AbstractMutableList
|
||||
import java.util.*
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
open class BlockingList<T>(val list: MutableList<T> = LinkedList()) : AbstractMutableList<T> {
|
||||
private var lock = ReentrantReadWriteLock()
|
||||
override val size: Int get() = list.size
|
||||
|
||||
override fun add(element: T): Boolean = lock.write {
|
||||
list.add(element)
|
||||
}
|
||||
|
||||
override fun add(index: Int, element: T) = lock.write {
|
||||
list.add(index, element)
|
||||
}
|
||||
|
||||
override fun removeAt(index: Int): T = lock.write {
|
||||
list.removeAt(index)
|
||||
}
|
||||
|
||||
override fun set(index: Int, element: T): T = lock.write {
|
||||
list.set(index, element)
|
||||
}
|
||||
|
||||
override fun get(index: Int): T = lock.read {
|
||||
list[index]
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,174 @@
|
||||
package cn.tursom.core.datastruct.concurrent
|
||||
|
||||
import cn.tursom.core.datastruct.AbstractMutableList
|
||||
import java.util.concurrent.locks.ReentrantReadWriteLock
|
||||
import kotlin.concurrent.read
|
||||
import kotlin.concurrent.write
|
||||
|
||||
@Suppress("MemberVisibilityCanBePrivate")
|
||||
class ConcurrentLinkedList<T> : AbstractMutableList<T> {
|
||||
private var length = 0
|
||||
private var lock = ReentrantReadWriteLock()
|
||||
private var root = Node()
|
||||
|
||||
override val size: Int get() = length
|
||||
|
||||
override fun get(index: Int): T {
|
||||
val p = prevNodeOfIndex(index).next
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return p.value as T
|
||||
}
|
||||
|
||||
override fun add(element: T): Boolean = lock.write {
|
||||
addBeforeNode(root.prev, element)
|
||||
return true
|
||||
}
|
||||
|
||||
override fun add(index: Int, element: T) = if (index > size) {
|
||||
throw IndexOutOfBoundsException()
|
||||
} else lock.write {
|
||||
val p = prevNodeOfIndex(index)
|
||||
addBeforeNode(p, element)
|
||||
}
|
||||
|
||||
fun addAndGetIndex(element: T): Int = lock.write {
|
||||
addBeforeNode(root.prev, element)
|
||||
return size - 1
|
||||
}
|
||||
|
||||
fun addAndGetIterator(element: T): MutableListIterator<T> = lock.write {
|
||||
addBeforeNode(root.prev, element)
|
||||
return Iterator(size - 1, root.prev)
|
||||
}
|
||||
|
||||
override fun clear() = lock.write {
|
||||
length = 0
|
||||
root.next = root
|
||||
root.prev = root
|
||||
}
|
||||
|
||||
override fun removeAt(index: Int): T = if (index > size) {
|
||||
throw IndexOutOfBoundsException()
|
||||
} else lock.write {
|
||||
val p = prevNodeOfIndex(index)
|
||||
val removed = p.next
|
||||
p.next = p.next.next
|
||||
p.next.prev = p
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
removed.value as T
|
||||
}
|
||||
|
||||
override fun set(index: Int, element: T): T = if (index < 0 || index > size) {
|
||||
throw IndexOutOfBoundsException()
|
||||
} else lock.read {
|
||||
val p = prevNodeOfIndex(index).next
|
||||
val oldValue = p.value
|
||||
p.value = element
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
oldValue as T
|
||||
}
|
||||
|
||||
override fun listIterator(index: Int): MutableListIterator<T> = Iterator(index)
|
||||
|
||||
override fun toString(): String {
|
||||
return if (length == 0) {
|
||||
"[]"
|
||||
} else {
|
||||
val sb = StringBuilder("[")
|
||||
var node = root.next
|
||||
while (node != root) {
|
||||
sb.append("${node.value}, ")
|
||||
node = node.next
|
||||
}
|
||||
repeat(2) {
|
||||
sb.deleteCharAt(sb.length - 1)
|
||||
}
|
||||
sb.append(']')
|
||||
sb.toString()
|
||||
}
|
||||
}
|
||||
|
||||
private fun addBeforeNode(p: Node, value: T) = lock.write {
|
||||
length++
|
||||
val new = Node(value, p.next.prev, p.next)
|
||||
new.next.prev = new
|
||||
new.prev.next = new
|
||||
}
|
||||
|
||||
private fun prevNodeOfIndex(index: Int): Node = if (index < 0) {
|
||||
root
|
||||
} else lock.read {
|
||||
var p = root
|
||||
if (index <= length / 2) {
|
||||
// 从前向后遍历
|
||||
repeat(index) {
|
||||
p = p.next
|
||||
}
|
||||
} else {
|
||||
// 从后向前遍历
|
||||
repeat(length - index + 1) {
|
||||
p = p.prev
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
private inner class Node {
|
||||
var value: T?
|
||||
var prev: Node
|
||||
var next: Node
|
||||
|
||||
constructor(value: T? = null, prev: Node, next: Node) {
|
||||
this.value = value
|
||||
this.next = next
|
||||
this.prev = prev
|
||||
}
|
||||
|
||||
constructor(value: T? = null) {
|
||||
this.value = value
|
||||
this.next = this
|
||||
this.prev = this
|
||||
}
|
||||
}
|
||||
|
||||
private inner class Iterator(
|
||||
var index: Int,
|
||||
var p: Node = prevNodeOfIndex(index - 1)
|
||||
) : MutableListIterator<T> {
|
||||
|
||||
override fun hasPrevious(): Boolean = p.prev != root
|
||||
|
||||
override fun previousIndex(): Int = index - 1
|
||||
override fun previous(): T {
|
||||
p = p.prev
|
||||
index--
|
||||
return get()
|
||||
}
|
||||
|
||||
override fun add(element: T) {
|
||||
addBeforeNode(p, element)
|
||||
}
|
||||
|
||||
override fun nextIndex(): Int = index + 1
|
||||
override fun hasNext(): Boolean = p.next != root
|
||||
override fun next(): T {
|
||||
p = p.next
|
||||
index++
|
||||
return get()
|
||||
}
|
||||
|
||||
override fun remove() = lock.write {
|
||||
p.next.prev = p.prev
|
||||
p.prev.next = p.next
|
||||
}
|
||||
|
||||
override fun set(element: T) {
|
||||
p.value = element
|
||||
}
|
||||
|
||||
fun get(): T {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
return p.value as T
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user