Check-in [70896f73e9]
Overview
Comment:Additional fixes and code simplification for MinReader
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 70896f73e95a9811868d697c2c2f59eb9899c3ab
User & Date: spaskalev on 2014-12-23 18:39:59
Other Links: manifest | tags
Context
2014-12-23
18:52
Renamed MinReader to BlockReader. The later is now used by predictor's decompressor to simplify the code and deal away with the need for internal buffering. check-in: 38f8e62c81 user: spaskalev tags: trunk
18:39
Additional fixes and code simplification for MinReader check-in: 70896f73e9 user: spaskalev tags: trunk
14:27
minReader fixes check-in: 4195e7817d user: spaskalev tags: trunk
Changes

Modified src/0dev.org/ioutil/ioutil.go from [4d4fd7d642] to [3d22f83cbe].

     1      1   // Package ioutil contains various constructs for io operations
     2      2   package ioutil
     3      3   
     4      4   import (
            5  +	//"fmt"
     5      6   	"io"
     6      7   )
     7      8   
     8      9   // An function alias type that implements io.Writer
     9     10   type WriterFunc func([]byte) (int, error)
    10     11   
    11     12   // Delegates the call to the WriterFunc while implementing io.Writer
................................................................................
    22     23   }
    23     24   
    24     25   // Returns a reader that will delegate calls to Read(...) while ensuring
    25     26   // that the output buffer will never be smaller than the required size
    26     27   func MinReader(reader io.Reader, size int) io.Reader {
    27     28   	var buffer []byte = make([]byte, 0, size)
    28     29   
    29         -	return ReaderFunc(func(output []byte) (readCount int, e error) {
           30  +	return ReaderFunc(func(output []byte) (int, error) {
    30     31   		var (
    31         -			bufferLength int = len(buffer)
    32         -			err          error
           32  +			readCount int
           33  +			err       error
    33     34   		)
    34     35   	start:
           36  +		//fmt.Println("Requesting read with length ", len(output), "buffer's length is ", len(buffer))
           37  +
    35     38   		// Reply with the buffered data if there is any
    36         -		if bufferLength > 0 {
           39  +		if len(buffer) > 0 {
    37     40   			readCount = copy(output, buffer)
    38     41   
    39         -			if readCount < bufferLength {
    40         -				// Advance the data in the buffer
    41         -				buffer = buffer[:copy(buffer, buffer[readCount:])]
    42         -			} else {
    43         -				// Clear the buffer
    44         -				buffer = buffer[:0]
           42  +			// Advance the data in the buffer
           43  +			buffer = buffer[:copy(buffer, buffer[readCount:])]
           44  +
           45  +			//fmt.Println("After buffer read - buffer lenght is", len(buffer))
           46  +
           47  +			if len(buffer) == 0 {
           48  +				return readCount, err
    45     49   			}
    46         -			// Stage any error for returning
    47         -			e, err = err, nil
    48         -			return readCount, e
           50  +
           51  +			// Do not propagate an error until the buffer is exhausted
           52  +			return readCount, nil
    49     53   		}
    50     54   
    51     55   		// Delegate if the buffer is empty and the destination buffer is large enough
    52     56   		if len(output) >= size {
    53         -			return reader.Read(output[:len(output)/size])
           57  +			//fmt.Println("Delegating read for output length ", len(output), " and size ", size)
           58  +			return reader.Read(output[:(len(output)/size)*size])
    54     59   		}
    55     60   
    56         -		// Extend the buffer up to the desired size and perform a Read
    57         -		buffer = buffer[:size]
    58         -		readCount, err = reader.Read(buffer)
           61  +		// Perform a read into the buffer
           62  +		readCount, err = reader.Read(buffer[:size])
    59     63   
    60     64   		// Size the buffer down to the read data size and restart
    61     65   		buffer = buffer[:readCount]
    62         -		bufferLength = len(buffer)
           66  +
           67  +		//fmt.Println("Read into buffer: ", len(buffer), "bytes")
    63     68   
    64         -		if bufferLength > 0 {
           69  +		if len(buffer) > 0 {
    65     70   			goto start
    66     71   		}
    67         -		// Stage any error for returning
    68         -		e, err = err, nil
    69         -		return 0, e
           72  +		return 0, err
    70     73   	})
    71     74   }