func (q *LinkedBlockingDeque) PollLast() interface{} {
	q.lock.Lock()
	result := q.unlinkLast()
	q.lock.Unlock()
	return result
}
PollLast retrieves and removes the last element of this deque,
or returns nil if this deque is empty.
package collections
import (
	"context"
	"errors"
	"sync"
	"github.com/jolestar/go-commons-pool/v2/concurrent"
)
type InterruptedErr struct {
}
func NewInterruptedErr() *InterruptedErr {
	return &InterruptedErr{}
}
func (err *InterruptedErr) Error() string {
	return "Interrupted"
}
type Node struct {
	item interface{}
	prev *Node
	next *Node
}
func newNode(item interface{}, prev *Node, next *Node) *Node {
	return &Node{item: item, prev: prev, next: next}
}
type LinkedBlockingDeque struct {
	first *Node
	last *Node
	count int
	capacity int
	lock *sync.Mutex
	notEmpty *concurrent.TimeoutCond
	notFull *concurrent.TimeoutCond
}
func NewDeque(capacity int) *LinkedBlockingDeque {
	if capacity < 0 {
		panic(errors.New("capacity must > 0"))
	}
	lock := new(sync.Mutex)
	return &LinkedBlockingDeque{capacity: capacity, lock: lock, notEmpty: concurrent.NewTimeoutCond(lock), notFull: concurrent.NewTimeoutCond(lock)}
}
func (q *LinkedBlockingDeque) linkFirst(e interface{}) bool {
	if q.count >= q.capacity {
		return false
	}
	f := q.first
	x := newNode(e, nil, f)
	q.first = x
	if q.last == nil {
		q.last = x
	} else {
		f.prev = x
	}
	q.count = q.count + 1
	q.notEmpty.Signal()
	return true
}
func (q *LinkedBlockingDeque) linkLast(e interface{}) bool {
	if q.count >= q.capacity {
		return false
	}
	l := q.last
	x := newNode(e, l, nil)
	q.last = x
	if q.first == nil {
		q.first = x
	} else {
		l.next = x
	}
	q.count = q.count + 1
	q.notEmpty.Signal()
	return true
}
func (q *LinkedBlockingDeque) unlinkFirst() interface{} {
	f := q.first
	if f == nil {
		return nil
	}
	n := f.next
	item := f.item
	f.item = nil
	f.next = f  
	q.first = n
	if n == nil {
		q.last = nil
	} else {
		n.prev = nil
	}
	q.count = q.count - 1
	q.notFull.Signal()
	return item
}
func (q *LinkedBlockingDeque) unlinkLast() interface{} {
	l := q.last
	if l == nil {
		return nil
	}
	p := l.prev
	item := l.item
	l.item = nil
	l.prev = l  
	q.last = p
	if p == nil {
		q.first = nil
	} else {
		p.next = nil
	}
	q.count = q.count - 1
	q.notFull.Signal()
	return item
}
func (q *LinkedBlockingDeque) unlink(x *Node) {
	p := x.prev
	n := x.next
	if p == nil {
		q.unlinkFirst()
	} else if n == nil {
		q.unlinkLast()
	} else {
		p.next = n
		n.prev = p
		x.item = nil
		q.count = q.count - 1
		q.notFull.Signal()
	}
}
func (q *LinkedBlockingDeque) AddFirst(e interface{}) error {
	if e == nil {
		return errors.New("e is nil")
	}
	if !q.OfferFirst(e) {
		return errors.New("Deque full")
	}
	return nil
}
func (q *LinkedBlockingDeque) AddLast(e interface{}) error {
	if e == nil {
		return errors.New("e is nil")
	}
	if !q.OfferLast(e) {
		return errors.New("Deque full")
	}
	return nil
}
func (q *LinkedBlockingDeque) OfferFirst(e interface{}) bool {
	if e == nil {
		return false
	}
	q.lock.Lock()
	result := q.linkFirst(e)
	q.lock.Unlock()
	return result
}
func (q *LinkedBlockingDeque) OfferLast(e interface{}) bool {
	if e == nil {
		return false
	}
	q.lock.Lock()
	result := q.linkLast(e)
	q.lock.Unlock()
	return result
}
func (q *LinkedBlockingDeque) PutFirst(ctx context.Context, e interface{}) {
	if e == nil {
		return
	}
	q.lock.Lock()
	defer q.lock.Unlock()
	for !q.linkFirst(e) {
		q.notFull.Wait(ctx)
	}
}
func (q *LinkedBlockingDeque) PutLast(ctx context.Context, e interface{}) {
	if e == nil {
		return
	}
	q.lock.Lock()
	defer q.lock.Unlock()
	for !q.linkLast(e) {
		q.notFull.Wait(ctx)
	}
}
func (q *LinkedBlockingDeque) PollFirst() (e interface{}) {
	q.lock.Lock()
	result := q.unlinkFirst()
	q.lock.Unlock()
	return result
}
func (q *LinkedBlockingDeque) PollFirstWithContext(ctx context.Context) (interface{}, error) {
	q.lock.Lock()
	defer q.lock.Unlock()
	var x interface{}
	interrupt := false
	for x = q.unlinkFirst(); x == nil; x = q.unlinkFirst() {
		if interrupt {
			return nil, NewInterruptedErr()
		}
		select {
		case <-ctx.Done():
			return nil, nil
		default:
		}
		interrupt = q.notEmpty.Wait(ctx)
	}
	return x, nil
}