Commit efd601d7 authored by xujianhai666's avatar xujianhai666

add full error

parent 6d88c0f0
......@@ -29,19 +29,21 @@ const (
)
var (
ErrEmpty = errors.New("")
ErrEmpty = errors.New("quue is empty")
ErrFull = errors.New("queue is full")
)
// Queue represents a single instance of the queue data structure.
type Queue struct {
buf []interface{}
head, tail, count int
lock sync.Mutex
buf []interface{}
head, tail, count, cap int
lock sync.Mutex
}
// New constructs and returns a new Queue.
func NewQueue() *Queue {
func NewQueue(cap int) *Queue {
return &Queue{
cap: cap,
buf: make([]interface{}, defaultQueueLen),
}
}
......@@ -56,7 +58,11 @@ func (q *Queue) Length() int {
// resizes the queue to fit exactly twice its current contents
// this can result in shrinking if the queue is less than half-full
func (q *Queue) resize() {
newBuf := make([]interface{}, q.count<<1)
newSize := q.count << 1
if newSize > q.cap {
newSize = q.cap
}
newBuf := make([]interface{}, newSize)
if q.tail > q.head {
copy(newBuf, q.buf[q.head:q.tail])
......@@ -71,9 +77,13 @@ func (q *Queue) resize() {
}
// Add puts an element on the end of the queue.
func (q *Queue) Add(elem interface{}) {
func (q *Queue) Add(elem interface{}) error {
q.lock.Lock()
defer q.lock.Unlock()
if q.count >= q.cap {
return ErrFull
}
if q.count == len(q.buf) {
q.resize()
}
......@@ -81,6 +91,7 @@ func (q *Queue) Add(elem interface{}) {
q.buf[q.tail] = elem
q.tail = (q.tail + 1) & (len(q.buf) - 1)
q.count++
return nil
}
// Peek returns the element at the head of the queue. return ErrEmpty
......
......@@ -26,7 +26,7 @@ import (
)
func TestQueueSimple(t *testing.T) {
q := NewQueue()
q := NewQueue(defaultQueueLen)
for i := 0; i < defaultQueueLen; i++ {
q.Add(i)
......@@ -40,7 +40,7 @@ func TestQueueSimple(t *testing.T) {
}
func TestQueueWrapping(t *testing.T) {
q := NewQueue()
q := NewQueue(defaultQueueLen)
for i := 0; i < defaultQueueLen; i++ {
q.Add(i)
......@@ -57,8 +57,18 @@ func TestQueueWrapping(t *testing.T) {
}
}
func TestQueueFull(t *testing.T) {
q := NewQueue(defaultQueueLen)
for i := 0; i < defaultQueueLen; i++ {
err := q.Add(i)
assert.Nil(t, err)
}
err := q.Add(defaultQueueLen)
assert.Equal(t, ErrFull, err)
}
func TestQueueLength(t *testing.T) {
q := NewQueue()
q := NewQueue(1000)
assert.Equal(t, 0, q.Length(), "empty queue length should be 0")
......@@ -72,8 +82,8 @@ func TestQueueLength(t *testing.T) {
}
}
func TestQueuePeekOutOfRangePanics(t *testing.T) {
q := NewQueue()
func TestQueuePeekOutOfRangeErr(t *testing.T) {
q := NewQueue(defaultQueueLen)
_, err := q.Peek()
assert.Equal(t, ErrEmpty, err)
......@@ -86,8 +96,8 @@ func TestQueuePeekOutOfRangePanics(t *testing.T) {
assert.Equal(t, ErrEmpty, err)
}
func TestQueueRemoveOutOfRangePanics(t *testing.T) {
q := NewQueue()
func TestQueueRemoveOutOfRangeErr(t *testing.T) {
q := NewQueue(defaultQueueLen)
_, err := q.Remove()
assert.Equal(t, ErrEmpty, err)
......@@ -106,7 +116,7 @@ func TestQueueRemoveOutOfRangePanics(t *testing.T) {
// enough, but if you have less than that available and start swapping, then all bets are off.
func BenchmarkQueueSerial(b *testing.B) {
q := NewQueue()
q := NewQueue(defaultQueueLen)
for i := 0; i < b.N; i++ {
q.Add(nil)
}
......@@ -117,7 +127,7 @@ func BenchmarkQueueSerial(b *testing.B) {
}
func BenchmarkQueueTickTock(b *testing.B) {
q := NewQueue()
q := NewQueue(defaultQueueLen)
for i := 0; i < b.N; i++ {
q.Add(nil)
q.Peek()
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment