-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
112 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()) | ||
}) | ||
}) | ||
}) | ||
}) | ||
}) |