diff --git a/go.mod b/go.mod index 9c36fe0..94d5683 100644 --- a/go.mod +++ b/go.mod @@ -2,4 +2,4 @@ module gopkg.in/dnaeon/go-binarytree.v1 go 1.24 -require gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250925170110-f4a9a9470e9e +require gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250926082955-0627070af3b0 diff --git a/go.sum b/go.sum index a2804e0..d0ccf71 100644 --- a/go.sum +++ b/go.sum @@ -1,2 +1,2 @@ -gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250925170110-f4a9a9470e9e h1:HogsLKKscO1lTlas1DSraYcScbzUt3JxJ/jyXb1VC3o= -gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250925170110-f4a9a9470e9e/go.mod h1:mAZ2p0oPgDAeRlUKq3IJOE9RvqVvA3BIA4WKxG/9zDM= +gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250926082955-0627070af3b0 h1:0lGmV/TJSnt0GTSoFcvWooB2bSbf3HDvMV3DRQEy9k4= +gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250926082955-0627070af3b0/go.mod h1:mAZ2p0oPgDAeRlUKq3IJOE9RvqVvA3BIA4WKxG/9zDM= diff --git a/vendor/gopkg.in/dnaeon/go-deque.v1/deque.go b/vendor/gopkg.in/dnaeon/go-deque.v1/deque.go index 315e462..cfab2d0 100644 --- a/vendor/gopkg.in/dnaeon/go-deque.v1/deque.go +++ b/vendor/gopkg.in/dnaeon/go-deque.v1/deque.go @@ -33,6 +33,7 @@ import ( // an item from an empty queue var ErrEmptyQueue = errors.New("Queue is empty") +// Deque represents a double-ended queue. type Deque[T any] struct { sync.RWMutex items []T @@ -51,6 +52,12 @@ func New[T any]() *Deque[T] { func (d *Deque[T]) PushBack(value T) { d.Lock() defer d.Unlock() + d.pushBack(value) +} + +// pushBack inserts a new item at the back. Callers should ensure that access to +// the deque is synchronized when using this method. +func (d *Deque[T]) pushBack(value T) { d.items = append(d.items, value) } @@ -58,6 +65,12 @@ func (d *Deque[T]) PushBack(value T) { func (d *Deque[T]) PushFront(value T) { d.Lock() defer d.Unlock() + d.pushFront(value) +} + +// pushFront inserts a new item at the front. Callers should ensure that +// access to the deque is synchronized when using this method. +func (d *Deque[T]) pushFront(value T) { d.items = append([]T{value}, d.items...) } @@ -65,19 +78,30 @@ func (d *Deque[T]) PushFront(value T) { func (d *Deque[T]) IsEmpty() bool { d.RLock() defer d.RUnlock() + return d.isEmpty() +} + +// isEmpty returns true if the deque is empty, false otherwise. Callers should +// ensure that access to the deque is synchronized when using this method. +func (d *Deque[T]) isEmpty() bool { return len(d.items) == 0 } // PopBack pops an item from the back func (d *Deque[T]) PopBack() (T, error) { + d.Lock() + defer d.Unlock() + return d.popBack() +} + +// popBack pops an item from the back of the deque. Callers should ensure that +// access to the deque is synchronized when using this method. +func (d *Deque[T]) popBack() (T, error) { var empty T - if d.IsEmpty() { + if d.isEmpty() { return empty, ErrEmptyQueue } - d.Lock() - defer d.Unlock() - size := len(d.items) item := d.items[size-1] d.items = d.items[:size-1] @@ -87,14 +111,19 @@ func (d *Deque[T]) PopBack() (T, error) { // PopFront pops an item from the front func (d *Deque[T]) PopFront() (T, error) { + d.Lock() + defer d.Unlock() + return d.popFront() +} + +// popFront pops an item from the front of the deque. Callers should ensure that +// access to the deque is synchronized when using this method. +func (d *Deque[T]) popFront() (T, error) { var empty T - if d.IsEmpty() { + if d.isEmpty() { return empty, ErrEmptyQueue } - d.Lock() - defer d.Unlock() - item := d.items[0] d.items = d.items[1:] @@ -134,3 +163,38 @@ func (d *Deque[T]) PeekBack() (T, error) { size := len(d.items) return d.items[size-1], nil } + +// Rotate rotates the elements in the deque with n positions. When n is negative +// the deque will be rotated to the left, and when n is positive it will be +// rotated to the right. +func (d *Deque[T]) Rotate(n int) error { + if d.IsEmpty() { + return nil + } + + d.Lock() + defer d.Unlock() + var pushFunc func(val T) + var popFunc func() (T, error) + switch { + case n > 0: + popFunc = d.popBack + pushFunc = d.pushFront + case n < 0: + popFunc = d.popFront + pushFunc = d.pushBack + n = -n + default: + return nil + } + + for range n { + val, err := popFunc() + if err != nil { + return err + } + pushFunc(val) + } + + return nil +} diff --git a/vendor/gopkg.in/dnaeon/go-deque.v1/renovate.json b/vendor/gopkg.in/dnaeon/go-deque.v1/renovate.json index 5db72dd..790aa3d 100644 --- a/vendor/gopkg.in/dnaeon/go-deque.v1/renovate.json +++ b/vendor/gopkg.in/dnaeon/go-deque.v1/renovate.json @@ -2,5 +2,8 @@ "$schema": "https://docs.renovatebot.com/renovate-schema.json", "extends": [ "config:recommended" + ], + "postUpdateOptions": [ + "gomodTidy", ] } diff --git a/vendor/modules.txt b/vendor/modules.txt index b070018..cb17c99 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,3 +1,3 @@ -# gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250925170110-f4a9a9470e9e +# gopkg.in/dnaeon/go-deque.v1 v1.0.0-20250926082955-0627070af3b0 ## explicit; go 1.22 gopkg.in/dnaeon/go-deque.v1