mirror of
https://github.com/tursom/GoCollections.git
synced 2024-12-27 17:10:25 +08:00
update concurrent collections
This commit is contained in:
parent
c7576d9b3b
commit
055889a402
@ -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)
|
||||
}
|
||||
|
@ -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() {
|
||||
|
@ -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
|
||||
}
|
||||
|
89
collections/ConcurrentLinkedStack.go
Normal file
89
collections/ConcurrentLinkedStack.go
Normal 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
|
||||
}
|
@ -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
13
collections/Stack.go
Normal 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
59
main.go
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user