New() optionally sets current and minimum capacity

This commit is contained in:
gammazero 2021-04-27 19:03:02 -04:00 committed by Andrew Gillis
parent 3932da5530
commit be20709541
4 changed files with 81 additions and 7 deletions

View file

@ -1,9 +1,7 @@
language: go
go:
- 1.14.x
- 1.15.x
- tip
- 1.16.x
before_script:
- go vet ./...

View file

@ -13,6 +13,52 @@ type Deque struct {
minCap int
}
// New creates a new Deque, optionally setting the current and minimum capacity
// when non-zero values are given for these.
//
// To create a Deque with capacity to store 2048 items without resizing, and
// that will not resize below space for 32 items when removing itmes:
// d := deque.New(2048, 32)
//
// To create a Deque that has not yet allocated memory, but after it does will
// never resize to have space for less than 64 items:
// d := deque.New(0, 64)
//
// Note that any values supplied here are rounded up to the nearest power of 2.
func New(size ...int) *Deque {
var capacity, minimum int
if len(size) >= 1 {
capacity = size[0]
if len(size) >= 2 {
minimum = size[1]
}
}
minCap := minCapacity
for minCap < minimum {
minCap <<= 1
}
var buf []interface{}
if capacity != 0 {
bufSize := minCap
for bufSize < capacity {
bufSize <<= 1
}
buf = make([]interface{}, bufSize)
}
return &Deque{
buf: buf,
minCap: minCap,
}
}
// Cap returns the current capacity of the Deque.
func (q *Deque) Cap() int {
return len(q.buf)
}
// Len returns the number of elements currently stored in the queue.
func (q *Deque) Len() int {
return q.count
@ -217,6 +263,9 @@ func (q *Deque) next(i int) int {
// growIfFull resizes up if the buffer is full.
func (q *Deque) growIfFull() {
if q.count != len(q.buf) {
return
}
if len(q.buf) == 0 {
if q.minCap == 0 {
q.minCap = minCapacity
@ -224,9 +273,7 @@ func (q *Deque) growIfFull() {
q.buf = make([]interface{}, q.minCap)
return
}
if q.count == len(q.buf) {
q.resize()
}
q.resize()
}
// shrinkIfExcess resize down if the buffer 1/4 full.

View file

@ -201,6 +201,35 @@ func TestBack(t *testing.T) {
}
}
func TestNew(t *testing.T) {
minCap := 64
q := New(0, minCap)
if q.Cap() != 0 {
t.Fatal("should not have allowcated mem yet")
}
q.PushBack("foo")
q.PopFront()
if q.Len() != 0 {
t.Fatal("Len() should return 0")
}
if q.Cap() != minCap {
t.Fatalf("worng capactiy expected %d, got %d", minCap, q.Cap())
}
curCap := 128
q = New(curCap, minCap)
if q.Cap() != curCap {
t.Fatalf("Cap() should return %d, got %d", curCap, q.Cap())
}
if q.Len() != 0 {
t.Fatalf("Len() should return 0")
}
q.PushBack("foo")
if q.Cap() != curCap {
t.Fatalf("Cap() should return %d, got %d", curCap, q.Cap())
}
}
func checkRotate(t *testing.T, size int) {
var q Deque
for i := 0; i < size; i++ {

2
go.mod
View file

@ -1,3 +1,3 @@
module github.com/gammazero/deque
go 1.14
go 1.15