mirror of
https://github.com/tursom/GoCollections.git
synced 2024-12-27 17:10:25 +08:00
add ConcurrentLinkedQueue
This commit is contained in:
parent
b44b1fd9a8
commit
c7576d9b3b
@ -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() {
|
||||
|
92
collections/ConcurrentLinkedQueue.go
Normal file
92
collections/ConcurrentLinkedQueue.go
Normal 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
13
collections/Queue.go
Normal 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)
|
||||
}
|
6
main.go
6
main.go
@ -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) {
|
||||
|
Loading…
Reference in New Issue
Block a user