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

Side by Side Diff: sdk/lib/core/uri.dart

Issue 2119833002: Cache hashCode in Uri implementations to improve performance when used as, e.g., Map key. (Closed) Base URL: https://github.com/dart-lang/sdk.git@master
Patch Set: Created 4 years, 5 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 | no next file » | 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) 2012, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2012, 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.core; 5 part of dart.core;
6 6
7 // Frequently used character codes. 7 // Frequently used character codes.
8 const int _SPACE = 0x20; 8 const int _SPACE = 0x20;
9 const int _PERCENT = 0x25; 9 const int _PERCENT = 0x25;
10 const int _PLUS = 0x2B; 10 const int _PLUS = 0x2B;
(...skipping 1352 matching lines...) Expand 10 before | Expand all | Expand 10 after
1363 * Cache the computed return value of [pathSegements]. 1363 * Cache the computed return value of [pathSegements].
1364 */ 1364 */
1365 List<String> _pathSegments; 1365 List<String> _pathSegments;
1366 1366
1367 /** 1367 /**
1368 * Cache of the full normalized text representation of the URI. 1368 * Cache of the full normalized text representation of the URI.
1369 */ 1369 */
1370 String _text; 1370 String _text;
1371 1371
1372 /** 1372 /**
1373 * Cache of the hashCode of [_text].
1374 *
1375 * Is null until computed.
1376 */
1377 int _hashCodeCache;
1378
1379 /**
1373 * Cache the computed return value of [queryParameters]. 1380 * Cache the computed return value of [queryParameters].
1374 */ 1381 */
1375 Map<String, String> _queryParameters; 1382 Map<String, String> _queryParameters;
1376 Map<String, List<String>> _queryParameterLists; 1383 Map<String, List<String>> _queryParameterLists;
1377 1384
1378 /// Internal non-verifying constructor. Only call with validated arguments. 1385 /// Internal non-verifying constructor. Only call with validated arguments.
1379 _Uri._internal(this.scheme, 1386 _Uri._internal(this.scheme,
1380 this._userInfo, 1387 this._userInfo,
1381 this._host, 1388 this._host,
1382 this._port, 1389 this._port,
(...skipping 1190 matching lines...) Expand 10 before | Expand all | Expand 10 after
2573 * Access the structure of a `data:` URI. 2580 * Access the structure of a `data:` URI.
2574 * 2581 *
2575 * Returns a [UriData] object for `data:` URIs and `null` for all other 2582 * Returns a [UriData] object for `data:` URIs and `null` for all other
2576 * URIs. 2583 * URIs.
2577 * The [UriData] object can be used to access the media type and data 2584 * The [UriData] object can be used to access the media type and data
2578 * of a `data:` URI. 2585 * of a `data:` URI.
2579 */ 2586 */
2580 UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null; 2587 UriData get data => (scheme == "data") ? new UriData.fromUri(this) : null;
2581 2588
2582 String toString() { 2589 String toString() {
2583 if (_text != null) return _text; 2590 return _text ??= _initializeText();
2591 }
2592
2593 String _initializeText() {
2594 assert(_text == null);
2584 StringBuffer sb = new StringBuffer(); 2595 StringBuffer sb = new StringBuffer();
2585 if (scheme.isNotEmpty) sb..write(scheme)..write(":"); 2596 if (scheme.isNotEmpty) sb..write(scheme)..write(":");
2586 if (hasAuthority || path.startsWith("//") || (scheme == "file")) { 2597 if (hasAuthority || path.startsWith("//") || (scheme == "file")) {
2587 // File URIS always have the authority, even if it is empty. 2598 // File URIS always have the authority, even if it is empty.
2588 // The empty URI means "localhost". 2599 // The empty URI means "localhost".
2589 sb.write("//"); 2600 sb.write("//");
2590 _writeAuthority(sb); 2601 _writeAuthority(sb);
2591 } 2602 }
2592 sb.write(path); 2603 sb.write(path);
2593 if (_query != null) sb..write("?")..write(_query); 2604 if (_query != null) sb..write("?")..write(_query);
2594 if (_fragment != null) sb..write("#")..write(_fragment); 2605 if (_fragment != null) sb..write("#")..write(_fragment);
2595 _text = sb.toString(); 2606 return sb.toString();
2596 return _text;
2597 } 2607 }
2598 2608
2599 bool operator==(other) { 2609 bool operator==(other) {
2600 if (identical(this, other)) return true; 2610 if (identical(this, other)) return true;
2601 if (other is Uri) { 2611 if (other is Uri) {
2602 Uri uri = other; 2612 Uri uri = other;
2603 return scheme == uri.scheme && 2613 return scheme == uri.scheme &&
2604 hasAuthority == uri.hasAuthority && 2614 hasAuthority == uri.hasAuthority &&
2605 userInfo == uri.userInfo && 2615 userInfo == uri.userInfo &&
2606 host == uri.host && 2616 host == uri.host &&
2607 port == uri.port && 2617 port == uri.port &&
2608 path == uri.path && 2618 path == uri.path &&
2609 hasQuery == uri.hasQuery && 2619 hasQuery == uri.hasQuery &&
2610 query == uri.query && 2620 query == uri.query &&
2611 hasFragment == uri.hasFragment && 2621 hasFragment == uri.hasFragment &&
2612 fragment == uri.fragment; 2622 fragment == uri.fragment;
2613 } 2623 }
2614 return false; 2624 return false;
2615 } 2625 }
2616 2626
2617 int get hashCode { 2627 int get hashCode {
2618 return (_text ?? toString()).hashCode; 2628 return _hashCodeCache ??= toString().hashCode;
2619 } 2629 }
2620 2630
2621 static List _createList() => []; 2631 static List _createList() => [];
2622 2632
2623 static Map _splitQueryStringAll( 2633 static Map _splitQueryStringAll(
2624 String query, {Encoding encoding: UTF8}) { 2634 String query, {Encoding encoding: UTF8}) {
2625 Map result = {}; 2635 Map result = {};
2626 int i = 0; 2636 int i = 0;
2627 int start = 0; 2637 int start = 0;
2628 int equalsIndex = -1; 2638 int equalsIndex = -1;
(...skipping 1366 matching lines...) Expand 10 before | Expand all | Expand 10 after
3995 final int _schemeEnd; 4005 final int _schemeEnd;
3996 final int _hostStart; 4006 final int _hostStart;
3997 final int _portStart; 4007 final int _portStart;
3998 final int _pathStart; 4008 final int _pathStart;
3999 final int _queryStart; 4009 final int _queryStart;
4000 final int _fragmentStart; 4010 final int _fragmentStart;
4001 /// The scheme is often used to distinguish URIs. 4011 /// The scheme is often used to distinguish URIs.
4002 /// To make comparisons more efficient, we cache the value, and 4012 /// To make comparisons more efficient, we cache the value, and
4003 /// canonicalize a few known types. 4013 /// canonicalize a few known types.
4004 String _schemeCache; 4014 String _schemeCache;
4015 int _hashCodeCache;
4005 4016
4006 _SimpleUri( 4017 _SimpleUri(
4007 this._uri, 4018 this._uri,
4008 this._schemeEnd, 4019 this._schemeEnd,
4009 this._hostStart, 4020 this._hostStart,
4010 this._portStart, 4021 this._portStart,
4011 this._pathStart, 4022 this._pathStart,
4012 this._queryStart, 4023 this._queryStart,
4013 this._fragmentStart, 4024 this._fragmentStart,
4014 this._schemeCache); 4025 this._schemeCache);
(...skipping 387 matching lines...) Expand 10 before | Expand all | Expand 10 after
4402 "with an authority"); 4413 "with an authority");
4403 } 4414 }
4404 return this.path; 4415 return this.path;
4405 } 4416 }
4406 4417
4407 UriData get data { 4418 UriData get data {
4408 assert(scheme != "data"); 4419 assert(scheme != "data");
4409 return null; 4420 return null;
4410 } 4421 }
4411 4422
4412 int get hashCode => _uri.hashCode; 4423 int get hashCode => _hashCodeCache ??= _uri.hashCode;
4413 4424
4414 bool operator==(Object other) { 4425 bool operator==(Object other) {
4415 if (identical(this, other)) return true; 4426 if (identical(this, other)) return true;
4416 if (other is Uri) return _uri == other.toString(); 4427 if (other is Uri) return _uri == other.toString();
4417 return false; 4428 return false;
4418 } 4429 }
4419 4430
4420 Uri _toNonSimple() { 4431 Uri _toNonSimple() {
4421 return new _Uri._internal( 4432 return new _Uri._internal(
4422 this.scheme, 4433 this.scheme,
(...skipping 22 matching lines...) Expand all
4445 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3; 4456 int delta = (text.codeUnitAt(start + 4) ^ _COLON) * 3;
4446 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/; 4457 delta |= text.codeUnitAt(start) ^ 0x64 /*d*/;
4447 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/; 4458 delta |= text.codeUnitAt(start + 1) ^ 0x61 /*a*/;
4448 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/; 4459 delta |= text.codeUnitAt(start + 2) ^ 0x74 /*t*/;
4449 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/; 4460 delta |= text.codeUnitAt(start + 3) ^ 0x61 /*a*/;
4450 return delta; 4461 return delta;
4451 } 4462 }
4452 4463
4453 /// Helper function returning the length of a string, or `0` for `null`. 4464 /// Helper function returning the length of a string, or `0` for `null`.
4454 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length; 4465 int _stringOrNullLength(String s) => (s == null) ? 0 : s.length;
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698