Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
162 changes: 19 additions & 143 deletions container/gring/gring.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,27 +9,11 @@
// Deprecated.
package gring

import (
"container/ring"

"github.com/gogf/gf/v2/container/gtype"
"github.com/gogf/gf/v2/internal/rwmutex"
)

// Ring is a struct of ring structure.
//
// Deprecated.
type Ring struct {
mu *rwmutex.RWMutex
ring *ring.Ring // Underlying ring.
len *gtype.Int // Length(already used size).
cap *gtype.Int // Capability(>=len).
dirty *gtype.Bool // Dirty, which means the len and cap should be recalculated. It's marked dirty when the size of ring changes.
}

// internalRingItem stores the ring element value.
type internalRingItem struct {
Value any
*TRing[any]
}

// New creates and returns a Ring structure of `cap` elements.
Expand All @@ -39,108 +23,53 @@ type internalRingItem struct {
// Deprecated.
func New(cap int, safe ...bool) *Ring {
return &Ring{
mu: rwmutex.New(safe...),
ring: ring.New(cap),
len: gtype.NewInt(),
cap: gtype.NewInt(cap),
dirty: gtype.NewBool(),
TRing: NewTRing[any](cap, safe...),
}
}

// Val returns the item's value of current position.
func (r *Ring) Val() any {
var value any
r.mu.RLock()
if r.ring.Value != nil {
value = r.ring.Value.(internalRingItem).Value
}
r.mu.RUnlock()
return value
return r.TRing.Val()
}

// Len returns the size of ring.
func (r *Ring) Len() int {
r.checkAndUpdateLenAndCap()
return r.len.Val()
return r.TRing.Len()
}

// Cap returns the capacity of ring.
func (r *Ring) Cap() int {
r.checkAndUpdateLenAndCap()
return r.cap.Val()
}

// Checks and updates the len and cap of ring when ring is dirty.
func (r *Ring) checkAndUpdateLenAndCap() {
if !r.dirty.Val() {
return
}
r.mu.RLock()
defer r.mu.RUnlock()
totalLen := 0
emptyLen := 0
if r.ring != nil {
if r.ring.Value == nil {
emptyLen++
}
totalLen++
for p := r.ring.Next(); p != r.ring; p = p.Next() {
if p.Value == nil {
emptyLen++
}
totalLen++
}
}
r.cap.Set(totalLen)
r.len.Set(totalLen - emptyLen)
r.dirty.Set(false)
return r.TRing.Cap()
}

// Set sets value to the item of current position.
func (r *Ring) Set(value any) *Ring {
r.mu.Lock()
if r.ring.Value == nil {
r.len.Add(1)
}
r.ring.Value = internalRingItem{Value: value}
r.mu.Unlock()
r.TRing.Set(value)
return r
}

// Put sets `value` to current item of ring and moves position to next item.
func (r *Ring) Put(value any) *Ring {
r.mu.Lock()
if r.ring.Value == nil {
r.len.Add(1)
}
r.ring.Value = internalRingItem{Value: value}
r.ring = r.ring.Next()
r.mu.Unlock()
r.TRing.Put(value)
return r
}

// Move moves n % r.Len() elements backward (n < 0) or forward (n >= 0)
// in the ring and returns that ring element. r must not be empty.
func (r *Ring) Move(n int) *Ring {
r.mu.Lock()
r.ring = r.ring.Move(n)
r.mu.Unlock()
r.TRing.Move(n)
return r
}

// Prev returns the previous ring element. r must not be empty.
func (r *Ring) Prev() *Ring {
r.mu.Lock()
r.ring = r.ring.Prev()
r.mu.Unlock()
r.TRing.Prev()
return r
}

// Next returns the next ring element. r must not be empty.
func (r *Ring) Next() *Ring {
r.mu.Lock()
r.ring = r.ring.Next()
r.mu.Unlock()
r.TRing.Next()
return r
}

Expand All @@ -160,92 +89,39 @@ func (r *Ring) Next() *Ring {
// after r. The result points to the element following the
// last element of s after insertion.
func (r *Ring) Link(s *Ring) *Ring {
r.mu.Lock()
s.mu.Lock()
r.ring.Link(s.ring)
s.mu.Unlock()
r.mu.Unlock()
r.dirty.Set(true)
s.dirty.Set(true)
r.TRing.Link(s.TRing)
return r
}

// Unlink removes n % r.Len() elements from the ring r, starting
// at r.Next(). If n % r.Len() == 0, r remains unchanged.
// The result is the removed sub-ring. r must not be empty.
func (r *Ring) Unlink(n int) *Ring {
r.mu.Lock()
resultRing := r.ring.Unlink(n)
r.dirty.Set(true)
r.mu.Unlock()
resultGRing := New(resultRing.Len())
resultGRing.ring = resultRing
resultGRing.dirty.Set(true)
return resultGRing
return &Ring{
TRing: r.TRing.Unlink(n),
}
}

// RLockIteratorNext iterates and locks reading forward
// with given callback function `f` within RWMutex.RLock.
// If `f` returns true, then it continues iterating; or false to stop.
func (r *Ring) RLockIteratorNext(f func(value any) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
if r.ring.Value != nil && !f(r.ring.Value.(internalRingItem).Value) {
return
}
for p := r.ring.Next(); p != r.ring; p = p.Next() {
if p.Value == nil || !f(p.Value.(internalRingItem).Value) {
break
}
}
r.TRing.RLockIteratorNext(f)
}

// RLockIteratorPrev iterates and locks writing backward
// RLockIteratorPrev iterates and locks reading backward
// with given callback function `f` within RWMutex.RLock.
// If `f` returns true, then it continues iterating; or false to stop.
func (r *Ring) RLockIteratorPrev(f func(value any) bool) {
r.mu.RLock()
defer r.mu.RUnlock()
if r.ring.Value != nil && !f(r.ring.Value.(internalRingItem).Value) {
return
}
for p := r.ring.Prev(); p != r.ring; p = p.Prev() {
if p.Value == nil || !f(p.Value.(internalRingItem).Value) {
break
}
}
r.TRing.RLockIteratorPrev(f)
}

// SliceNext returns a copy of all item values as slice forward from current position.
func (r *Ring) SliceNext() []any {
s := make([]any, 0)
r.mu.RLock()
if r.ring.Value != nil {
s = append(s, r.ring.Value.(internalRingItem).Value)
}
for p := r.ring.Next(); p != r.ring; p = p.Next() {
if p.Value == nil {
break
}
s = append(s, p.Value.(internalRingItem).Value)
}
r.mu.RUnlock()
return s
return r.TRing.SliceNext()
}

// SlicePrev returns a copy of all item values as slice backward from current position.
func (r *Ring) SlicePrev() []any {
s := make([]any, 0)
r.mu.RLock()
if r.ring.Value != nil {
s = append(s, r.ring.Value.(internalRingItem).Value)
}
for p := r.ring.Prev(); p != r.ring; p = p.Prev() {
if p.Value == nil {
break
}
s = append(s, p.Value.(internalRingItem).Value)
}
r.mu.RUnlock()
return s
return r.TRing.SlicePrev()
}
Loading
Loading