Skip to content

Commit

Permalink
Add pool data structure (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
mokiat authored Apr 23, 2023
1 parent c6e445e commit 91f3643
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 0 deletions.
38 changes: 38 additions & 0 deletions ds/pool.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
package ds

// NewPool creates a new Pool instance.
func NewPool[T any]() *Pool[T] {
return &Pool[T]{
items: NewStack[*T](0),
}
}

// Pool represents a storage structure that can preseve allocated objects
// for faster reuse.
type Pool[T any] struct {
items *Stack[*T]
}

// IsEmpty returns true if there is nothing stored for reuse in this pool.
func (p *Pool[T]) IsEmpty() bool {
return p.items.IsEmpty()
}

// Clear removes any items that were stored for reuse.
func (p *Pool[T]) Clear() {
p.items.Clear()
}

// Fetch retrieves an available item from the pool or creates a new one
// if one is not available.
func (p *Pool[T]) Fetch() *T {
if p.items.IsEmpty() {
return new(T)
}
return p.items.Pop()
}

// Restore returns an item to the pool to be reused.
func (p *Pool[T]) Restore(v *T) {
p.items.Push(v)
}
74 changes: 74 additions & 0 deletions ds/pool_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
package ds_test

import (
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"

"github.com/mokiat/gog/ds"
)

var _ = Describe("Pool", func() {
type Item struct {
Value string
}

var pool *ds.Pool[Item]

BeforeEach(func() {
pool = ds.NewPool[Item]()
})

It("is initially empty", func() {
Expect(pool.IsEmpty()).To(BeTrue())
})

It("is possible to fetch an item", func() {
item := pool.Fetch()
Expect(item).ToNot(BeNil())
})

When("an item is fetched", func() {
var item *Item

BeforeEach(func() {
item = pool.Fetch()
item.Value = "Changed"
})

It("is possible to return the item", func() {
pool.Restore(item)
})

When("an item is restored", func() {
BeforeEach(func() {
pool.Restore(item)
})

It("is no longer empty", func() {
Expect(pool.IsEmpty()).To(BeFalse())
})

It("is possible to fetch a cached item", func() {
newItem := pool.Fetch()
Expect(newItem).ToNot(BeNil())
Expect(newItem.Value).To(Equal("Changed"))
})

When("the pool is cleared", func() {
BeforeEach(func() {
pool.Clear()
})

It("is empty", func() {
Expect(pool.IsEmpty()).To(BeTrue())
})

It("is not possible to fetch a cached item", func() {
newItem := pool.Fetch()
Expect(newItem).ToNot(BeNil())
Expect(newItem.Value).To(BeEmpty())
})
})
})
})
})

0 comments on commit 91f3643

Please sign in to comment.