Rietveld Code Review Tool
Help | Bug tracker | Discussion group | Source code | Sign in
(151)

Delta Between Two Patch Sets: src/pkg/bufio/bufio.go

Issue 8819049: code review 8819049: bufio: make Reader buffer transient (Closed)
Left Patch Set: Created 10 years, 11 months ago
Right Patch Set: diff -r 43b3233f0b5b https://go.googlecode.com/hg/ Created 10 years, 10 months ago
Left:
Right:
Use n/p to move between diff chunks; N/P to move between comments. Please Sign in to add in-line comments.
Jump to:
Right: Side by side diff | Download
« no previous file with change/comment | « no previous file | src/pkg/bufio/bufio_test.go » ('j') | no next file with change/comment »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
LEFTRIGHT
(no file at all)
1 // Copyright 2009 The Go Authors. All rights reserved. 1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style 2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file. 3 // license that can be found in the LICENSE file.
4 4
5 // Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer 5 // Package bufio implements buffered I/O. It wraps an io.Reader or io.Writer
6 // object, creating another object (Reader or Writer) that also implements 6 // object, creating another object (Reader or Writer) that also implements
7 // the interface but provides buffering and some help for textual I/O. 7 // the interface but provides buffering and some help for textual I/O.
8 package bufio 8 package bufio
9 9
10 import ( 10 import (
(...skipping 11 matching lines...) Expand all
22 ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte") 22 ErrInvalidUnreadByte = errors.New("bufio: invalid use of UnreadByte")
23 ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune") 23 ErrInvalidUnreadRune = errors.New("bufio: invalid use of UnreadRune")
24 ErrBufferFull = errors.New("bufio: buffer full") 24 ErrBufferFull = errors.New("bufio: buffer full")
25 ErrNegativeCount = errors.New("bufio: negative count") 25 ErrNegativeCount = errors.New("bufio: negative count")
26 ) 26 )
27 27
28 // Buffered input. 28 // Buffered input.
29 29
30 // Reader implements buffering for an io.Reader object. 30 // Reader implements buffering for an io.Reader object.
31 type Reader struct { 31 type Reader struct {
32 » buf []byte 32 » buf []byte // either nil or []byte of size bufSize
33 » bufSize int
33 rd io.Reader 34 rd io.Reader
34 r, w int 35 r, w int
35 err error 36 err error
36 lastByte int 37 lastByte int
37 lastRuneSize int 38 lastRuneSize int
38 } 39 }
39 40
40 const minReadBufferSize = 16 41 const minReadBufferSize = 16
41 42
42 // NewReaderSize returns a new Reader whose buffer has at least the specified 43 // NewReaderSize returns a new Reader whose buffer has at least the specified
43 // size. If the argument io.Reader is already a Reader with large enough 44 // size. If the argument io.Reader is already a Reader with large enough
44 // size, it returns the underlying Reader. 45 // size, it returns the underlying Reader.
45 func NewReaderSize(rd io.Reader, size int) *Reader { 46 func NewReaderSize(rd io.Reader, size int) *Reader {
46 // Is it already a Reader? 47 // Is it already a Reader?
47 b, ok := rd.(*Reader) 48 b, ok := rd.(*Reader)
48 » if ok && len(b.buf) >= size { 49 » if ok && b.bufSize >= size {
49 return b 50 return b
50 } 51 }
51 if size < minReadBufferSize { 52 if size < minReadBufferSize {
52 size = minReadBufferSize 53 size = minReadBufferSize
53 } 54 }
54 » return &Reader{ 55 » r := &Reader{
55 » » buf: make([]byte, size), 56 » » bufSize: size,
56 rd: rd, 57 rd: rd,
57 lastByte: -1, 58 lastByte: -1,
58 lastRuneSize: -1, 59 lastRuneSize: -1,
59 } 60 }
61 if size > defaultBufSize {
62 // TODO(bradfitz): make all buffer sizes recycle
63 r.buf = make([]byte, r.bufSize)
64 }
65 return r
60 } 66 }
61 67
62 // NewReader returns a new Reader whose buffer has the default size. 68 // NewReader returns a new Reader whose buffer has the default size.
63 func NewReader(rd io.Reader) *Reader { 69 func NewReader(rd io.Reader) *Reader {
64 return NewReaderSize(rd, defaultBufSize) 70 return NewReaderSize(rd, defaultBufSize)
65 } 71 }
66 72
67 var errNegativeRead = errors.New("bufio: reader returned negative count from Rea d") 73 var errNegativeRead = errors.New("bufio: reader returned negative count from Rea d")
68 74
75 // TODO: use a sync.Cache instead of this:
76 const arbitrarySize = 8
77
78 // bufCache holds only byte slices with capacity defaultBufSize.
79 var bufCache = make(chan []byte, arbitrarySize)
80
81 // allocBuf makes b.buf non-nil.
82 func (b *Reader) allocBuf() {
83 if b.buf != nil {
84 return
85 }
86 select {
87 case b.buf = <-bufCache:
88 b.buf = b.buf[:b.bufSize]
89 default:
90 b.buf = make([]byte, b.bufSize, defaultBufSize)
91 }
92 }
93
94 // putBuf returns b.buf if it's unused.
95 func (b *Reader) putBuf() {
96 if b.r == b.w && b.err == io.EOF && cap(b.buf) == defaultBufSize {
97 select {
98 case bufCache <- b.buf:
99 b.buf = nil
100 b.r = 0
101 b.w = 0
102 default:
103 }
104 }
105 }
106
69 // fill reads a new chunk into the buffer. 107 // fill reads a new chunk into the buffer.
70 func (b *Reader) fill() { 108 func (b *Reader) fill() {
109 b.allocBuf()
110
71 // Slide existing data to beginning. 111 // Slide existing data to beginning.
72 if b.r > 0 { 112 if b.r > 0 {
73 copy(b.buf, b.buf[b.r:b.w]) 113 copy(b.buf, b.buf[b.r:b.w])
74 b.w -= b.r 114 b.w -= b.r
75 b.r = 0 115 b.r = 0
76 } 116 }
77 117
78 // Read new data. 118 // Read new data.
79 n, err := b.rd.Read(b.buf[b.w:]) 119 n, err := b.rd.Read(b.buf[b.w:])
80 if n < 0 { 120 if n < 0 {
(...skipping 12 matching lines...) Expand all
93 } 133 }
94 134
95 // Peek returns the next n bytes without advancing the reader. The bytes stop 135 // Peek returns the next n bytes without advancing the reader. The bytes stop
96 // being valid at the next read call. If Peek returns fewer than n bytes, it 136 // being valid at the next read call. If Peek returns fewer than n bytes, it
97 // also returns an error explaining why the read is short. The error is 137 // also returns an error explaining why the read is short. The error is
98 // ErrBufferFull if n is larger than b's buffer size. 138 // ErrBufferFull if n is larger than b's buffer size.
99 func (b *Reader) Peek(n int) ([]byte, error) { 139 func (b *Reader) Peek(n int) ([]byte, error) {
100 if n < 0 { 140 if n < 0 {
101 return nil, ErrNegativeCount 141 return nil, ErrNegativeCount
102 } 142 }
103 » if n > len(b.buf) { 143 » if n > b.bufSize {
104 return nil, ErrBufferFull 144 return nil, ErrBufferFull
105 } 145 }
106 for b.w-b.r < n && b.err == nil { 146 for b.w-b.r < n && b.err == nil {
107 b.fill() 147 b.fill()
108 } 148 }
109 m := b.w - b.r 149 m := b.w - b.r
110 if m > n { 150 if m > n {
111 m = n 151 m = n
112 } 152 }
113 var err error 153 var err error
(...skipping 13 matching lines...) Expand all
127 // At EOF, the count will be zero and err will be io.EOF. 167 // At EOF, the count will be zero and err will be io.EOF.
128 func (b *Reader) Read(p []byte) (n int, err error) { 168 func (b *Reader) Read(p []byte) (n int, err error) {
129 n = len(p) 169 n = len(p)
130 if n == 0 { 170 if n == 0 {
131 return 0, b.readErr() 171 return 0, b.readErr()
132 } 172 }
133 if b.w == b.r { 173 if b.w == b.r {
134 if b.err != nil { 174 if b.err != nil {
135 return 0, b.readErr() 175 return 0, b.readErr()
136 } 176 }
137 » » if len(p) >= len(b.buf) { 177 » » if len(p) >= b.bufSize {
138 // Large read, empty buffer. 178 // Large read, empty buffer.
139 // Read directly into p to avoid copy. 179 // Read directly into p to avoid copy.
140 n, b.err = b.rd.Read(p) 180 n, b.err = b.rd.Read(p)
141 if n > 0 { 181 if n > 0 {
142 b.lastByte = int(p[n-1]) 182 b.lastByte = int(p[n-1])
143 b.lastRuneSize = -1 183 b.lastRuneSize = -1
144 } 184 }
145 return n, b.readErr() 185 return n, b.readErr()
146 } 186 }
147 b.fill() 187 b.fill()
148 if b.w == b.r { 188 if b.w == b.r {
149 return 0, b.readErr() 189 return 0, b.readErr()
150 } 190 }
151 } 191 }
152 192
153 if n > b.w-b.r { 193 if n > b.w-b.r {
154 n = b.w - b.r 194 n = b.w - b.r
155 } 195 }
156 copy(p[0:n], b.buf[b.r:]) 196 copy(p[0:n], b.buf[b.r:])
157 b.r += n 197 b.r += n
158 b.lastByte = int(b.buf[b.r-1]) 198 b.lastByte = int(b.buf[b.r-1])
159 b.lastRuneSize = -1 199 b.lastRuneSize = -1
200 b.putBuf()
160 return n, nil 201 return n, nil
161 } 202 }
162 203
163 // ReadByte reads and returns a single byte. 204 // ReadByte reads and returns a single byte.
164 // If no byte is available, returns an error. 205 // If no byte is available, returns an error.
165 func (b *Reader) ReadByte() (c byte, err error) { 206 func (b *Reader) ReadByte() (c byte, err error) {
166 b.lastRuneSize = -1 207 b.lastRuneSize = -1
167 for b.w == b.r { 208 for b.w == b.r {
168 if b.err != nil { 209 if b.err != nil {
169 return 0, b.readErr() 210 return 0, b.readErr()
170 } 211 }
171 b.fill() 212 b.fill()
172 } 213 }
173 c = b.buf[b.r] 214 c = b.buf[b.r]
174 b.r++ 215 b.r++
175 b.lastByte = int(c) 216 b.lastByte = int(c)
217 if b.err != nil { // avoid putBuf call in the common case
218 b.putBuf()
219 }
176 return c, nil 220 return c, nil
177 } 221 }
178 222
179 // UnreadByte unreads the last byte. Only the most recently read byte can be un read. 223 // UnreadByte unreads the last byte. Only the most recently read byte can be un read.
180 func (b *Reader) UnreadByte() error { 224 func (b *Reader) UnreadByte() error {
181 b.lastRuneSize = -1 225 b.lastRuneSize = -1
182 if b.r == b.w && b.lastByte >= 0 { 226 if b.r == b.w && b.lastByte >= 0 {
227 b.allocBuf()
183 b.w = 1 228 b.w = 1
184 b.r = 0 229 b.r = 0
185 b.buf[0] = byte(b.lastByte) 230 b.buf[0] = byte(b.lastByte)
186 b.lastByte = -1 231 b.lastByte = -1
187 return nil 232 return nil
188 } 233 }
189 if b.r <= 0 { 234 if b.r <= 0 {
190 return ErrInvalidUnreadByte 235 return ErrInvalidUnreadByte
191 } 236 }
192 b.r-- 237 b.r--
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
374 419
375 // ReadString reads until the first occurrence of delim in the input, 420 // ReadString reads until the first occurrence of delim in the input,
376 // returning a string containing the data up to and including the delimiter. 421 // returning a string containing the data up to and including the delimiter.
377 // If ReadString encounters an error before finding a delimiter, 422 // If ReadString encounters an error before finding a delimiter,
378 // it returns the data read before the error and the error itself (often io.EOF) . 423 // it returns the data read before the error and the error itself (often io.EOF) .
379 // ReadString returns err != nil if and only if the returned data does not end i n 424 // ReadString returns err != nil if and only if the returned data does not end i n
380 // delim. 425 // delim.
381 // For simple uses, a Scanner may be more convenient. 426 // For simple uses, a Scanner may be more convenient.
382 func (b *Reader) ReadString(delim byte) (line string, err error) { 427 func (b *Reader) ReadString(delim byte) (line string, err error) {
383 bytes, err := b.ReadBytes(delim) 428 bytes, err := b.ReadBytes(delim)
384 » return string(bytes), err 429 » line = string(bytes)
430 » b.putBuf()
431 » return line, err
385 } 432 }
386 433
387 // WriteTo implements io.WriterTo. 434 // WriteTo implements io.WriterTo.
388 func (b *Reader) WriteTo(w io.Writer) (n int64, err error) { 435 func (b *Reader) WriteTo(w io.Writer) (n int64, err error) {
389 n, err = b.writeBuf(w) 436 n, err = b.writeBuf(w)
390 if err != nil { 437 if err != nil {
391 return 438 return
392 } 439 }
393 440
394 if r, ok := b.rd.(io.WriterTo); ok { 441 if r, ok := b.rd.(io.WriterTo); ok {
(...skipping 14 matching lines...) Expand all
409 b.err = nil 456 b.err = nil
410 } 457 }
411 458
412 return n, b.readErr() 459 return n, b.readErr()
413 } 460 }
414 461
415 // writeBuf writes the Reader's buffer to the writer. 462 // writeBuf writes the Reader's buffer to the writer.
416 func (b *Reader) writeBuf(w io.Writer) (int64, error) { 463 func (b *Reader) writeBuf(w io.Writer) (int64, error) {
417 n, err := w.Write(b.buf[b.r:b.w]) 464 n, err := w.Write(b.buf[b.r:b.w])
418 b.r += n 465 b.r += n
466 b.putBuf()
419 return int64(n), err 467 return int64(n), err
420 } 468 }
421 469
422 // buffered output 470 // buffered output
423 471
424 // Writer implements buffering for an io.Writer object. 472 // Writer implements buffering for an io.Writer object.
425 // If an error occurs writing to a Writer, no more data will be 473 // If an error occurs writing to a Writer, no more data will be
426 // accepted and all subsequent writes will return the error. 474 // accepted and all subsequent writes will return the error.
427 type Writer struct { 475 type Writer struct {
428 err error 476 err error
429 buf []byte 477 buf []byte
430 n int 478 n int
431 wr io.Writer 479 wr io.Writer
432 } 480 }
433 481
434 // NewWriterSize returns a new Writer whose buffer has at least the specified 482 // NewWriterSize returns a new Writer whose buffer has at least the specified
435 // size. If the argument io.Writer is already a Writer with large enough 483 // size. If the argument io.Writer is already a Writer with large enough
436 // size, it returns the underlying Writer. 484 // size, it returns the underlying Writer.
437 func NewWriterSize(wr io.Writer, size int) *Writer { 485 func NewWriterSize(wr io.Writer, size int) *Writer {
438 // Is it already a Writer? 486 // Is it already a Writer?
439 b, ok := wr.(*Writer) 487 b, ok := wr.(*Writer)
440 if ok && len(b.buf) >= size { 488 if ok && len(b.buf) >= size {
441 return b 489 return b
442 } 490 }
443 if size <= 0 { 491 if size <= 0 {
444 size = defaultBufSize 492 size = defaultBufSize
445 } 493 }
446 b = new(Writer) 494 b = new(Writer)
495 // TODO(bradfitz): make Writer buffers lazy too, like Reader's
447 b.buf = make([]byte, size) 496 b.buf = make([]byte, size)
448 b.wr = wr 497 b.wr = wr
449 return b 498 return b
450 } 499 }
451 500
452 // NewWriter returns a new Writer whose buffer has the default size. 501 // NewWriter returns a new Writer whose buffer has the default size.
453 func NewWriter(wr io.Writer) *Writer { 502 func NewWriter(wr io.Writer) *Writer {
454 return NewWriterSize(wr, defaultBufSize) 503 return NewWriterSize(wr, defaultBufSize)
455 } 504 }
456 505
(...skipping 155 matching lines...) Expand 10 before | Expand all | Expand 10 after
612 // It implements io.ReadWriter. 661 // It implements io.ReadWriter.
613 type ReadWriter struct { 662 type ReadWriter struct {
614 *Reader 663 *Reader
615 *Writer 664 *Writer
616 } 665 }
617 666
618 // NewReadWriter allocates a new ReadWriter that dispatches to r and w. 667 // NewReadWriter allocates a new ReadWriter that dispatches to r and w.
619 func NewReadWriter(r *Reader, w *Writer) *ReadWriter { 668 func NewReadWriter(r *Reader, w *Writer) *ReadWriter {
620 return &ReadWriter{r, w} 669 return &ReadWriter{r, w}
621 } 670 }
LEFTRIGHT

Powered by Google App Engine
RSS Feeds Recent Issues | This issue
This is Rietveld f62528b