Skip to content

Commit

Permalink
LinkedBlockingQueue: Tests
Browse files Browse the repository at this point in the history
  • Loading branch information
Theo committed Dec 30, 2017
1 parent b0168d8 commit 92f0fa8
Show file tree
Hide file tree
Showing 6 changed files with 395 additions and 131 deletions.
20 changes: 19 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Using:
L3 Cache: 4 MB
Memory: 16 GB
```

#### ArrayBlockingQueue
Simple operations - no goroutines

```text
Expand Down Expand Up @@ -65,5 +65,23 @@ ArrayBlockingQueueSuite.BenchmarkPut4to1 1000000 1239 ns/op
```
Having a different ratio of readers and writers introduce the same amount of latency.

#### LinkedBlockingQueue
```text
LinkedBlockingQueueSuite.BenchmarkPeek 100000000 21.4 ns/op
LinkedBlockingQueueSuite.BenchmarkPop100000000 24.4 ns/op
LinkedBlockingQueueSuite.BenchmarkPopOverflow 100000000 23.4 ns/op
LinkedBlockingQueueSuite.BenchmarkPush 50000000 47.3 ns/op
LinkedBlockingQueueSuite.BenchmarkPushOverflow 50000000 42.1 ns/op
LinkedBlockingQueueSuite.BenchmarkPut1to1 10000000 246 ns/op
LinkedBlockingQueueSuite.BenchmarkPut1to3 2000000 930 ns/op
LinkedBlockingQueueSuite.BenchmarkPut1to4 1000000 1496 ns/op
LinkedBlockingQueueSuite.BenchmarkPut2to1 5000000 578 ns/op
LinkedBlockingQueueSuite.BenchmarkPut2to2 5000000 560 ns/op
LinkedBlockingQueueSuite.BenchmarkPut2to3 2000000 1053 ns/op
LinkedBlockingQueueSuite.BenchmarkPut3to2 2000000 1041 ns/op
LinkedBlockingQueueSuite.BenchmarkPut4to1 1000000 1488 ns/op
LinkedBlockingQueueSuite.BenchmarkPut4to4 1000000 1451 ns/op
```

## LICENCE
Copyright © 2017 Theo Despoudis MIT license
138 changes: 14 additions & 124 deletions arrayBlockingQueue_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,28 +5,29 @@ import (

. "gopkg.in/check.v1"
"math"
"sync"
)

// Hook up gocheck into the "go test" runner.
func Test(t *testing.T) { TestingT(t) }

type ArrayBlockingQueueSuite struct {
queue *BlockingQueue
queue *BlockingQueue
queue2 *BlockingQueue
}

var _ = Suite(&ArrayBlockingQueueSuite{})

func (s *ArrayBlockingQueueSuite) SetUpTest(c *C) {
s.queue, _ = NewArrayBlockingQueue(16)
s.queue2, _ = NewArrayBlockingQueue(1024)
}

func (s *ArrayBlockingQueueSuite) TestInvalidCapacity(c *C) {
_, err := NewArrayBlockingQueue(0)
c.Assert(err, ErrorMatches, "ERROR_CAPACITY: attempt to Create Queue with invalid Capacity")
}

func (s *ArrayBlockingQueueSuite) TestContstructor(c *C) {
func (s *ArrayBlockingQueueSuite) TestConstructor(c *C) {
q, err := NewArrayBlockingQueue(16)

c.Assert(err, IsNil)
Expand Down Expand Up @@ -112,7 +113,7 @@ func (s *ArrayBlockingQueueSuite) TestPutPanicsOnNil(c *C) {
}

func (s *ArrayBlockingQueueSuite) TestPutBlocks(c *C) {
q, _ := NewArrayBlockingQueue(16)
q := s.queue
for i := 0; i < 16; i += 1 {
q.Push(i)
}
Expand Down Expand Up @@ -177,7 +178,6 @@ func (s *ArrayBlockingQueueSuite) BenchmarkPeek(c *C) {
}
}


func (s *ArrayBlockingQueueSuite) BenchmarkPopOverflow(c *C) {
for i := 0; i < c.N; i++ {
s.queue.Pop()
Expand All @@ -198,7 +198,6 @@ func (s *ArrayBlockingQueueSuite) BenchmarkPop(c *C) {
}
}


func (s *ArrayBlockingQueueSuite) BenchmarkPushOverflow(c *C) {
for i := 0; i < c.N; i++ {
s.queue.Push(i)
Expand All @@ -215,147 +214,38 @@ func (s *ArrayBlockingQueueSuite) BenchmarkPush(c *C) {
}
}


func (s *ArrayBlockingQueueSuite) BenchmarkPut1to1(c *C) {
benchmarkPut(c, 1, 1)
benchmarkPut(c, 1, 1, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut2to2(c *C) {
benchmarkPut(c, 2, 2)
benchmarkPut(c, 2, 2, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut4to4(c *C) {
benchmarkPut(c, 4, 4)
benchmarkPut(c, 4, 4, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut4to1(c *C) {
benchmarkPutMoreWriters(c, 4, 1)
benchmarkPutMoreWriters(c, 4, 1, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut2to1(c *C) {
benchmarkPutMoreWriters(c, 2, 1)
benchmarkPutMoreWriters(c, 2, 1, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut3to2(c *C) {
benchmarkPutMoreWriters(c, 3, 2)
benchmarkPutMoreWriters(c, 3, 2, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut1to3(c *C) {
benchmarkPutMoreReaders(c, 1, 3)
benchmarkPutMoreReaders(c, 1, 3, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut2to3(c *C) {
benchmarkPutMoreReaders(c, 2, 3)
benchmarkPutMoreReaders(c, 2, 3, s.queue2)
}

func (s *ArrayBlockingQueueSuite) BenchmarkPut1to4(c *C) {
benchmarkPutMoreReaders(c, 1, 4)
}

func benchmarkPut(c *C, writers int, readers int) {
q, _ := NewArrayBlockingQueue(1024)

wg := sync.WaitGroup{}

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}

wg.Wait()
}

func benchmarkPutMoreWriters(c *C, writers int, readers int) {
q, _ := NewArrayBlockingQueue(1024)

wg := sync.WaitGroup{}

rest := writers - readers

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
c.ResetTimer()
for reader := 0; reader < rest; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
wg.Wait()

}

func benchmarkPutMoreReaders(c *C, writers int, readers int) {
q, _ := NewArrayBlockingQueue(1024)

wg := sync.WaitGroup{}

rest := readers - writers

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
c.ResetTimer()

for writer := 0; writer < rest; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}
wg.Wait()
benchmarkPutMoreReaders(c, 1, 4, s.queue2)
}
108 changes: 108 additions & 0 deletions blockingQueue_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
package blockingQueues

import (
. "gopkg.in/check.v1"
"sync"
)

func benchmarkPut(c *C, writers int, readers int, q *BlockingQueue) {
wg := sync.WaitGroup{}

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}

wg.Wait()
}

func benchmarkPutMoreWriters(c *C, writers int, readers int, q *BlockingQueue) {

wg := sync.WaitGroup{}
rest := writers - readers

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
c.ResetTimer()
for reader := 0; reader < rest; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
wg.Wait()

}

func benchmarkPutMoreReaders(c *C, writers int, readers int, q *BlockingQueue) {

wg := sync.WaitGroup{}
rest := readers - writers

for writer := 0; writer < writers; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}

for reader := 0; reader < readers; reader++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Get()
}
wg.Done()
}()
}
c.ResetTimer()

for writer := 0; writer < rest; writer++ {
wg.Add(1)
go func() {
for i := 0; i < c.N; i++ {
q.Put(i)
}
wg.Done()
}()
}
wg.Wait()
}
2 changes: 1 addition & 1 deletion doc.go
Original file line number Diff line number Diff line change
@@ -1 +1 @@
package blockingQueues
package blockingQueues
12 changes: 7 additions & 5 deletions linkedBlockingQueue.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import (
)

type LinkedListStore struct {
store *list.List
store *list.List
capacity uint64
}

func NewLinkedListStore() *LinkedListStore {
func NewLinkedListStore(capacity uint64) *LinkedListStore {
return &LinkedListStore{
store: list.New(),
store: list.New(),
capacity: capacity,
}
}

Expand All @@ -29,7 +31,7 @@ func (s *LinkedListStore) Remove(pos uint64) interface{} {
}

func (s LinkedListStore) Size() uint64 {
return uint64(s.store.Len())
return s.capacity
}

// Creates an BlockingQueue backed by an LinkedList with the given (fixed) capacity
Expand All @@ -46,6 +48,6 @@ func NewLinkedBlockingQueue(capacity uint64) (*BlockingQueue, error) {
notEmpty: sync.NewCond(lock),
notFull: sync.NewCond(lock),
count: uint64(0),
store: NewLinkedListStore(),
store: NewLinkedListStore(capacity),
}, nil
}
Loading

0 comments on commit 92f0fa8

Please sign in to comment.