Check-in [46da7a6ae9]
Overview
SHA1:46da7a6ae933a799da23fba4c3d096e592f39934
Date: 2014-12-25 00:26:02
User: spaskalev
Comment:Extracted SizedWriter to a sizedWriter struct with a Write() method.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2014-12-25
00:43
[50507bd510] Extracted predictor's compressor and decompressor code into separate structs that embed Sized{Writer,Reader} (user: spaskalev, tags: trunk)
00:26
[46da7a6ae9] Extracted SizedWriter to a sizedWriter struct with a Write() method. (user: spaskalev, tags: trunk)
2014-12-24
23:58
[2cec92909f] 0dev.org/ioutil/SizedReader is now as fast as bufio.Reader if not faster for a buffer of 4096 bytes. Switched pdc to use it for decompression buffering and removed profiling code from the former (user: spaskalev, tags: trunk)
Changes

Modified src/0dev.org/ioutil/ioutil.go from [9862ea3396] to [c11fdb5a53].

    23     23   
    24     24   // Returns a writer that delegates calls to Write(...) while ensuring
    25     25   // that it is never called with less bytes than the specified amount.
    26     26   //
    27     27   // Calls with fewer bytes are buffered while a call with a nil slice
    28     28   // causes the buffer to be flushed to the underlying writer.
    29     29   func SizedWriter(writer io.Writer, size int) io.Writer {
    30         -	var buffer []byte = make([]byte, 0, size)
    31         -	var write WriterFunc
    32         -
    33         -	write = func(input []byte) (int, error) {
    34         -		var (
    35         -			count int
    36         -			err   error
    37         -		)
    38         -
    39         -		// Flush the buffer when called with no bytes to write
    40         -		if input == nil {
    41         -			// Call the writer with whatever we have in store..
    42         -			count, err = writer.Write(buffer)
    43         -
    44         -			// Advance the buffer
    45         -			buffer = buffer[:copy(buffer, buffer[count:])]
    46         -
    47         -			return 0, err
    48         -		}
    49         -
    50         -		// Delegate to the writer if the size is right
    51         -		if len(buffer) == 0 && len(input) >= size {
    52         -			reduced := (len(input) / size) * size
    53         -			count, err = writer.Write(input[:reduced])
    54         -			if count < reduced || err != nil {
    55         -				return count, err
    56         -			}
    57         -
    58         -			// Stage any remaining data in the buffer
    59         -			buffer = append(buffer, input[count:]...)
    60         -			return len(input), nil
    61         -		}
    62         -
    63         -		// Append data to the buffer
    64         -		count = copy(buffer[len(buffer):size], input)
    65         -		buffer = buffer[:len(buffer)+count]
    66         -
    67         -		// Return if we don't have enough bytes to write
    68         -		if len(buffer) < size {
    69         -			return len(input), nil
    70         -		}
    71         -
    72         -		// Flush the buffer as it is filled
    73         -		_, err = write(nil)
    74         -		if err != nil {
           30  +	var sw sizedWriter
           31  +	sw.writer = writer
           32  +	sw.buffer = make([]byte, 0, size)
           33  +	sw.size = size
           34  +	return &sw
           35  +}
           36  +
           37  +type sizedWriter struct {
           38  +	writer io.Writer
           39  +	buffer []byte
           40  +	size   int
           41  +}
           42  +
           43  +func (sw *sizedWriter) Write(input []byte) (int, error) {
           44  +	var (
           45  +		count int
           46  +		err   error
           47  +	)
           48  +
           49  +	// Flush the buffer when called with no bytes to write
           50  +	if input == nil {
           51  +		// Call the writer with whatever we have in store..
           52  +		count, err = sw.writer.Write(sw.buffer)
           53  +
           54  +		// Advance the buffer
           55  +		sw.buffer = sw.buffer[:copy(sw.buffer, sw.buffer[count:])]
           56  +
           57  +		return 0, err
           58  +	}
           59  +
           60  +	// Delegate to the writer if the size is right
           61  +	if len(sw.buffer) == 0 && len(input) >= sw.size {
           62  +		reduced := (len(input) / sw.size) * sw.size
           63  +		count, err = sw.writer.Write(input[:reduced])
           64  +		if count < reduced || err != nil {
    75     65   			return count, err
    76     66   		}
    77     67   
    78         -		// Handle the rest of the input
    79         -		return write(input[count:])
           68  +		// Stage any remaining data in the buffer
           69  +		sw.buffer = append(sw.buffer, input[count:]...)
           70  +		return len(input), nil
           71  +	}
           72  +
           73  +	// Append data to the buffer
           74  +	count = copy(sw.buffer[len(sw.buffer):sw.size], input)
           75  +	sw.buffer = sw.buffer[:len(sw.buffer)+count]
           76  +
           77  +	// Return if we don't have enough bytes to write
           78  +	if len(sw.buffer) < sw.size {
           79  +		return len(input), nil
           80  +	}
           81  +
           82  +	// Flush the buffer as it is filled
           83  +	_, err = sw.Write(nil)
           84  +	if err != nil {
           85  +		return count, err
    80     86   	}
    81     87   
    82         -	return write
    83         -}
    84         -
    85         -type sizedReader struct {
    86         -	reader         io.Reader
    87         -	buffer         []byte
    88         -	from, to, size int
           88  +	// Handle the rest of the input
           89  +	return sw.Write(input[count:])
    89     90   }
    90     91   
    91     92   // Returns a reader that delegates calls to Read(...) while ensuring
    92     93   // that the output buffer is never smaller than the required size
    93     94   // and is downsized to a multiple of the required size if larger.
    94     95   func SizedReader(reader io.Reader, size int) io.Reader {
    95     96   	var sr sizedReader
    96     97   	sr.reader = reader
    97     98   	sr.buffer = make([]byte, size)
    98     99   	sr.size, sr.from, sr.to = size, 0, 0
    99    100   	return &sr
   100    101   }
          102  +
          103  +type sizedReader struct {
          104  +	reader         io.Reader
          105  +	buffer         []byte
          106  +	from, to, size int
          107  +}
   101    108   
   102    109   func (sr *sizedReader) Read(output []byte) (int, error) {
   103    110   	var (
   104    111   		count int
   105    112   		err   error
   106    113   	)
   107    114