update concurrent collections

This commit is contained in:
tursom 2021-05-22 17:10:26 +08:00
parent c7576d9b3b
commit 055889a402
7 changed files with 300 additions and 57 deletions

View File

@ -14,6 +14,13 @@ func NewArrayList() *ArrayList {
}
}
func NewArrayListByCapacity(cap uint32) *ArrayList {
return &ArrayList{
make([]interface{}, cap),
0,
}
}
func (a ArrayList) String() string {
return String(a)
}

View File

@ -67,15 +67,6 @@ type (
}
)
func Contains(l Collection, element interface{}) bool {
return Loop(l, func(e interface{}) exceptions.Exception {
if e == element {
return exceptions.ElementFound
}
return nil
}) != nil
}
func ContainsAll(l Collection, collection Collection) bool {
return Loop(collection, func(e interface{}) exceptions.Exception {
if l.Contains(e) {
@ -95,21 +86,6 @@ func AddAll(l MutableCollection, collection Collection) bool {
}) == nil
}
func RemoveAll(l MutableCollection, collection Collection) bool {
return Loop(collection, func(e interface{}) exceptions.Exception {
return l.Remove(e)
}) == nil
}
func RetainAll(l MutableCollection, collection Collection) bool {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) exceptions.Exception {
if !collection.Contains(element) {
return iterator.Remove()
}
return nil
}) == nil
}
func String(l Iterable) string {
iterator := l.Iterator()
if !iterator.HasNext() {

View File

@ -8,7 +8,6 @@ import (
type ConcurrentLinkedQueue struct {
head *concurrentLinkedQueueNode
tail *concurrentLinkedQueueNode
}
func (c ConcurrentLinkedQueue) String() string {
@ -17,17 +16,20 @@ func (c ConcurrentLinkedQueue) String() string {
type concurrentLinkedQueueNode struct {
value interface{}
prev *concurrentLinkedQueueNode
next *concurrentLinkedQueueNode
}
type concurrentLinkedQueueIterator struct {
prev *concurrentLinkedQueueNode
head *concurrentLinkedQueueNode
node *concurrentLinkedQueueNode
}
func NewConcurrentLinkedQueue() *ConcurrentLinkedQueue {
head := &concurrentLinkedQueueNode{}
return &ConcurrentLinkedQueue{head, head}
head.prev = head
head.next = head
return &ConcurrentLinkedQueue{head}
}
func (c ConcurrentLinkedQueue) Iterator() Iterator {
@ -35,26 +37,30 @@ func (c ConcurrentLinkedQueue) Iterator() Iterator {
}
func (c *ConcurrentLinkedQueue) Push(element interface{}) exceptions.Exception {
newNode := &concurrentLinkedQueueNode{element, nil}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.tail.next))
np := unsafe.Pointer(newNode)
for !atomic.CompareAndSwapPointer(p, nil, np) {
p = (*unsafe.Pointer)(unsafe.Pointer(&c.tail.next))
newNode := &concurrentLinkedQueueNode{element, c.head.prev, c.head}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.head.prev))
for !atomic.CompareAndSwapPointer(p, unsafe.Pointer(newNode.prev), unsafe.Pointer(newNode)) {
newNode.prev = c.head.prev
}
c.tail = newNode
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(unsafe.Pointer(&newNode.prev.next)),
unsafe.Pointer(c.head),
unsafe.Pointer(newNode),
)
return nil
}
func (c *ConcurrentLinkedQueue) Offer() (interface{}, exceptions.Exception) {
next := c.head.next
if next == nil {
if next == c.head {
return nil, exceptions.NewIndexOutOfBound("", true)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.head.next))
p := (*unsafe.Pointer)(unsafe.Pointer(&next.next.prev))
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(next), unsafe.Pointer(next.next)) {
if !next.removeNode(p) {
next = c.head.next
p = (*unsafe.Pointer)(unsafe.Pointer(&next.prev))
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
}
@ -63,30 +69,89 @@ func (c *ConcurrentLinkedQueue) Offer() (interface{}, exceptions.Exception) {
return next.value, nil
}
func (node *concurrentLinkedQueueNode) removeNode(p *unsafe.Pointer) bool {
if p == nil {
p = (*unsafe.Pointer)(unsafe.Pointer(&node.next.prev))
}
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(node), unsafe.Pointer(node.prev)) {
return false
}
atomic.CompareAndSwapPointer(
(*unsafe.Pointer)(unsafe.Pointer(&node.prev.next)),
unsafe.Pointer(node),
unsafe.Pointer(node.next),
)
return true
}
func (c *ConcurrentLinkedQueue) MutableIterator() MutableIterator {
return &concurrentLinkedQueueIterator{nil, c.head}
return &concurrentLinkedQueueIterator{c.head, c.head}
}
func (c *concurrentLinkedQueueIterator) HasNext() bool {
return c.head.next != nil
return c.node.next != c.head
}
func (c *concurrentLinkedQueueIterator) Next() (interface{}, exceptions.Exception) {
c.prev = c.head
c.head = c.head.next
if c.head == nil {
c.node = c.node.next
if c.node == c.head {
return nil, exceptions.NewIndexOutOfBound("", true)
}
return c.head.value, nil
return c.node.value, nil
}
func (c *concurrentLinkedQueueIterator) Remove() exceptions.Exception {
next := c.head.next
if next == nil {
if c.node == c.head {
return exceptions.NewIndexOutOfBound("", true)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.prev.next))
atomic.CompareAndSwapPointer(p, unsafe.Pointer(c.head), unsafe.Pointer(next))
c.node.removeNode(nil)
c.node = c.node.prev
return nil
}
func (c *ConcurrentLinkedQueue) Size() uint32 {
size, err := Size(c)
exceptions.Print(err)
return size
}
func (c *ConcurrentLinkedQueue) IsEmpty() bool {
return c.head.next == c.head
}
func (c *ConcurrentLinkedQueue) Contains(element interface{}) bool {
return Contains(c, element)
}
func (c *ConcurrentLinkedQueue) ContainsAll(collection Collection) bool {
return ContainsAll(c, collection)
}
func (c *ConcurrentLinkedQueue) Add(element interface{}) bool {
exception := c.Push(element)
exceptions.Print(exception)
return exception == nil
}
func (c *ConcurrentLinkedQueue) Remove(element interface{}) exceptions.Exception {
return Remove(c, element)
}
func (c *ConcurrentLinkedQueue) AddAll(collection Collection) bool {
return AddAll(c, collection)
}
func (c *ConcurrentLinkedQueue) RemoveAll(collection Collection) bool {
return RemoveAll(c, collection)
}
func (c *ConcurrentLinkedQueue) RetainAll(collection Collection) bool {
return RetainAll(c, collection)
}
func (c *ConcurrentLinkedQueue) Clear() {
head := &concurrentLinkedQueueNode{}
head.prev = head
head.next = head
c.head = head
}

View File

@ -0,0 +1,89 @@
package collections
import (
"github.com/tursom/GoCollections/exceptions"
"sync/atomic"
"unsafe"
)
type ConcurrentLinkedStack struct {
head *concurrentLinkedStackNode
p *unsafe.Pointer
}
func (c ConcurrentLinkedStack) String() string {
return String(c)
}
type concurrentLinkedStackNode struct {
value interface{}
next *concurrentLinkedStackNode
}
type concurrentLinkedStackIterator struct {
node *concurrentLinkedStackNode
prev *concurrentLinkedStackNode
}
func NewConcurrentLinkedStack() *ConcurrentLinkedStack {
head := &concurrentLinkedStackNode{}
return &ConcurrentLinkedStack{head, (*unsafe.Pointer)(unsafe.Pointer(&head.next))}
}
func (c ConcurrentLinkedStack) Iterator() Iterator {
return c.MutableIterator()
}
func (c *ConcurrentLinkedStack) Push(element interface{}) exceptions.Exception {
newNode := &concurrentLinkedStackNode{element, c.head.next}
np := unsafe.Pointer(newNode)
for !atomic.CompareAndSwapPointer(c.p, unsafe.Pointer(newNode.next), np) {
}
return nil
}
func (c *ConcurrentLinkedStack) Pop() (interface{}, exceptions.Exception) {
next := c.head.next
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.head.next))
if !atomic.CompareAndSwapPointer(p, unsafe.Pointer(next), unsafe.Pointer(next.next)) {
next = c.head.next
if next == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
}
}
return next.value, nil
}
func (c *ConcurrentLinkedStack) MutableIterator() MutableIterator {
return &concurrentLinkedStackIterator{c.head, nil}
}
func (c *concurrentLinkedStackIterator) HasNext() bool {
return c.node.next != nil
}
func (c *concurrentLinkedStackIterator) Next() (interface{}, exceptions.Exception) {
c.prev = c.node
c.node = c.node.next
if c.node == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
}
return c.node.value, nil
}
func (c *concurrentLinkedStackIterator) Remove() exceptions.Exception {
if c.node == nil {
return exceptions.NewIndexOutOfBound("", true)
}
next := c.node.next
p := (*unsafe.Pointer)(unsafe.Pointer(&c.prev.next))
atomic.CompareAndSwapPointer(p, unsafe.Pointer(c.node), unsafe.Pointer(next))
return nil
}

View File

@ -69,3 +69,57 @@ func LoopMutableIterator(iterator MutableIterator, f func(element interface{}, i
}
return nil
}
func Size(iterable Iterable) (size uint32, err exceptions.Exception) {
iterator := iterable.Iterator()
for iterator.HasNext() {
_, err = iterator.Next()
if err != nil {
return
}
size++
}
return
}
func Contains(l Iterable, element interface{}) bool {
return Loop(l, func(e interface{}) exceptions.Exception {
if e == element {
return exceptions.ElementFound
}
return nil
}) != nil
}
func Remove(l MutableIterable, element interface{}) exceptions.Exception {
return LoopMutable(l, func(e interface{}, iterator MutableIterator) (err exceptions.Exception) {
if element == e {
return iterator.Remove()
}
return nil
})
}
func RemoveAll(l MutableIterable, collection Collection) bool {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) (err exceptions.Exception) {
if collection.Contains(element) {
return iterator.Remove()
}
return nil
}) == nil
}
func RetainAll(l MutableIterable, collection Collection) bool {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) exceptions.Exception {
if !collection.Contains(element) {
return iterator.Remove()
}
return nil
}) == nil
}
func Clear(l MutableIterable) exceptions.Exception {
return LoopMutable(l, func(element interface{}, iterator MutableIterator) (err exceptions.Exception) {
return iterator.Remove()
})
}

13
collections/Stack.go Normal file
View File

@ -0,0 +1,13 @@
package collections
import "github.com/tursom/GoCollections/exceptions"
type Stack interface {
// Iterator MutableIterable
Iterator() Iterator
// MutableIterator MutableIterable
MutableIterator() MutableIterator
Push(element interface{}) exceptions.Exception
Pop() (interface{}, exceptions.Exception)
}

59
main.go
View File

@ -4,6 +4,7 @@ import (
"fmt"
"github.com/tursom/GoCollections/collections"
"github.com/tursom/GoCollections/exceptions"
"time"
)
func main() {
@ -16,19 +17,57 @@ func main() {
exceptions.Print(err)
list := collections.NewConcurrentLinkedQueue()
fmt.Println(list)
for i := 0; i < 20; i++ {
list.Push(i)
fmt.Println(list)
}
target := collections.NewArrayListByCapacity(10000)
fmt.Println("list", list)
_ = collections.LoopMutable(list, func(element interface{}, iterator collections.MutableIterator) (err exceptions.Exception) {
if element.(int)&1 == 0 {
err = iterator.Remove()
go func() {
for i := 0; i < 1000000; i++ {
element, _ := list.Offer()
//fmt.Println(offer)
if element != nil {
target.Add(element)
}
}
fmt.Println("target:", target)
}()
go func() {
for i := 0; i < 1000; i++ {
err = list.Push(i)
//fmt.Println(err)
}
time.Sleep(time.Second * 2)
fmt.Println(list)
return
})
}()
//
//for i := 0; i < 100; i++ {
// fmt.Println(list)
//}
time.Sleep(time.Second * 10)
fmt.Println("target:", target)
//for i := 0; i < 20; i++ {
// list.Push(i)
// fmt.Println(list)
//}
//
//for i := 0; i < 20; i++ {
// list.Offer()
// fmt.Println(list)
//}
//
//for i := 0; i < 25; i++ {
// list.Push(i)
// fmt.Println(list)
//}
//
//_ = collections.LoopMutable(list, func(element interface{}, iterator collections.MutableIterator) (err exceptions.Exception) {
// if element.(int)&1 == 0 {
// err = iterator.Remove()
// }
// fmt.Println(list)
// return
//})
//for i := 0; i < 10; i++ {
// list.Remove(i * 2)
// fmt.Println(list)