diff --git a/queue/queue.go b/queue/queue.go index 856ae3e..e66c657 100644 --- a/queue/queue.go +++ b/queue/queue.go @@ -118,6 +118,25 @@ func (items *items) getUntil(checker func(item interface{}) bool) []interface{} return returnItems } +func (items *items) getMatch(checker func(item interface{}) bool) []interface{} { + length := len(*items) + + if len(*items) == 0 { + // returning nil here actually wraps that nil in a list + // of interfaces... thanks go + return []interface{}{} + } + + returnItems := make([]interface{}, 0, length) + for _, item := range *items { + if !checker(item) { + returnItems = append(returnItems, item) + } + } + + return returnItems +} + type sema struct { wg *sync.WaitGroup response *sync.WaitGroup @@ -246,6 +265,51 @@ func (q *Queue) Len() int64 { return int64(len(q.items)) } +// GetItems returns items in this queue. +func (q *Queue) GetItems() []interface{} { + q.lock.Lock() + defer q.lock.Unlock() + + return q.items +} + +// Search takes a function and returns a list of items that +// match the checker. This does not wait and remove items. +func (q *Queue) Search(checker func(item interface{}) bool) ([]interface{}) { + if checker == nil { + return nil + } + + q.lock.Lock() + + if q.disposed { + q.lock.Unlock() + return nil + } + + result := q.items.getMatch(checker) + q.lock.Unlock() + return result +} + + +// GetItem returns one item without deleting in this queue. +func (q *Queue) GetItem(pos int) (interface{}, bool) { + q.lock.Lock() + defer q.lock.Unlock() + if len(q.items) > pos { + return q.items[pos], true + } + return nil, false +} + +// GetItems returns items in this queue. +func (q *Queue) Clear(hint int64) { + q.lock.Lock() + defer q.lock.Unlock() + q.items = make([]interface{}, 0, hint) +} + // Disposed returns a bool indicating if this queue // has had disposed called on it. func (q *Queue) Disposed() bool { diff --git a/queue/queue_test.go b/queue/queue_test.go index fbaf514..7c7e7a2 100644 --- a/queue/queue_test.go +++ b/queue/queue_test.go @@ -134,6 +134,57 @@ func TestGetEmpty(t *testing.T) { assert.Equal(t, `a`, result[0]) } +func TestGetItems(t *testing.T) { + q := New(10) + + q.Put(`a`) + + result := q.GetItems() + + assert.Len(t, result, 1) + assert.Equal(t, `a`, result[0]) +} + +func TestSearch(t *testing.T) { + q := New(10) + + q.Put(`a`) + q.Put(`b`) + q.Put(`c`) + + result := q.Search(func(item interface{}) bool { + return item != `b` + }) + + assert.Len(t, result, 1) + assert.Equal(t, `b`, result[0]) +} + +func TestGetItem(t *testing.T) { + q := New(10) + + q.Put(`a`) + + result, ok := q.GetItem(0) + if !assert.Equal(t, ok, true) { + return + } + + assert.Equal(t, `a`, result) +} + +func TestClear(t *testing.T) { + q := New(10) + + q.Put(`a`) + + result := q.GetItems() + assert.Len(t, result, 1) + q.Clear(10) + result = q.GetItems() + assert.Len(t, result, 0) +} + func TestMultipleGetEmpty(t *testing.T) { q := New(10) var wg sync.WaitGroup