aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShulhan <m.shulhan@gmail.com>2023-09-16 23:17:48 +0700
committerShulhan <m.shulhan@gmail.com>2026-04-14 21:51:40 +0700
commit5410be8b93277d2b1d0f701bfa64a4930b31615e (patch)
tree492499e42b20c51a7971335dd2f2255789c88274
parent46703a0c6d11d17c75f6f77b2c7e8941b8cd505f (diff)
downloadgo-5410be8b93277d2b1d0f701bfa64a4930b31615e.tar.xz
bufio: realign struct Reader
This reduce the Reader allocation size from 72 to 40 bytes and Writer allocation size from 64 to 40 bytes.
-rw-r--r--src/bufio/bufio.go9
-rw-r--r--src/bufio/bufio_test.go97
2 files changed, 55 insertions, 51 deletions
diff --git a/src/bufio/bufio.go b/src/bufio/bufio.go
index f9b762be8d..79e7f3cf57 100644
--- a/src/bufio/bufio.go
+++ b/src/bufio/bufio.go
@@ -33,10 +33,10 @@ var (
// alternatively the zero value of a Reader may be used after calling [Reader.Reset]
// on it.
type Reader struct {
- buf []byte
rd io.Reader // reader provided by the client
- r, w int // buf read and write positions
err error
+ buf []byte
+ r, w int // buf read and write positions
lastByte int // last byte read for UnreadByte; -1 means invalid
lastRuneSize int // size of last rune read for UnreadRune; -1 means invalid
}
@@ -577,10 +577,10 @@ func (b *Reader) writeBuf(w io.Writer) (int64, error) {
// [Writer.Flush] method to guarantee all data has been forwarded to
// the underlying [io.Writer].
type Writer struct {
+ wr io.Writer
err error
buf []byte
n int
- wr io.Writer
}
// NewWriterSize returns a new [Writer] whose buffer has at least the specified
@@ -794,7 +794,8 @@ func (b *Writer) ReadFrom(r io.Reader) (n int64, err error) {
}
}
if readerFromOK && b.Buffered() == 0 {
- nn, err := readerFrom.ReadFrom(r)
+ var nn int64
+ nn, err = readerFrom.ReadFrom(r)
b.err = err
n += nn
return n, err
diff --git a/src/bufio/bufio_test.go b/src/bufio/bufio_test.go
index 742e195425..d51fb7fee0 100644
--- a/src/bufio/bufio_test.go
+++ b/src/bufio/bufio_test.go
@@ -77,16 +77,16 @@ func TestReaderSimple(t *testing.T) {
}
type readMaker struct {
- name string
fn func(io.Reader) io.Reader
+ name string
}
var readMakers = []readMaker{
- {"full", func(r io.Reader) io.Reader { return r }},
- {"byte", iotest.OneByteReader},
- {"half", iotest.HalfReader},
- {"data+err", iotest.DataErrReader},
- {"timeout", iotest.TimeoutReader},
+ {name: "full", fn: func(r io.Reader) io.Reader { return r }},
+ {name: "byte", fn: iotest.OneByteReader},
+ {name: "half", fn: iotest.HalfReader},
+ {name: "data+err", fn: iotest.DataErrReader},
+ {name: "timeout", fn: iotest.TimeoutReader},
}
// Call ReadString (which ends up calling everything else)
@@ -121,19 +121,19 @@ func reads(buf *Reader, m int) string {
}
type bufReader struct {
- name string
fn func(*Reader) string
+ name string
}
var bufreaders = []bufReader{
- {"1", func(b *Reader) string { return reads(b, 1) }},
- {"2", func(b *Reader) string { return reads(b, 2) }},
- {"3", func(b *Reader) string { return reads(b, 3) }},
- {"4", func(b *Reader) string { return reads(b, 4) }},
- {"5", func(b *Reader) string { return reads(b, 5) }},
- {"7", func(b *Reader) string { return reads(b, 7) }},
- {"bytes", readBytes},
- {"lines", readLines},
+ {name: "1", fn: func(b *Reader) string { return reads(b, 1) }},
+ {name: "2", fn: func(b *Reader) string { return reads(b, 2) }},
+ {name: "3", fn: func(b *Reader) string { return reads(b, 3) }},
+ {name: "4", fn: func(b *Reader) string { return reads(b, 4) }},
+ {name: "5", fn: func(b *Reader) string { return reads(b, 5) }},
+ {name: "7", fn: func(b *Reader) string { return reads(b, 7) }},
+ {name: "bytes", fn: readBytes},
+ {name: "lines", fn: readLines},
}
const minReadBufferSize = 16
@@ -682,9 +682,9 @@ func TestWriterAppend(t *testing.T) {
// Check that write errors are returned properly.
type errorWriterTest struct {
- n, m int
err error
expect error
+ n, m int
}
func (w errorWriterTest) Write(p []byte) (int, error) {
@@ -692,12 +692,12 @@ func (w errorWriterTest) Write(p []byte) (int, error) {
}
var errorWriterTests = []errorWriterTest{
- {0, 1, nil, io.ErrShortWrite},
- {1, 2, nil, io.ErrShortWrite},
- {1, 1, nil, nil},
- {0, 1, io.ErrClosedPipe, io.ErrClosedPipe},
- {1, 2, io.ErrClosedPipe, io.ErrClosedPipe},
- {1, 1, io.ErrClosedPipe, io.ErrClosedPipe},
+ {n: 0, m: 1, err: nil, expect: io.ErrShortWrite},
+ {n: 1, m: 2, err: nil, expect: io.ErrShortWrite},
+ {n: 1, m: 1, err: nil, expect: nil},
+ {n: 0, m: 1, err: io.ErrClosedPipe, expect: io.ErrClosedPipe},
+ {n: 1, m: 2, err: io.ErrClosedPipe, expect: io.ErrClosedPipe},
+ {n: 1, m: 1, err: io.ErrClosedPipe, expect: io.ErrClosedPipe},
}
func TestWriteErrors(t *testing.T) {
@@ -1054,9 +1054,9 @@ func TestReadLineNonNilLineOrError(t *testing.T) {
}
type readLineResult struct {
+ err error
line []byte
isPrefix bool
- err error
}
var readLineNewlinesTests = []struct {
@@ -1064,17 +1064,17 @@ var readLineNewlinesTests = []struct {
expect []readLineResult
}{
{"012345678901234\r\n012345678901234\r\n", []readLineResult{
- {[]byte("012345678901234"), true, nil},
- {nil, false, nil},
- {[]byte("012345678901234"), true, nil},
- {nil, false, nil},
- {nil, false, io.EOF},
+ {line: []byte("012345678901234"), isPrefix: true, err: nil},
+ {line: nil, isPrefix: false, err: nil},
+ {line: []byte("012345678901234"), isPrefix: true, err: nil},
+ {line: nil, isPrefix: false, err: nil},
+ {line: nil, isPrefix: false, err: io.EOF},
}},
{"0123456789012345\r012345678901234\r", []readLineResult{
- {[]byte("0123456789012345"), true, nil},
- {[]byte("\r012345678901234"), true, nil},
- {[]byte("\r"), false, nil},
- {nil, false, io.EOF},
+ {line: []byte("0123456789012345"), isPrefix: true, err: nil},
+ {line: []byte("\r012345678901234"), isPrefix: true, err: nil},
+ {line: []byte("\r"), isPrefix: false, err: nil},
+ {line: nil, isPrefix: false, err: io.EOF},
}},
}
@@ -1133,9 +1133,9 @@ func TestReaderWriteTo(t *testing.T) {
}
type errorWriterToTest struct {
- rn, wn int
rerr, werr error
expected error
+ rn, wn int
}
func (r errorWriterToTest) Read(p []byte) (int, error) {
@@ -1147,10 +1147,10 @@ func (w errorWriterToTest) Write(p []byte) (int, error) {
}
var errorWriterToTests = []errorWriterToTest{
- {1, 0, nil, io.ErrClosedPipe, io.ErrClosedPipe},
- {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
- {0, 0, io.ErrUnexpectedEOF, io.ErrClosedPipe, io.ErrUnexpectedEOF},
- {0, 1, io.EOF, nil, nil},
+ {rn: 1, wn: 0, rerr: nil, werr: io.ErrClosedPipe, expected: io.ErrClosedPipe},
+ {rn: 0, wn: 1, rerr: io.ErrClosedPipe, werr: nil, expected: io.ErrClosedPipe},
+ {rn: 0, wn: 0, rerr: io.ErrUnexpectedEOF, werr: io.ErrClosedPipe, expected: io.ErrUnexpectedEOF},
+ {rn: 0, wn: 1, rerr: io.EOF, werr: nil, expected: nil},
}
func TestReaderWriteToErrors(t *testing.T) {
@@ -1195,9 +1195,9 @@ func TestWriterReadFrom(t *testing.T) {
}
type errorReaderFromTest struct {
- rn, wn int
rerr, werr error
expected error
+ rn, wn int
}
func (r errorReaderFromTest) Read(p []byte) (int, error) {
@@ -1209,11 +1209,11 @@ func (w errorReaderFromTest) Write(p []byte) (int, error) {
}
var errorReaderFromTests = []errorReaderFromTest{
- {0, 1, io.EOF, nil, nil},
- {1, 1, io.EOF, nil, nil},
- {0, 1, io.ErrClosedPipe, nil, io.ErrClosedPipe},
- {0, 0, io.ErrClosedPipe, io.ErrShortWrite, io.ErrClosedPipe},
- {1, 0, nil, io.ErrShortWrite, io.ErrShortWrite},
+ {rn: 0, wn: 1, rerr: io.EOF, werr: nil, expected: nil},
+ {rn: 1, wn: 1, rerr: io.EOF, werr: nil, expected: nil},
+ {rn: 0, wn: 1, rerr: io.ErrClosedPipe, werr: nil, expected: io.ErrClosedPipe},
+ {rn: 0, wn: 0, rerr: io.ErrClosedPipe, werr: io.ErrShortWrite, expected: io.ErrClosedPipe},
+ {rn: 1, wn: 0, rerr: nil, werr: io.ErrShortWrite, expected: io.ErrShortWrite},
}
func TestWriterReadFromErrors(t *testing.T) {
@@ -1564,15 +1564,18 @@ func TestWriterReset(t *testing.T) {
func TestReaderDiscard(t *testing.T) {
tests := []struct {
- name string
- r io.Reader
+ r io.Reader
+
+ wantErr error // from Discard
+
+ name string
+
bufSize int // 0 means 16
peekSize int
n int // input to Discard
- want int // from Discard
- wantErr error // from Discard
+ want int // from Discard
wantBuffered int
}{