diff --git a/src/sync/pool.go b/src/sync/pool.go index 410f1aad..ec4b770f 100644 --- a/src/sync/pool.go +++ b/src/sync/pool.go @@ -1,13 +1,18 @@ package sync -// Pool is a very simple implementation of sync.Pool. It does not actually -// implement a pool. +// Pool is a very simple implementation of sync.Pool. type Pool struct { - New func() interface{} + New func() interface{} + items []interface{} } // Get returns the value of calling Pool.New(). func (p *Pool) Get() interface{} { + if len(p.items) > 0 { + x := p.items[len(p.items)-1] + p.items = p.items[:len(p.items)-1] + return x + } if p.New == nil { return nil } @@ -16,4 +21,5 @@ func (p *Pool) Get() interface{} { // Put drops the value put into the pool. func (p *Pool) Put(x interface{}) { + p.items = append(p.items, x) } diff --git a/src/sync/pool_test.go b/src/sync/pool_test.go new file mode 100644 index 00000000..f73691de --- /dev/null +++ b/src/sync/pool_test.go @@ -0,0 +1,50 @@ +package sync_test + +import ( + "sync" + "testing" +) + +type testItem struct { + val int +} + +func TestPool(t *testing.T) { + p := sync.Pool{ + New: func() interface{} { + return &testItem{} + }, + } + + i1P := p.Get() + if i1P == nil { + t.Error("pool with New returned nil") + } + i1 := i1P.(*testItem) + if got, want := i1.val, 0; got != want { + t.Errorf("empty pool item value: got %v, want %v", got, want) + } + i1.val = 1 + + i2 := p.Get().(*testItem) + if got, want := i2.val, 0; got != want { + t.Errorf("empty pool item value: got %v, want %v", got, want) + } + i2.val = 2 + + p.Put(i1) + + i3 := p.Get().(*testItem) + if got, want := i3.val, 1; got != want { + t.Errorf("pool with item value: got %v, want %v", got, want) + } +} + +func TestPool_noNew(t *testing.T) { + p := sync.Pool{} + + i1 := p.Get() + if i1 != nil { + t.Errorf("pool without New returned %v, want nil", i1) + } +}