From 60c4df4adec12f010a3f6d5bc39c46f33e2db879 Mon Sep 17 00:00:00 2001 From: tursom Date: Sun, 24 Apr 2022 16:01:22 +0800 Subject: [PATCH] update --- collections/GoMap.go | 8 +-- collections/HashMap.go | 3 +- collections/LinkedList.go | 68 ++++++++++++++++++- collections/Map.go | 7 +- collections/Queue.go | 2 +- collections/Stack.go | 3 +- .../ConcurrentLinkedQueue.go} | 46 ++++++------- .../ConcurrentLinkedQueue_test.go} | 2 +- .../ConcurrentLinkedStack.go} | 46 ++++++------- concurrent/{ => collections}/GoSyncMap.go | 7 +- .../{ => collections}/LockedMutableList.go | 17 ++++- main.go | 10 ++- util/arrayList.go | 23 ++++++- 13 files changed, 173 insertions(+), 69 deletions(-) rename concurrent/{LinkedQueue.go => collections/ConcurrentLinkedQueue.go} (62%) rename concurrent/{LinkedQueue_test.go => collections/ConcurrentLinkedQueue_test.go} (99%) rename concurrent/{LinkedStack.go => collections/ConcurrentLinkedStack.go} (65%) rename concurrent/{ => collections}/GoSyncMap.go (90%) rename concurrent/{ => collections}/LockedMutableList.go (90%) diff --git a/collections/GoMap.go b/collections/GoMap.go index 480e6e5..cb3168c 100644 --- a/collections/GoMap.go +++ b/collections/GoMap.go @@ -31,7 +31,7 @@ func (g *GoMap[K, V]) String() string { return g.ToString().GoString() } -func (g *GoMap[K, V]) findSlot(k K) MapNode[K, V] { +func (g *GoMap[K, V]) FindSlot(k K) MapNode[K, V] { hashCode := lang.HashCode(k) root := g.m[hashCode] if root == nil { @@ -42,13 +42,13 @@ func (g *GoMap[K, V]) findSlot(k K) MapNode[K, V] { } //func (g *GoMap[K, V]) Put(k K, v V) (bool, exceptions.Exception) { -// node, _ := g.findNode(k, true) +// node, _ := g.FindNode(k, true) // node.value = v // return true, nil //} // //func (g *GoMap[K, V]) Get(k K) (V, bool, exceptions.Exception) { -// node, _ := g.findNode(k, false) +// node, _ := g.FindNode(k, false) // if node == nil { // return g.nil() // } else { @@ -57,7 +57,7 @@ func (g *GoMap[K, V]) findSlot(k K) MapNode[K, V] { //} // //func (g *GoMap[K, V]) Remove(k K) (V, bool, exceptions.Exception) { -// node, prev := g.findNode(k, false) +// node, prev := g.FindNode(k, false) // if node == nil { // return g.nil() // } else { diff --git a/collections/HashMap.go b/collections/HashMap.go index 4ab9790..b46ceab 100644 --- a/collections/HashMap.go +++ b/collections/HashMap.go @@ -2,6 +2,7 @@ package collections import ( "fmt" + "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang" ) @@ -51,7 +52,7 @@ func (m *HashMap[K, V]) String() string { return MapToString[K, V](m).String() } -func (m *HashMap[K, V]) findSlot(k K) MapNode[K, V] { +func (m *HashMap[K, V]) FindSlot(k K) MapNode[K, V] { hashCode := lang.HashCode(k) hashCode ^= hashCode >> 16 index := int(hashCode) % len(m.slot) diff --git a/collections/LinkedList.go b/collections/LinkedList.go index 95359f9..f8623e6 100644 --- a/collections/LinkedList.go +++ b/collections/LinkedList.go @@ -18,6 +18,7 @@ type ( linkedListIterator[T lang.Object] struct { list *LinkedList[T] node, head *linkedListNode[T] + index int } ) @@ -89,7 +90,7 @@ func (l *LinkedList[T]) Clear() { } func (l *LinkedList[T]) SubList(from, to int) List[T] { - return NewSubList[T](l, from, to) + return l.SubMutableList(from, to) } func (l *LinkedList[T]) Set(index int, element T) exceptions.Exception { @@ -118,6 +119,12 @@ func (l *LinkedList[T]) AddAtIndex(index int, element T) bool { return false } +func (l *LinkedList[T]) addAtNode(node *linkedListNode[T], element T) { + l.size++ + node.next = &linkedListNode[T]{node, node.next, element} + node.next.next.prev = node.next +} + func (l *LinkedList[T]) RemoveAt(index int) exceptions.Exception { node := l.head for node != l.head { @@ -138,7 +145,22 @@ func (l *LinkedList[T]) RemoveLast() (T, exceptions.Exception) { } func (l *LinkedList[T]) SubMutableList(from, to int) MutableList[T] { - return NewMutableSubList[T](l, from, to) + if from < 0 || from < to || to > l.size { + panic(exceptions.NewIndexOutOfBound("", nil)) + } + list := NewLinkedList[T]() + if from == to { + return list + } + node := l.head + for i := 0; i < from; i++ { + node = node.next + } + for i := from; i < to; i++ { + node = node.next + list.Add(node.value) + } + return list } func (l *LinkedList[T]) Get(index int) (T, exceptions.Exception) { @@ -180,7 +202,15 @@ func (l *LinkedList[T]) Iterator() Iterator[T] { } func (l *LinkedList[T]) MutableIterator() MutableIterator[T] { - return &linkedListIterator[T]{l, l.head.next, l.head} + return l.MutableListIterator() +} + +func (l *LinkedList[T]) ListIterator() ListIterator[T] { + return l.MutableListIterator() +} + +func (l *LinkedList[T]) MutableListIterator() MutableListIterator[T] { + return &linkedListIterator[T]{l, l.head.next, l.head, 0} } func (l *linkedListIterator[T]) HasNext() bool { @@ -192,6 +222,7 @@ func (l *linkedListIterator[T]) Next() (T, exceptions.Exception) { return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil) } l.node = l.node.next + l.index++ return l.node.prev.value, nil } @@ -209,3 +240,34 @@ func (l *linkedListNode[T]) remove() T { l.prev.next = l.next return l.value } + +func (l *linkedListIterator[T]) HasPrevious() bool { + return l.head.next != l.head +} + +func (l *linkedListIterator[T]) Previous() (T, exceptions.Exception) { + if l.node.prev.prev == l.head { + return lang.Nil[T](), exceptions.NewIndexOutOfBound("", nil) + } + l.node = l.node.prev + l.index-- + return l.node.prev.value, nil +} + +func (l *linkedListIterator[T]) NextIndex() int { + return l.index +} + +func (l *linkedListIterator[T]) PreviousIndex() int { + return l.index - 1 +} + +func (l *linkedListIterator[T]) Set(value T) exceptions.Exception { + l.node.prev.value = value + return nil +} + +func (l *linkedListIterator[T]) Add(value T) exceptions.Exception { + l.list.addAtNode(l.node.prev, value) + return nil +} diff --git a/collections/Map.go b/collections/Map.go index f43bd0f..79e5d50 100644 --- a/collections/Map.go +++ b/collections/Map.go @@ -2,9 +2,10 @@ package collections import ( "fmt" + "strings" + "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang" - "strings" ) type ( @@ -28,7 +29,7 @@ type ( } MapSlotFinder[K lang.Object, V any] interface { - findSlot(k K) (root MapNode[K, V]) + FindSlot(k K) (root MapNode[K, V]) } MapNode[K lang.Object, V any] interface { @@ -118,7 +119,7 @@ func (g *NodeMap[K, V]) nil() (V, bool, exceptions.Exception) { } func (m *MapNodeFinderBySlot[K, V]) findNode(k K, createIfNotExist bool) (node, prev MapNode[K, V]) { - prev = m.slotFinder.findSlot(k) + prev = m.slotFinder.FindSlot(k) if prev != nil { node = prev.GetNext() for node != nil { diff --git a/collections/Queue.go b/collections/Queue.go index 0317674..0714a2f 100644 --- a/collections/Queue.go +++ b/collections/Queue.go @@ -14,5 +14,5 @@ type ( Poll() (T, exceptions.Exception) } - QueueNode[T lang.Object] = StackNode[T] + QueueNode[T lang.Object] StackNode[T] ) diff --git a/collections/Stack.go b/collections/Stack.go index 17e2080..3403b2e 100644 --- a/collections/Stack.go +++ b/collections/Stack.go @@ -2,7 +2,6 @@ package collections import ( "github.com/tursom/GoCollections/exceptions" - "github.com/tursom/GoCollections/lang" ) type ( @@ -14,7 +13,7 @@ type ( Pop() (T, exceptions.Exception) } - StackNode[T lang.Object] interface { + StackNode[T any] interface { Set(value T) exceptions.Exception Get() (T, exceptions.Exception) Remove() exceptions.Exception diff --git a/concurrent/LinkedQueue.go b/concurrent/collections/ConcurrentLinkedQueue.go similarity index 62% rename from concurrent/LinkedQueue.go rename to concurrent/collections/ConcurrentLinkedQueue.go index e11afe8..5c0857b 100644 --- a/concurrent/LinkedQueue.go +++ b/concurrent/collections/ConcurrentLinkedQueue.go @@ -1,4 +1,4 @@ -package concurrent +package collections import ( "github.com/tursom/GoCollections/collections" @@ -8,36 +8,36 @@ import ( ) type ( - LinkedQueue[T lang.Object] struct { + ConcurrentLinkedQueue[T lang.Object] struct { lang.BaseObject - LinkedStack[T] + ConcurrentLinkedStack[T] end *linkedStackNode[T] } linkedQueueIterator[T lang.Object] struct { node *linkedStackNode[T] - queue *LinkedQueue[T] + queue *ConcurrentLinkedQueue[T] } ) -func (q *LinkedQueue[T]) String() string { +func (q *ConcurrentLinkedQueue[T]) String() string { return collections.String[T](q) } -func NewLinkedQueue[T lang.Object]() *LinkedQueue[T] { - return &LinkedQueue[T]{} +func NewLinkedQueue[T lang.Object]() *ConcurrentLinkedQueue[T] { + return &ConcurrentLinkedQueue[T]{} } -func (q *LinkedQueue[T]) Iterator() collections.Iterator[T] { +func (q *ConcurrentLinkedQueue[T]) Iterator() collections.Iterator[T] { return q.MutableIterator() } -func (q *LinkedQueue[T]) Offer(element T) exceptions.Exception { +func (q *ConcurrentLinkedQueue[T]) Offer(element T) exceptions.Exception { _, err := q.offerAndGetNode(element) return err } -func (q *LinkedQueue[T]) OfferAndGetNode(element T) (collections.QueueNode[T], exceptions.Exception) { +func (q *ConcurrentLinkedQueue[T]) OfferAndGetNode(element T) (collections.QueueNode[T], exceptions.Exception) { newNode, err := q.offerAndGetNode(element) if err != nil { return nil, err @@ -45,7 +45,7 @@ func (q *LinkedQueue[T]) OfferAndGetNode(element T) (collections.QueueNode[T], e return &linkedQueueIterator[T]{queue: q, node: newNode}, nil } -func (q *LinkedQueue[T]) offerAndGetNode(element T) (*linkedStackNode[T], exceptions.Exception) { +func (q *ConcurrentLinkedQueue[T]) offerAndGetNode(element T) (*linkedStackNode[T], exceptions.Exception) { newNode := &linkedStackNode[T]{value: element} q.size.Add(1) @@ -72,53 +72,53 @@ func (q *LinkedQueue[T]) offerAndGetNode(element T) (*linkedStackNode[T], except return newNode, nil } -func (q *LinkedQueue[T]) Poll() (T, exceptions.Exception) { +func (q *ConcurrentLinkedQueue[T]) Poll() (T, exceptions.Exception) { return q.Pop() } -func (q *LinkedQueue[T]) MutableIterator() collections.MutableIterator[T] { +func (q *ConcurrentLinkedQueue[T]) MutableIterator() collections.MutableIterator[T] { return &linkedQueueIterator[T]{queue: q, node: q.head} } -func (q *LinkedQueue[T]) Size() int { +func (q *ConcurrentLinkedQueue[T]) Size() int { return int(q.size.Load()) } -func (q *LinkedQueue[T]) IsEmpty() bool { +func (q *ConcurrentLinkedQueue[T]) IsEmpty() bool { return q.head == nil } -func (q *LinkedQueue[T]) Contains(element T) bool { +func (q *ConcurrentLinkedQueue[T]) Contains(element T) bool { return collections.Contains[T](q, element) } -func (q *LinkedQueue[T]) ContainsAll(collection collections.Collection[T]) bool { +func (q *ConcurrentLinkedQueue[T]) ContainsAll(collection collections.Collection[T]) bool { return collections.ContainsAll[T](q, collection) } -func (q *LinkedQueue[T]) Add(element T) bool { +func (q *ConcurrentLinkedQueue[T]) Add(element T) bool { exception := q.Push(element) exceptions.Print(exception) return exception == nil } -func (q *LinkedQueue[T]) Remove(element T) exceptions.Exception { +func (q *ConcurrentLinkedQueue[T]) Remove(element T) exceptions.Exception { return collections.Remove[T](q, element) } -func (q *LinkedQueue[T]) AddAll(collection collections.Collection[T]) bool { +func (q *ConcurrentLinkedQueue[T]) AddAll(collection collections.Collection[T]) bool { return collections.AddAll[T](q, collection) } -func (q *LinkedQueue[T]) RemoveAll(collection collections.Collection[T]) bool { +func (q *ConcurrentLinkedQueue[T]) RemoveAll(collection collections.Collection[T]) bool { return collections.RemoveAll[T](q, collection) } -func (q *LinkedQueue[T]) RetainAll(collection collections.Collection[T]) bool { +func (q *ConcurrentLinkedQueue[T]) RetainAll(collection collections.Collection[T]) bool { return collections.RetainAll[T](q, collection) } -func (q *LinkedQueue[T]) Clear() { +func (q *ConcurrentLinkedQueue[T]) Clear() { q.head = nil q.end = nil q.size.Store(0) diff --git a/concurrent/LinkedQueue_test.go b/concurrent/collections/ConcurrentLinkedQueue_test.go similarity index 99% rename from concurrent/LinkedQueue_test.go rename to concurrent/collections/ConcurrentLinkedQueue_test.go index 0ad66c5..e192e7e 100644 --- a/concurrent/LinkedQueue_test.go +++ b/concurrent/collections/ConcurrentLinkedQueue_test.go @@ -1,4 +1,4 @@ -package concurrent +package collections import ( "fmt" diff --git a/concurrent/LinkedStack.go b/concurrent/collections/ConcurrentLinkedStack.go similarity index 65% rename from concurrent/LinkedStack.go rename to concurrent/collections/ConcurrentLinkedStack.go index 6c5310d..846911a 100644 --- a/concurrent/LinkedStack.go +++ b/concurrent/collections/ConcurrentLinkedStack.go @@ -1,4 +1,4 @@ -package concurrent +package collections import ( "github.com/tursom/GoCollections/collections" @@ -8,7 +8,7 @@ import ( ) type ( - LinkedStack[T lang.Object] struct { + ConcurrentLinkedStack[T lang.Object] struct { lang.BaseObject size atomic.Int32 deleted atomic.Int32 @@ -23,35 +23,35 @@ type ( linkedStackIterator[T lang.Object] struct { node *linkedStackNode[T] - stack *LinkedStack[T] + stack *ConcurrentLinkedStack[T] } ) -func (s *LinkedStack[T]) String() string { +func (s *ConcurrentLinkedStack[T]) String() string { return collections.String[T](s) } -func NewLinkedStack[T lang.Object]() *LinkedStack[T] { - return &LinkedStack[T]{} +func NewLinkedStack[T lang.Object]() *ConcurrentLinkedStack[T] { + return &ConcurrentLinkedStack[T]{} } -func (s *LinkedStack[T]) Iterator() collections.Iterator[T] { +func (s *ConcurrentLinkedStack[T]) Iterator() collections.Iterator[T] { return s.MutableIterator() } -func (s *LinkedStack[T]) Push(element T) exceptions.Exception { +func (s *ConcurrentLinkedStack[T]) Push(element T) exceptions.Exception { s.push(element) return nil } -func (s *LinkedStack[T]) PushAndGetNode(element T) collections.StackNode[T] { +func (s *ConcurrentLinkedStack[T]) PushAndGetNode(element T) collections.StackNode[T] { return &linkedStackIterator[T]{ node: s.push(element), stack: s, } } -func (s *LinkedStack[T]) push(element T) *linkedStackNode[T] { +func (s *ConcurrentLinkedStack[T]) push(element T) *linkedStackNode[T] { newNode := &linkedStackNode[T]{value: element, next: s.head} for !atomic.CompareAndSwapPointer(&s.head, newNode.next, newNode) { newNode.next = s.head @@ -60,7 +60,7 @@ func (s *LinkedStack[T]) push(element T) *linkedStackNode[T] { return newNode } -func (s *LinkedStack[T]) Pop() (T, exceptions.Exception) { +func (s *ConcurrentLinkedStack[T]) Pop() (T, exceptions.Exception) { node := s.head for node != nil && (!atomic.CompareAndSwapPointer(&s.head, node, node.next) || node.deleted) { node = s.head @@ -73,7 +73,7 @@ func (s *LinkedStack[T]) Pop() (T, exceptions.Exception) { return node.value, nil } -func (s *LinkedStack[T]) CleanDeleted() { +func (s *ConcurrentLinkedStack[T]) CleanDeleted() { if s.deleted.Load() <= s.size.Load() { return } @@ -88,50 +88,50 @@ func (s *LinkedStack[T]) CleanDeleted() { } } -func (s *LinkedStack[T]) Size() int { +func (s *ConcurrentLinkedStack[T]) Size() int { return int(s.size.Load()) } -func (s *LinkedStack[T]) IsEmpty() bool { +func (s *ConcurrentLinkedStack[T]) IsEmpty() bool { return s.head == nil } -func (s *LinkedStack[T]) Contains(element T) bool { +func (s *ConcurrentLinkedStack[T]) Contains(element T) bool { return collections.Contains[T](s, element) } -func (s *LinkedStack[T]) ContainsAll(c collections.Collection[T]) bool { +func (s *ConcurrentLinkedStack[T]) ContainsAll(c collections.Collection[T]) bool { return collections.ContainsAll[T](s, c) } -func (s *LinkedStack[T]) Add(element T) bool { +func (s *ConcurrentLinkedStack[T]) Add(element T) bool { exception := s.Push(element) exceptions.Print(exception) return exception == nil } -func (s *LinkedStack[T]) Remove(element T) exceptions.Exception { +func (s *ConcurrentLinkedStack[T]) Remove(element T) exceptions.Exception { return collections.Remove[T](s, element) } -func (s *LinkedStack[T]) AddAll(c collections.Collection[T]) bool { +func (s *ConcurrentLinkedStack[T]) AddAll(c collections.Collection[T]) bool { return collections.AddAll[T](s, c) } -func (s *LinkedStack[T]) RemoveAll(c collections.Collection[T]) bool { +func (s *ConcurrentLinkedStack[T]) RemoveAll(c collections.Collection[T]) bool { return collections.RemoveAll[T](s, c) } -func (s *LinkedStack[T]) RetainAll(c collections.Collection[T]) bool { +func (s *ConcurrentLinkedStack[T]) RetainAll(c collections.Collection[T]) bool { return collections.RetainAll[T](s, c) } -func (s *LinkedStack[T]) Clear() { +func (s *ConcurrentLinkedStack[T]) Clear() { s.head = nil s.size.Store(0) } -func (s *LinkedStack[T]) MutableIterator() collections.MutableIterator[T] { +func (s *ConcurrentLinkedStack[T]) MutableIterator() collections.MutableIterator[T] { return &linkedStackIterator[T]{s.head, nil} } diff --git a/concurrent/GoSyncMap.go b/concurrent/collections/GoSyncMap.go similarity index 90% rename from concurrent/GoSyncMap.go rename to concurrent/collections/GoSyncMap.go index 0eb4513..e7bed49 100644 --- a/concurrent/GoSyncMap.go +++ b/concurrent/collections/GoSyncMap.go @@ -1,9 +1,10 @@ -package concurrent +package collections import ( "sync" "github.com/tursom/GoCollections/collections" + "github.com/tursom/GoCollections/concurrent" "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang" ) @@ -13,7 +14,7 @@ type ( GoSyncMap[K lang.Object, V any] struct { collections.NodeMap[K, V] m sync.Map - lock RWLock + lock concurrent.RWLock } ) @@ -27,7 +28,7 @@ func (g *GoSyncMap[K, V]) ToString() lang.String { return collections.MapToString[K, V](g) } -func (g *GoSyncMap[K, V]) findSlot(k K) collections.MapNode[K, V] { +func (g *GoSyncMap[K, V]) FindSlot(k K) collections.MapNode[K, V] { hashCode := lang.HashCode(k) p, _ := g.m.Load(hashCode) root := lang.Cast[*collections.SimpleMapNode[K, V]](p) diff --git a/concurrent/LockedMutableList.go b/concurrent/collections/LockedMutableList.go similarity index 90% rename from concurrent/LockedMutableList.go rename to concurrent/collections/LockedMutableList.go index 14104ff..589f6d8 100644 --- a/concurrent/LockedMutableList.go +++ b/concurrent/collections/LockedMutableList.go @@ -1,9 +1,10 @@ -package concurrent +package collections import ( "sync" "github.com/tursom/GoCollections/collections" + "github.com/tursom/GoCollections/concurrent" "github.com/tursom/GoCollections/exceptions" "github.com/tursom/GoCollections/lang" ) @@ -11,11 +12,11 @@ import ( type ( LockedMutableList[T lang.Object] struct { list collections.MutableList[T] - lock RWLock + lock concurrent.RWLock } lockedMutableListIterator[T lang.Object] struct { iterator collections.MutableIterator[T] - lock RWLock + lock concurrent.RWLock } ) @@ -161,3 +162,13 @@ func (l *lockedMutableListIterator[T]) Remove() exceptions.Exception { return l.iterator.Remove() } + +func (l *LockedMutableList[T]) ListIterator() collections.ListIterator[T] { + //TODO implement me + panic("implement me") +} + +func (l *LockedMutableList[T]) MutableListIterator() collections.MutableListIterator[T] { + //TODO implement me + panic("implement me") +} diff --git a/main.go b/main.go index 5bb9245..73cd200 100644 --- a/main.go +++ b/main.go @@ -1,6 +1,14 @@ package main -import "github.com/tursom/GoCollections/exceptions" +import ( + _ "github.com/tursom/GoCollections/collections" + _ "github.com/tursom/GoCollections/concurrent" + _ "github.com/tursom/GoCollections/concurrent/collections" + "github.com/tursom/GoCollections/exceptions" + _ "github.com/tursom/GoCollections/lang" + _ "github.com/tursom/GoCollections/lang/atomic" + _ "github.com/tursom/GoCollections/util" +) func main() { exceptions.NewRuntimeException("test2", exceptions.DefaultExceptionConfig().SetCause(1)).PrintStackTrace() diff --git a/util/arrayList.go b/util/arrayList.go index 4bca7c5..f76e27d 100644 --- a/util/arrayList.go +++ b/util/arrayList.go @@ -11,10 +11,14 @@ type arrayList[T lang.Object] struct { array []T } -func (a *arrayList[T]) Iterator() collections.Iterator[T] { +func (a *arrayList[T]) ListIterator() collections.ListIterator[T] { return &arrayListIterator[T]{a.array, 0} } +func (a *arrayList[T]) Iterator() collections.Iterator[T] { + return a.ListIterator() +} + func (a *arrayList[T]) Size() int { return lang.Len(a.array) } @@ -44,6 +48,23 @@ type arrayListIterator[T lang.Object] struct { index int } +func (a *arrayListIterator[T]) HasPrevious() bool { + return a.index > 0 +} + +func (a *arrayListIterator[T]) Previous() (T, exceptions.Exception) { + a.index-- + return a.array[a.index], nil +} + +func (a *arrayListIterator[T]) NextIndex() int { + return a.index +} + +func (a *arrayListIterator[T]) PreviousIndex() int { + return a.index - 1 +} + func (a *arrayListIterator[T]) HasNext() bool { return a.index < lang.Len(a.array) }