quorum/vendor/gopkg.in/oleiade/lane.v1/deque.go

149 lines
3.0 KiB
Go

package lane
import (
"container/list"
"sync"
)
// Deque is a head-tail linked list data structure implementation.
// It is based on a doubly linked list container, so that every
// operations time complexity is O(1).
//
// every operations over an instiated Deque are synchronized and
// safe for concurrent usage.
type Deque struct {
sync.RWMutex
container *list.List
capacity int
}
// NewDeque creates a Deque.
func NewDeque() *Deque {
return NewCappedDeque(-1)
}
// NewCappedDeque creates a Deque with the specified capacity limit.
func NewCappedDeque(capacity int) *Deque {
return &Deque{
container: list.New(),
capacity: capacity,
}
}
// Append inserts element at the back of the Deque in a O(1) time complexity,
// returning true if successful or false if the deque is at capacity.
func (s *Deque) Append(item interface{}) bool {
s.Lock()
defer s.Unlock()
if s.capacity < 0 || s.container.Len() < s.capacity {
s.container.PushBack(item)
return true
}
return false
}
// Prepend inserts element at the Deques front in a O(1) time complexity,
// returning true if successful or false if the deque is at capacity.
func (s *Deque) Prepend(item interface{}) bool {
s.Lock()
defer s.Unlock()
if s.capacity < 0 || s.container.Len() < s.capacity {
s.container.PushFront(item)
return true
}
return false
}
// Pop removes the last element of the deque in a O(1) time complexity
func (s *Deque) Pop() interface{} {
s.Lock()
defer s.Unlock()
var item interface{} = nil
var lastContainerItem *list.Element = nil
lastContainerItem = s.container.Back()
if lastContainerItem != nil {
item = s.container.Remove(lastContainerItem)
}
return item
}
// Shift removes the first element of the deque in a O(1) time complexity
func (s *Deque) Shift() interface{} {
s.Lock()
defer s.Unlock()
var item interface{} = nil
var firstContainerItem *list.Element = nil
firstContainerItem = s.container.Front()
if firstContainerItem != nil {
item = s.container.Remove(firstContainerItem)
}
return item
}
// First returns the first value stored in the deque in a O(1) time complexity
func (s *Deque) First() interface{} {
s.RLock()
defer s.RUnlock()
item := s.container.Front()
if item != nil {
return item.Value
} else {
return nil
}
}
// Last returns the last value stored in the deque in a O(1) time complexity
func (s *Deque) Last() interface{} {
s.RLock()
defer s.RUnlock()
item := s.container.Back()
if item != nil {
return item.Value
} else {
return nil
}
}
// Size returns the actual deque size
func (s *Deque) Size() int {
s.RLock()
defer s.RUnlock()
return s.container.Len()
}
// Capacity returns the capacity of the deque, or -1 if unlimited
func (s *Deque) Capacity() int {
s.RLock()
defer s.RUnlock()
return s.capacity
}
// Empty checks if the deque is empty
func (s *Deque) Empty() bool {
s.RLock()
defer s.RUnlock()
return s.container.Len() == 0
}
// Full checks if the deque is full
func (s *Deque) Full() bool {
s.RLock()
defer s.RUnlock()
return s.capacity >= 0 && s.container.Len() >= s.capacity
}