Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(65)

Side by Side Diff: sdk/lib/io/bytes_builder.dart

Issue 2650583005: Revert "Make HTTP headers use a growing buffer, not a fixed-size 8K one." (Closed)
Patch Set: Created 3 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | sdk/lib/io/http_headers.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file
2 // for details. All rights reserved. Use of this source code is governed by a 2 // for details. All rights reserved. Use of this source code is governed by a
3 // BSD-style license that can be found in the LICENSE file. 3 // BSD-style license that can be found in the LICENSE file.
4 4
5 part of dart.io; 5 part of dart.io;
6 6
7 /** 7 /**
8 * Builds a list of bytes, allowing bytes and lists of bytes to be added at the 8 * Builds a list of bytes, allowing bytes and lists of bytes to be added at the
9 * end. 9 * end.
10 * 10 *
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
76 * Clear the contents of the builder. 76 * Clear the contents of the builder.
77 */ 77 */
78 void clear(); 78 void clear();
79 } 79 }
80 80
81 81
82 class _CopyingBytesBuilder implements BytesBuilder { 82 class _CopyingBytesBuilder implements BytesBuilder {
83 // Start with 1024 bytes. 83 // Start with 1024 bytes.
84 static const int _INIT_SIZE = 1024; 84 static const int _INIT_SIZE = 1024;
85 85
86 static final _emptyList = new Uint8List(0);
87
88 int _length = 0; 86 int _length = 0;
89 Uint8List _buffer; 87 Uint8List _buffer;
90 88
91 _CopyingBytesBuilder([int initialCapacity = 0])
92 : _buffer = (initialCapacity <= 0)
93 ? _emptyList
94 : new Uint8List(_pow2roundup(initialCapacity));
95
96 void add(List<int> bytes) { 89 void add(List<int> bytes) {
97 int bytesLength = bytes.length; 90 int bytesLength = bytes.length;
98 if (bytesLength == 0) return; 91 if (bytesLength == 0) return;
99 int required = _length + bytesLength; 92 int required = _length + bytesLength;
100 if (_buffer.length < required) { 93 if (_buffer == null) {
101 _grow(required); 94 int size = _pow2roundup(required);
95 size = max(size, _INIT_SIZE);
96 _buffer = new Uint8List(size);
97 } else if (_buffer.length < required) {
98 // We will create a list in the range of 2-4 times larger than
99 // required.
100 int size = _pow2roundup(required) * 2;
101 var newBuffer = new Uint8List(size);
102 newBuffer.setRange(0, _buffer.length, _buffer);
103 _buffer = newBuffer;
102 } 104 }
103 assert(_buffer.length >= required); 105 assert(_buffer.length >= required);
104 if (bytes is Uint8List) { 106 if (bytes is Uint8List) {
105 _buffer.setRange(_length, required, bytes); 107 _buffer.setRange(_length, required, bytes);
106 } else { 108 } else {
107 for (int i = 0; i < bytesLength; i++) { 109 for (int i = 0; i < bytesLength; i++) {
108 _buffer[_length + i] = bytes[i]; 110 _buffer[_length + i] = bytes[i];
109 } 111 }
110 } 112 }
111 _length = required; 113 _length = required;
112 } 114 }
113 115
114 void addByte(int byte) { 116 void addByte(int byte) { add([byte]); }
115 if (_buffer.length == _length) {
116 // The grow algorithm always at least doubles.
117 // If we added one to _length it would quadruple unnecessarily.
118 _grow(_length);
119 }
120 assert(_buffer.length > _length);
121 _buffer[_length] = byte;
122 _length++;
123 }
124
125 void _grow(int required) {
126 // We will create a list in the range of 2-4 times larger than
127 // required.
128 int newSize = required * 2;
129 if (newSize < _INIT_SIZE) {
130 newSize = _INIT_SIZE;
131 } else {
132 newSize = _pow2roundup(newSize);
133 }
134 var newBuffer = new Uint8List(newSize);
135 newBuffer.setRange(0, _buffer.length, _buffer);
136 _buffer = newBuffer;
137 }
138 117
139 List<int> takeBytes() { 118 List<int> takeBytes() {
140 if (_length == 0) return _emptyList; 119 if (_buffer == null) return new Uint8List(0);
141 var buffer = new Uint8List.view(_buffer.buffer, 0, _length); 120 var buffer = new Uint8List.view(_buffer.buffer, 0, _length);
142 clear(); 121 clear();
143 return buffer; 122 return buffer;
144 } 123 }
145 124
146 List<int> toBytes() { 125 List<int> toBytes() {
147 if (_length == 0) return _emptyList; 126 if (_buffer == null) return new Uint8List(0);
148 return new Uint8List.fromList( 127 return new Uint8List.fromList(
149 new Uint8List.view(_buffer.buffer, 0, _length)); 128 new Uint8List.view(_buffer.buffer, 0, _length));
150 } 129 }
151 130
152 int get length => _length; 131 int get length => _length;
153 132
154 bool get isEmpty => _length == 0; 133 bool get isEmpty => _length == 0;
155 134
156 bool get isNotEmpty => _length != 0; 135 bool get isNotEmpty => _length != 0;
157 136
158 void clear() { 137 void clear() {
159 _length = 0; 138 _length = 0;
160 _buffer = _emptyList; 139 _buffer = null;
161 } 140 }
162 141
163 static int _pow2roundup(int x) { 142 int _pow2roundup(int x) {
164 assert(x > 0);
165 --x; 143 --x;
166 x |= x >> 1; 144 x |= x >> 1;
167 x |= x >> 2; 145 x |= x >> 2;
168 x |= x >> 4; 146 x |= x >> 4;
169 x |= x >> 8; 147 x |= x >> 8;
170 x |= x >> 16; 148 x |= x >> 16;
171 return x + 1; 149 return x + 1;
172 } 150 }
173 } 151 }
174 152
175 153
176 class _BytesBuilder implements BytesBuilder { 154 class _BytesBuilder implements BytesBuilder {
177 int _length = 0; 155 int _length = 0;
178 final List<Uint8List> _chunks = []; 156 final List<Uint8List> _chunks = [];
179 157
180 void add(List<int> bytes) { 158 void add(List<int> bytes) {
181 Uint8List typedBytes; 159 Uint8List typedBytes;
182 if (bytes is Uint8List) { 160 if (bytes is Uint8List) {
183 typedBytes = bytes; 161 typedBytes = bytes;
184 } else { 162 } else {
185 typedBytes = new Uint8List.fromList(bytes); 163 typedBytes = new Uint8List.fromList(bytes);
186 } 164 }
187 _chunks.add(typedBytes); 165 _chunks.add(typedBytes);
188 _length += typedBytes.length; 166 _length += typedBytes.length;
189 } 167 }
190 168
191 void addByte(int byte) { 169 void addByte(int byte) { add([byte]); }
192 _chunks.add(new Uint8List(1)..[0] = byte);
193 _length++;
194 }
195 170
196 List<int> takeBytes() { 171 List<int> takeBytes() {
197 if (_length == 0) return _CopyingBytesBuilder._emptyList; 172 if (_chunks.length == 0) return new Uint8List(0);
198 if (_chunks.length == 1) { 173 if (_chunks.length == 1) {
199 var buffer = _chunks[0]; 174 var buffer = _chunks.single;
200 clear(); 175 clear();
201 return buffer; 176 return buffer;
202 } 177 }
203 var buffer = new Uint8List(_length); 178 var buffer = new Uint8List(_length);
204 int offset = 0; 179 int offset = 0;
205 for (var chunk in _chunks) { 180 for (var chunk in _chunks) {
206 buffer.setRange(offset, offset + chunk.length, chunk); 181 buffer.setRange(offset, offset + chunk.length, chunk);
207 offset += chunk.length; 182 offset += chunk.length;
208 } 183 }
209 clear(); 184 clear();
210 return buffer; 185 return buffer;
211 } 186 }
212 187
213 List<int> toBytes() { 188 List<int> toBytes() {
214 if (_length == 0) return _CopyingBytesBuilder._emptyList; 189 if (_chunks.length == 0) return new Uint8List(0);
215 var buffer = new Uint8List(_length); 190 var buffer = new Uint8List(_length);
216 int offset = 0; 191 int offset = 0;
217 for (var chunk in _chunks) { 192 for (var chunk in _chunks) {
218 buffer.setRange(offset, offset + chunk.length, chunk); 193 buffer.setRange(offset, offset + chunk.length, chunk);
219 offset += chunk.length; 194 offset += chunk.length;
220 } 195 }
221 return buffer; 196 return buffer;
222 } 197 }
223 198
224 int get length => _length; 199 int get length => _length;
225 200
226 bool get isEmpty => _length == 0; 201 bool get isEmpty => _length == 0;
227 202
228 bool get isNotEmpty => _length != 0; 203 bool get isNotEmpty => _length != 0;
229 204
230 void clear() { 205 void clear() {
231 _length = 0; 206 _length = 0;
232 _chunks.clear(); 207 _chunks.clear();
233 } 208 }
234 } 209 }
OLDNEW
« no previous file with comments | « no previous file | sdk/lib/io/http_headers.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698