Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,10 @@ goos: darwin
goarch: amd64
pkg: github.com/vtopc/go-airmat
cpu: Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz
BenchmarkMakeSlices/8-4 1677363 731.3 ns/op 4080 B/op 8 allocs/op
BenchmarkMakeSlices/16-4 10000 105324 ns/op 1048563 B/op 16 allocs/op
BenchmarkMakeSlices/24-4 100 15483531 ns/op 268435443 B/op 24 allocs/op
BenchmarkPool/8-4 4156912 288.8 ns/op 0 B/op 0 allocs/op
BenchmarkPool/16-4 56299 19531 ns/op 9 B/op 0 allocs/op
BenchmarkPool/24-4 133 8669618 ns/op 13 B/op 0 allocs/op
BenchmarkMakeSlices/8-4 1573507 719.0 ns/op 4080 B/op 8 allocs/op
BenchmarkMakeSlices/16-4 10000 125151 ns/op 1048562 B/op 16 allocs/op
BenchmarkMakeSlices/24-4 100 18851436 ns/op 268435446 B/op 24 allocs/op
BenchmarkPool/8-4 3459918 289.3 ns/op 0 B/op 0 allocs/op
BenchmarkPool/16-4 54115 20723 ns/op 9 B/op 0 allocs/op
BenchmarkPool/24-4 110 11347946 ns/op 15 B/op 0 allocs/op
```
34 changes: 11 additions & 23 deletions mattress.go
Original file line number Diff line number Diff line change
@@ -1,26 +1,22 @@
package airmat

// Mattress is a container for a Slice.
// Slice should be updated by the index, not with append(...) func.
type Mattress[T any] struct {
Slice []T
}
// Mattress is a sync.Pool compatible slice,
// should be updated by the index, not with append(...) func.
type Mattress[T any] []T

func NewMattress[T any](size int) *Mattress[T] {
return &Mattress[T]{
Slice: make([]T, size),
}
func NewMattress[T any](size int) Mattress[T] {
return make([]T, size)
}

// SetSize extends or shrinks length of underlying Slice.
func (m *Mattress[T]) SetSize(size int) {
if m.Slice == nil {
m.Slice = make([]T, size)
if m == nil || *m == nil {
*m = make([]T, size)

return
}

l := len(m.Slice)
l := len(*m)

switch {
case l == size:
Expand All @@ -33,19 +29,11 @@ func (m *Mattress[T]) SetSize(size int) {
}

func (m *Mattress[T]) extend(l int) {
diff := l - len(m.Slice)
diff := l - len(*m)

// if diff < 0 {
// return
// }

m.Slice = append(m.Slice, make([]T, diff)...)
*m = append(*m, make([]T, diff)...)
}

func (m *Mattress[T]) shrink(l int) {
// if len(m.Slice) < len {
// return
// }

m.Slice = m.Slice[:l]
*m = (*m)[:l]
}
26 changes: 13 additions & 13 deletions mattress_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,41 +15,41 @@ func TestNewMattress(t *testing.T) {

t.Run("simple", func(t *testing.T) {
m := NewMattress[int](size)
assert.Len(t, m.Slice, size)
assert.Len(t, m, size)
})

t.Run("struct", func(t *testing.T) {
m := NewMattress[S](size)
assert.Len(t, m.Slice, size)
assert.Len(t, m, size)

m.Slice[1].F = 42
assert.Equal(t, m.Slice[1].F, 42)
m[1].F = 42
assert.Equal(t, m[1].F, 42)
})

t.Run("struct_ptr", func(t *testing.T) {
m := NewMattress[*S](size)
assert.Len(t, m.Slice, size)
assert.Len(t, m, size)

// TODO: automate?
if m.Slice[1] == nil {
m.Slice[1] = &S{}
if m[1] == nil {
m[1] = &S{}
}

m.Slice[1].F = 42
assert.Equal(t, m.Slice[1].F, 42)
m[1].F = 42
assert.Equal(t, m[1].F, 42)
})
}

func TestMattress_Grow(t *testing.T) {
tests := []struct {
name string
m *Mattress[string]
m Mattress[string]
len int
cap int
}{
{
name: "nil",
m: &Mattress[string]{},
m: nil,
len: size,
cap: size,
},
Expand Down Expand Up @@ -88,8 +88,8 @@ func TestMattress_Grow(t *testing.T) {
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
tt.m.SetSize(tt.len)
assert.Equal(t, tt.len, len(tt.m.Slice))
assert.Equal(t, tt.cap, cap(tt.m.Slice))
assert.Equal(t, tt.len, len(tt.m))
assert.Equal(t, tt.cap, cap(tt.m))
})
}
}