add ConcurrentLinkedQueue

This commit is contained in:
tursom 2021-05-21 23:07:48 +08:00
parent b44b1fd9a8
commit c7576d9b3b
4 changed files with 111 additions and 6 deletions

View File

@ -110,14 +110,14 @@ func RetainAll(l MutableCollection, collection Collection) bool {
}) == nil
}
func String(l List) string {
if l.IsEmpty() {
func String(l Iterable) string {
iterator := l.Iterator()
if !iterator.HasNext() {
return "[]"
}
builder := strings.Builder{}
builder.WriteString("[")
iterator := l.Iterator()
next, _ := iterator.Next()
builder.WriteString(fmt.Sprint(next))
for iterator.HasNext() {

View File

@ -0,0 +1,92 @@
package collections
import (
"github.com/tursom/GoCollections/exceptions"
"sync/atomic"
"unsafe"
)
type ConcurrentLinkedQueue struct {
head *concurrentLinkedQueueNode
tail *concurrentLinkedQueueNode
}
func (c ConcurrentLinkedQueue) String() string {
return String(c)
}
type concurrentLinkedQueueNode struct {
value interface{}
next *concurrentLinkedQueueNode
}
type concurrentLinkedQueueIterator struct {
prev *concurrentLinkedQueueNode
head *concurrentLinkedQueueNode
}
func NewConcurrentLinkedQueue() *ConcurrentLinkedQueue {
head := &concurrentLinkedQueueNode{}
return &ConcurrentLinkedQueue{head, head}
}
func (c ConcurrentLinkedQueue) Iterator() Iterator {
return c.MutableIterator()
}
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))
}
c.tail = newNode
return nil
}
func (c *ConcurrentLinkedQueue) Offer() (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 *ConcurrentLinkedQueue) MutableIterator() MutableIterator {
return &concurrentLinkedQueueIterator{nil, c.head}
}
func (c *concurrentLinkedQueueIterator) HasNext() bool {
return c.head.next != nil
}
func (c *concurrentLinkedQueueIterator) Next() (interface{}, exceptions.Exception) {
c.prev = c.head
c.head = c.head.next
if c.head == nil {
return nil, exceptions.NewIndexOutOfBound("", true)
}
return c.head.value, nil
}
func (c *concurrentLinkedQueueIterator) Remove() exceptions.Exception {
next := c.head.next
if next == nil {
return exceptions.NewIndexOutOfBound("", true)
}
p := (*unsafe.Pointer)(unsafe.Pointer(&c.prev.next))
atomic.CompareAndSwapPointer(p, unsafe.Pointer(c.head), unsafe.Pointer(next))
return nil
}

13
collections/Queue.go Normal file
View File

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

View File

@ -15,11 +15,11 @@ func main() {
})
exceptions.Print(err)
list := collections.NewArrayList()
list := collections.NewConcurrentLinkedQueue()
fmt.Println(list)
for i := 0; i < 20; i++ {
list.Add(i)
//fmt.Println(list)
list.Push(i)
fmt.Println(list)
}
_ = collections.LoopMutable(list, func(element interface{}, iterator collections.MutableIterator) (err exceptions.Exception) {