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

Side by Side Diff: runtime/lib/compact_hash.dart

Issue 946893002: Ensure hash pattern is non-zero. Re-enable compact hash map/set. (Closed) Base URL: http://dart.googlecode.com/svn/branches/bleeding_edge/dart/
Patch Set: Created 5 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | runtime/lib/linked_hash_map.cc » ('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) 2015, the Dart project authors. Please see the AUTHORS file 1 // Copyright (c) 2015, 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 import 'dart:typed_data'; 5 import 'dart:typed_data';
6 6
7 // Hash table with open addressing that separates the index from keys/values. 7 // Hash table with open addressing that separates the index from keys/values.
8 abstract class _HashBase { 8 abstract class _HashBase {
9 // Each occupied entry in _index is a fixed-size integer that encodes a pair: 9 // Each occupied entry in _index is a fixed-size integer that encodes a pair:
10 // [ hash pattern for key | index of entry in _data ] 10 // [ hash pattern for key | index of entry in _data ]
(...skipping 14 matching lines...) Expand all
25 static const int _UNUSED_PAIR = 0; 25 static const int _UNUSED_PAIR = 0;
26 static const int _DELETED_PAIR = 1; 26 static const int _DELETED_PAIR = 1;
27 27
28 // Cached in-place mask for the hash pattern component. On 32-bit, the top 28 // Cached in-place mask for the hash pattern component. On 32-bit, the top
29 // bits are wasted to avoid Mint allocation. 29 // bits are wasted to avoid Mint allocation.
30 // TODO(koda): Reclaim the bits by making the compiler treat hash patterns 30 // TODO(koda): Reclaim the bits by making the compiler treat hash patterns
31 // as unsigned words. 31 // as unsigned words.
32 int _hashMask = int.is64Bit() ? 32 int _hashMask = int.is64Bit() ?
33 (1 << (32 - _INITIAL_INDEX_BITS)) - 1 : 33 (1 << (32 - _INITIAL_INDEX_BITS)) - 1 :
34 (1 << (30 - _INITIAL_INDEX_BITS)) - 1; 34 (1 << (30 - _INITIAL_INDEX_BITS)) - 1;
35 35
36 static int _hashPattern(int fullHash, int hashMask, int size) => 36 static int _hashPattern(int fullHash, int hashMask, int size) {
37 // TODO(koda): Consider keeping bit length and use left shift. 37 final int maskedHash = fullHash & hashMask;
38 (fullHash == 0) ? (size >> 1) : (fullHash & hashMask) * (size >> 1); 38 // TODO(koda): Consider keeping bit length and use left shift.
39 return (maskedHash == 0) ? (size >> 1) : maskedHash * (size >> 1);
40 }
39 41
40 // Linear probing. 42 // Linear probing.
41 static int _firstProbe(int fullHash, int sizeMask) { 43 static int _firstProbe(int fullHash, int sizeMask) {
42 final int i = fullHash & sizeMask; 44 final int i = fullHash & sizeMask;
43 // Light, fast shuffle to mitigate bad hashCode (e.g., sequential). 45 // Light, fast shuffle to mitigate bad hashCode (e.g., sequential).
44 return ((i << 1) + i) & sizeMask; 46 return ((i << 1) + i) & sizeMask;
45 } 47 }
46 static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask; 48 static int _nextProbe(int i, int sizeMask) => (i + 1) & sizeMask;
47 49
48 // Fixed-length list of keys (set) or key/value at even/odd indices (map). 50 // Fixed-length list of keys (set) or key/value at even/odd indices (map).
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
117 } 119 }
118 } 120 }
119 } 121 }
120 } 122 }
121 123
122 void _insert(K key, V value, int hashPattern, int i) { 124 void _insert(K key, V value, int hashPattern, int i) {
123 if (_usedData == _data.length) { 125 if (_usedData == _data.length) {
124 _rehash(); 126 _rehash();
125 this[key] = value; 127 this[key] = value;
126 } else { 128 } else {
127 assert(0 <= hashPattern && hashPattern < (1 << 32)); 129 assert(1 <= hashPattern && hashPattern < (1 << 32));
128 final int index = _usedData >> 1; 130 final int index = _usedData >> 1;
129 assert((index & hashPattern) == 0); 131 assert((index & hashPattern) == 0);
130 _index[i] = hashPattern | index; 132 _index[i] = hashPattern | index;
131 _data[_usedData++] = key; 133 _data[_usedData++] = key;
132 _data[_usedData++] = value; 134 _data[_usedData++] = value;
133 } 135 }
134 } 136 }
135 137
136 // If key is present, returns the index of the value in _data, else returns 138 // If key is present, returns the index of the value in _data, else returns
137 // the negated insertion point in _index. 139 // the negated insertion point in _index.
(...skipping 258 matching lines...) Expand 10 before | Expand all | Expand 10 after
396 } 398 }
397 } 399 }
398 i = _HashBase._nextProbe(i, sizeMask); 400 i = _HashBase._nextProbe(i, sizeMask);
399 pair = _index[i]; 401 pair = _index[i];
400 } 402 }
401 if (_usedData == _data.length) { 403 if (_usedData == _data.length) {
402 _rehash(); 404 _rehash();
403 add(key); 405 add(key);
404 } else { 406 } else {
405 final int insertionPoint = (firstDeleted >= 0) ? firstDeleted : i; 407 final int insertionPoint = (firstDeleted >= 0) ? firstDeleted : i;
406 assert(0 <= hashPattern && hashPattern < (1 << 32)); 408 assert(1 <= hashPattern && hashPattern < (1 << 32));
407 assert((hashPattern & _usedData) == 0); 409 assert((hashPattern & _usedData) == 0);
408 _index[insertionPoint] = hashPattern | _usedData; 410 _index[insertionPoint] = hashPattern | _usedData;
409 _data[_usedData++] = key; 411 _data[_usedData++] = key;
410 } 412 }
411 return true; 413 return true;
412 } 414 }
413 415
414 // If key is absent, return _data (which is never a value). 416 // If key is absent, return _data (which is never a value).
415 Object _getKeyOrData(Object key) { 417 Object _getKeyOrData(Object key) {
416 final int size = _index.length; 418 final int size = _index.length;
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after
462 pair = _index[i]; 464 pair = _index[i];
463 } 465 }
464 return false; 466 return false;
465 } 467 }
466 468
467 Iterator<K> get iterator => 469 Iterator<K> get iterator =>
468 new _CompactIterator<K>(this, _data, _usedData, -1, 1); 470 new _CompactIterator<K>(this, _data, _usedData, -1, 1);
469 471
470 Set<K> toSet() => new Set<K>()..addAll(this); 472 Set<K> toSet() => new Set<K>()..addAll(this);
471 } 473 }
OLDNEW
« no previous file with comments | « no previous file | runtime/lib/linked_hash_map.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698