mirror of https://github.com/poanetwork/quorum.git
149 lines
3.0 KiB
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
|
||
|
}
|