clean up lazy union reader

Signed-off-by: Will Murphy <will.murphy@anchore.com>
This commit is contained in:
Will Murphy 2024-04-24 11:54:02 -04:00
parent bad5cf2af8
commit 434f100add
3 changed files with 18 additions and 128 deletions

View File

@ -9,8 +9,6 @@ import (
"sync"
)
const readSize int64 = 1024 * 1024
// lazyUnionReader must implement UnionReader
var _ UnionReader = (*lazyUnionReader)(nil)
@ -21,7 +19,6 @@ var _ UnionReader = (*lazyUnionReader)(nil)
type lazyUnionReader struct {
buf []byte // the bytes that have been read so far
cursor int64 // the current position where Read() will take place
done bool // whether we have seen EOF from rc
rc io.ReadCloser // the underlying reader
mu sync.Mutex // exported methods must acquire this lock before changing any field. Unexported methods assume their caller acquired the lock
}
@ -35,7 +32,8 @@ func (c *lazyUnionReader) Read(p []byte) (n int, err error) {
if err != nil && !errors.Is(err, io.EOF) {
return 0, err
}
// stop reading either at cursor + length p, or the end of the buffer, whichever is sooner
// stop reading either at cursor + length p, or the end of the underlying reader,
// whichever is sooner
end := min(c.cursor+int64(len(p)), int64(len(c.buf)))
copy(p, c.buf[c.cursor:end])
n = int(end - c.cursor)
@ -97,7 +95,6 @@ func (c *lazyUnionReader) readAll() error {
case err != nil:
return err
}
//c.maxRead = c.maxRead() + int64(len(buf))
c.buf = append(c.buf, buf...)
return nil
}
@ -120,16 +117,6 @@ func (c *lazyUnionReader) maxRead() int64 {
return int64(len(c.buf))
}
func max(ints ...int64) int64 {
var maxSeen int64
for _, in := range ints {
if in > maxSeen {
maxSeen = in
}
}
return maxSeen
}
func min(ints ...int64) int64 {
minSeeen := int64(math.MaxInt64) // really? math.MaxInt64 has type int?
for _, n := range ints {

View File

@ -2,13 +2,12 @@ package unionreader
import (
"bytes"
"fmt"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"io"
"strings"
"sync"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
)
type spyingCloser struct {
@ -38,9 +37,9 @@ func Test_lazyUnionReader_ReadAll(t *testing.T) {
subject, err := newLazyUnionReader(rc)
require.NoError(t, err)
bytes, err := io.ReadAll(subject)
b, err := io.ReadAll(subject)
require.NoError(t, err)
assert.Equal(t, "some data", string(bytes))
assert.Equal(t, "some data", string(b))
}
func Test_lazyUnionReader_RepeatedlyRead(t *testing.T) {
@ -183,6 +182,15 @@ func Test_lazyUnionReader_Seek(t *testing.T) {
},
wantBytes: []byte("harehare"),
},
{
name: "read 4, skip 4, read 4",
commands: []command{
{readDst: make([]byte, 4)},
{seekOffset: 4, seekWhence: io.SeekCurrent},
{readDst: make([]byte, 4)},
},
wantBytes: []byte("thisa st"),
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
@ -207,90 +215,3 @@ func Test_lazyUnionReader_Seek(t *testing.T) {
})
}
}
func Test_lazyUnionReader_ensureReadUntil(t *testing.T) {
type fields struct {
buf []byte
cursor int64
maxRead int64
done bool
rc io.ReadCloser
mu sync.Mutex
}
type args struct {
offset int64
}
tests := []struct {
name string
fields fields
args args
wantErr assert.ErrorAssertionFunc
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &lazyUnionReader{
buf: tt.fields.buf,
cursor: tt.fields.cursor,
done: tt.fields.done,
rc: tt.fields.rc,
mu: tt.fields.mu,
}
tt.wantErr(t, c.ensureReadUntil(tt.args.offset), fmt.Sprintf("ensureReadUntil(%v)", tt.args.offset))
})
}
}
func Test_lazyUnionReader_readAll(t *testing.T) {
type fields struct {
buf []byte
cursor int64
maxRead int64
done bool
rc io.ReadCloser
mu sync.Mutex
}
tests := []struct {
name string
fields fields
wantErr assert.ErrorAssertionFunc
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
c := &lazyUnionReader{
buf: tt.fields.buf,
cursor: tt.fields.cursor,
done: tt.fields.done,
rc: tt.fields.rc,
mu: tt.fields.mu,
}
tt.wantErr(t, c.readAll(), fmt.Sprintf("readAll()"))
})
}
}
func Test_newLazyUnionReader(t *testing.T) {
type args struct {
readCloser io.ReadCloser
}
tests := []struct {
name string
args args
want UnionReader
wantErr assert.ErrorAssertionFunc
}{
// TODO: Add test cases.
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got, err := newLazyUnionReader(tt.args.readCloser)
if !tt.wantErr(t, err, fmt.Sprintf("newLazyUnionReader(%v)", tt.args.readCloser)) {
return
}
assert.Equalf(t, tt.want, got, "newLazyUnionReader(%v)", tt.args.readCloser)
})
}
}

View File

@ -1,9 +1,10 @@
package unionreader
import (
"io"
macho "github.com/anchore/go-macholibre"
"github.com/anchore/syft/internal/log"
"io"
)
// UnionReader is a single interface with all reading functions needed by multi-arch binary catalogers
@ -41,23 +42,4 @@ func GetUnionReader(readerCloser io.ReadCloser) (UnionReader, error) {
return reader, nil
}
return newLazyUnionReader(readerCloser)
//
//b, err := io.ReadAll(readerCloser)
//if err != nil {
// return nil, fmt.Errorf("unable to read contents from binary: %w", err)
//}
//
//bytesReader := bytes.NewReader(b)
//
//reader = struct {
// io.ReadCloser
// io.ReaderAt
// io.Seeker
//}{
// ReadCloser: io.NopCloser(bytesReader),
// ReaderAt: bytesReader,
// Seeker: bytesReader,
//}
//
//return reader, nil
}