add concurrent list

This commit is contained in:
tursom 2020-02-18 13:55:24 +08:00
parent 2773e20eda
commit ee9b6cd87f
7 changed files with 367 additions and 1 deletions

View File

@ -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()

View 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
}
}
}

View 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]
}

View File

@ -0,0 +1,3 @@
package cn.tursom.core.datastruct.concurrent
class BlockingArrayList<T> : BlockingList<T>(ArrayList<T>())

View File

@ -0,0 +1,5 @@
package cn.tursom.core.datastruct.concurrent
import java.util.*
class BlockingLinkedList<T> : BlockingList<T>(LinkedList<T>())

View File

@ -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]
}
}

View File

@ -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
}
}
}