OLD | NEW |
---|---|
(Empty) | |
1 // Copyright (c) 2014, the Dart project authors. Please see the AUTHORS file | |
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. | |
4 | |
5 // VM-internalized implementation of a default-constructed LinkedHashMap. | |
6 // Currently calls the runtime for most operations. | |
7 class _InternalLinkedHashMap<K, V> implements HashMap<K, V>, | |
8 LinkedHashMap<K, V> { | |
9 factory _InternalLinkedHashMap() native "LinkedHashMap_allocate"; | |
10 int get length native "LinkedHashMap_getLength"; | |
11 V operator [](K key) native "LinkedHashMap_lookUp"; | |
12 void operator []=(K key, V value) native "LinkedHashMap_insertOrUpdate"; | |
13 V remove(K key) native "LinkedHashMap_remove"; | |
14 void clear() native "LinkedHashMap_clear"; | |
15 bool containsKey(K key) native "LinkedHashMap_containsKey"; | |
16 | |
17 bool get isEmpty => length == 0; | |
18 bool get isNotEmpty => !isEmpty; | |
19 | |
20 List _toArray() native "LinkedHashMap_toArray"; | |
siva
2014/07/23 22:43:06
blank line here for spacing?
koda
2014/07/24 19:31:44
Done.
| |
21 // The "modificaton mark" is used to detect concurrent modification. | |
22 // Any modification to the map clears the mark, and iterators' moveNext | |
23 // check whether the mark has changed. | |
24 // TODO(koda): Consider a counter instead. | |
25 Object _getModMark(bool create) native "LinkedHashMap_getModMark"; | |
26 | |
27 void addAll(Map<K, V> other) { | |
28 other.forEach((K key, V value) { | |
29 this[key] = value; | |
30 }); | |
31 } | |
32 | |
33 V putIfAbsent(K key, Function ifAbsent) { | |
34 if (containsKey(key)) { | |
35 return this[key]; | |
36 } else { | |
37 V value = ifAbsent(); | |
38 this[key] = value; | |
39 return value; | |
40 } | |
41 } | |
42 | |
43 bool containsValue(V value) { | |
44 for (V v in values) { | |
45 if (v == value) { | |
46 return true; | |
47 } | |
48 } | |
49 return false; | |
50 } | |
51 | |
52 void forEach(Function f) { | |
53 for (K key in keys) { | |
54 f(key, this[key]); | |
55 } | |
56 } | |
57 | |
58 // The even-indexed entries of toArray are the keys. | |
59 Iterable<K> get keys => | |
60 new _ListStepIterable<K>(this, _getModMark(true), _toArray(), -2, 2); | |
61 | |
62 // The even-indexed entries of toArray are the values. | |
siva
2014/07/23 22:43:06
Comment states both key and values are even-indexe
koda
2014/07/24 19:31:44
Done.
| |
63 Iterable<V> get values => | |
64 new _ListStepIterable<V>(this, _getModMark(true), _toArray(), -1, 2); | |
65 | |
66 String toString() => Maps.mapToString(this); | |
67 } | |
68 | |
69 // Iterates over a list from a given offset and step size. | |
70 class _ListStepIterable<E> extends IterableBase<E> { | |
71 _InternalLinkedHashMap _map; | |
72 Object _modMark; | |
73 List _list; | |
74 int _offset; | |
75 int _step; | |
76 | |
77 _ListStepIterable(this._map, this._modMark, | |
78 this._list, this._offset, this._step); | |
79 | |
80 Iterator<E> get iterator => | |
81 new _ListStepIterator(_map, _modMark, _list, _offset, _step); | |
82 | |
83 // TODO(koda): Should this check for concurrent modification? | |
84 int get length => _map.length; | |
85 bool get isEmpty => length == 0; | |
86 bool get isNotEmpty => !isEmpty; | |
87 } | |
88 | |
89 class _ListStepIterator<E> implements Iterator<E> { | |
90 _InternalLinkedHashMap _map; | |
91 Object _modMark; | |
92 List _list; | |
93 int _offset; | |
94 int _step; | |
95 | |
96 _ListStepIterator(this._map, this._modMark, | |
97 this._list, this._offset, this._step); | |
98 | |
99 bool moveNext() { | |
100 if (_map._getModMark(false) != _modMark) { | |
101 throw new ConcurrentModificationError(_map); | |
102 } | |
103 _offset += _step; | |
104 return _offset < _list.length; | |
105 } | |
106 | |
107 E get current { | |
108 if (_offset < 0 || _offset >= _list.length) { | |
109 return null; | |
110 } | |
111 return _list[_offset]; | |
112 } | |
113 } | |
114 | |
OLD | NEW |