Check-in [701ac713de]
Overview
SHA1:701ac713deb812f7f5feda484c6a43147071f8f9
Date: 2014-12-24 23:33:45
User: spaskalev
Comment:Made SizedReader faster by keeping explicit buffer indices.
Timelines: family | ancestors | descendants | both | trunk
Downloads: Tarball | ZIP archive
Other Links: files | file ages | folders | manifest
Tags And Properties
Context
2014-12-24
23:45
[b703c38e0b] Extracted SizedReader to a sizedReader type with a Read() method. Closures seem to be slower in Go 1.4 and there is no real need for SizedReader to be a closure. (user: spaskalev, tags: trunk)
23:33
[701ac713de] Made SizedReader faster by keeping explicit buffer indices. (user: spaskalev, tags: trunk)
22:32
[1717bfae3b] Use 0dev.org/ioutil.SizedWriter as an output buffer for pdc in both compress and decompress modes. (user: spaskalev, tags: trunk)
Changes

Modified src/0dev.org/ioutil/ioutil.go from [bca057263b] to [e5419d451e].

82
83
84
85
86
87
88

89


90
91
92
93
94
95

96
97
98

99
100
101
102

103
104
105




106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
	return write
}

// Returns a reader that delegates calls to Read(...) while ensuring
// that the output buffer is never smaller than the required size
// and is downsized to a multiple of the required size if larger.
func SizedReader(reader io.Reader, size int) io.Reader {

	var buffer []byte = make([]byte, 0, size)



	return ReaderFunc(func(output []byte) (int, error) {
		var (
			count int
			err   error
		)

	start:
		// Reply with the buffered data if there is any
		if len(buffer) > 0 {

			count = copy(output, buffer)

			// Advance the data in the buffer
			buffer = buffer[:copy(buffer, buffer[count:])]


			// Return count and error if we have read the whole buffer
			if len(buffer) == 0 {




				return count, err
			}

			// Do not propagate an error until the buffer is exhausted
			return count, nil
		}

		// Delegate if the buffer is empty and the destination buffer is large enough
		if len(output) >= size {
			return reader.Read(output[:(len(output)/size)*size])
		}

		// Perform a read into the buffer
		count, err = reader.Read(buffer[:size])

		// Size the buffer down to the read data size
		// and restart if we have successfully read some bytes
		buffer = buffer[:count]
		if len(buffer) > 0 {
			goto start
		}

		// Returning on err/misbehaving noop reader
		return 0, err
	})
}







>
|
>
>






>


<
>
|


<
>

<
|
>
>
>
>













|



|
|







82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101

102
103
104
105

106
107

108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
	return write
}

// Returns a reader that delegates calls to Read(...) while ensuring
// that the output buffer is never smaller than the required size
// and is downsized to a multiple of the required size if larger.
func SizedReader(reader io.Reader, size int) io.Reader {
	var (
		buffer   []byte = make([]byte, size)
		from, to int    = 0, 0
	)

	return ReaderFunc(func(output []byte) (int, error) {
		var (
			count int
			err   error
		)

	start:
		// Reply with the buffered data if there is any

		if to-from > 0 {
			count = copy(output, buffer[from:to])

			// Advance the data in the buffer

			from += count


			// Check whether we have reached the end of the buffer
			if to-from == 0 {
				// Reset the buffer
				from, to = 0, 0

				return count, err
			}

			// Do not propagate an error until the buffer is exhausted
			return count, nil
		}

		// Delegate if the buffer is empty and the destination buffer is large enough
		if len(output) >= size {
			return reader.Read(output[:(len(output)/size)*size])
		}

		// Perform a read into the buffer
		count, err = reader.Read(buffer)

		// Size the buffer down to the read data size
		// and restart if we have successfully read some bytes
		from, to = 0, count
		if to-from > 0 {
			goto start
		}

		// Returning on err/misbehaving noop reader
		return 0, err
	})
}