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

Side by Side Diff: quiver/lib/src/collection/multimap.dart

Issue 1400473008: Roll Observatory packages and add a roll script (Closed) Base URL: git@github.com:dart-lang/observatory_pub_packages.git@master
Patch Set: Created 5 years, 2 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 | « quiver/lib/src/collection/lru_map.dart ('k') | quiver/lib/src/collection/treeset.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 // Copyright 2013 Google Inc. All Rights Reserved.
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 part of quiver.collection;
16
17 /**
18 * An associative container that maps a key to multiple values.
19 *
20 * Key lookups return mutable collections that are views of the multimap.
21 * Updates to the multimap are reflected in these collections and similarly,
22 * modifications to the returned collections are reflected in the multimap.
23 */
24 abstract class Multimap<K, V> {
25 /**
26 * Constructs a new list-backed multimap.
27 */
28 factory Multimap() => new ListMultimap<K, V>();
29
30 /**
31 * Returns whether this multimap contains the given [value].
32 */
33 bool containsValue(Object value);
34
35 /**
36 * Returns whether this multimap contains the given [key].
37 */
38 bool containsKey(Object key);
39
40 /**
41 * Returns the values for the given [key]. An empty iterable is returned if
42 * [key] is not mapped. The returned collection is a view on the multimap.
43 * Updates to the collection modify the multimap and likewise, modifications
44 * to the multimap are reflected in the returned collection.
45 */
46 Iterable<V> operator [](Object key);
47
48 /**
49 * Adds an association from the given key to the given value.
50 */
51 void add(K key, V value);
52
53 /**
54 * Adds an association from the given key to each of the given values.
55 */
56 void addValues(K key, Iterable<V> values);
57
58 /**
59 * Adds all associations of [other] to this multimap.
60 *
61 * The operation is equivalent to doing `this[key] = value` for each key
62 * and associated value in other. It iterates over [other], which must
63 * therefore not change during the iteration.
64 */
65 void addAll(Multimap<K, V> other);
66
67 /**
68 * Removes the association between the given [key] and [value]. Returns
69 * `true` if the association existed, `false` otherwise.
70 */
71 bool remove(Object key, V value);
72
73 /**
74 * Removes the association for the given [key]. Returns the collection of
75 * removed values, or an empty iterable if [key] was unmapped.
76 */
77 Iterable<V> removeAll(Object key);
78
79 /**
80 * Removes all data from the multimap.
81 */
82 void clear();
83
84 /**
85 * Applies [f] to each {key, Iterable<value>} pair of the multimap.
86 *
87 * It is an error to add or remove keys from the map during iteration.
88 */
89 void forEachKey(void f(K key, Iterable<V> value));
90
91 /**
92 * Applies [f] to each {key, value} pair of the multimap.
93 *
94 * It is an error to add or remove keys from the map during iteration.
95 */
96 void forEach(void f(K key, V value));
97
98 /**
99 * The keys of [this].
100 */
101 Iterable<K> get keys;
102
103 /**
104 * The values of [this].
105 */
106 Iterable<V> get values;
107
108 /**
109 * Returns a view of this multimap as a map.
110 */
111 Map<K, Iterable<V>> asMap();
112
113 /**
114 * Returns a view of this multimap as a map.
115 *
116 * DEPRECATED: this method is replaced with `asMap`.
117 */
118 @Deprecated('Will be removed in 0.22.0')
119 Map<K, Iterable<V>> toMap();
120
121 /**
122 * The number of keys in the multimap.
123 */
124 int get length;
125
126 /**
127 * Returns true if there is no key in the multimap.
128 */
129 bool get isEmpty;
130
131 /**
132 * Returns true if there is at least one key in the multimap.
133 */
134 bool get isNotEmpty;
135 }
136
137 /**
138 * Abstract base class for multimap implementations.
139 */
140 abstract class _BaseMultimap<K, V, C extends Iterable<V>>
141 implements Multimap<K, V> {
142 final Map<K, Iterable<V>> _map = new HashMap();
143
144 Iterable<V> _create();
145 void _add(C iterable, V value);
146 void _addAll(C iterable, Iterable<V> value);
147 void _clear(C iterable);
148 bool _remove(C iterable, Object value);
149 Iterable<V> _wrap(Object key, C iterable);
150
151 bool containsValue(Object value) => values.contains(value);
152 bool containsKey(Object key) => _map.keys.contains(key);
153
154 Iterable<V> operator [](Object key) {
155 var values = _map[key];
156 if (values == null) {
157 values = _create();
158 }
159 return _wrap(key, values);
160 }
161
162 void add(K key, V value) {
163 _map.putIfAbsent(key, _create);
164 _add(_map[key], value);
165 }
166
167 void addValues(K key, Iterable<V> values) {
168 _map.putIfAbsent(key, _create);
169 _addAll(_map[key], values);
170 }
171
172 /**
173 * Adds all associations of [other] to this multimap.
174 *
175 * The operation is equivalent to doing `this[key] = value` for each key
176 * and associated value in other. It iterates over [other], which must
177 * therefore not change during the iteration.
178 *
179 * This implementation iterates through each key of [other] and adds the
180 * associated values to this instance via [addValues].
181 */
182 void addAll(Multimap<K, V> other) => other.forEachKey(addValues);
183
184 bool remove(Object key, V value) {
185 if (!_map.containsKey(key)) return false;
186 bool removed = _remove(_map[key], value);
187 if (removed && _map[key].isEmpty) _map.remove(key);
188 return removed;
189 }
190
191 Iterable<V> removeAll(Object key) {
192 // Cast to dynamic to remove warnings
193 var values = _map.remove(key) as dynamic;
194 var retValues = _create() as dynamic;
195 if (values != null) {
196 retValues.addAll(values);
197 values.clear();
198 }
199 return retValues;
200 }
201
202 void clear() {
203 _map.forEach((K key, Iterable<V> value) => _clear(value));
204 _map.clear();
205 }
206
207 void forEachKey(void f(K key, Iterable<V> value)) => _map.forEach(f);
208
209 void forEach(void f(K key, V value)) {
210 _map.forEach((K key, Iterable<V> values) {
211 values.forEach((V value) => f(key, value));
212 });
213 }
214
215 Iterable<K> get keys => _map.keys;
216 Iterable<V> get values => _map.values.expand((x) => x);
217 Iterable<Iterable<V>> get _groupedValues => _map.values;
218 int get length => _map.length;
219 bool get isEmpty => _map.isEmpty;
220 bool get isNotEmpty => _map.isNotEmpty;
221 }
222
223 /**
224 * A multimap implementation that uses [List]s to store the values associated
225 * with each key.
226 */
227 class ListMultimap<K, V> extends _BaseMultimap<K, V, List<V>> {
228 ListMultimap() : super();
229 @override
230 List<V> _create() => new List<V>();
231 @override
232 void _add(List<V> iterable, V value) {
233 iterable.add(value);
234 }
235 @override
236 void _addAll(List<V> iterable, Iterable<V> value) => iterable.addAll(value);
237 @override
238 void _clear(List<V> iterable) => iterable.clear();
239 @override
240 bool _remove(List<V> iterable, Object value) => iterable.remove(value);
241 @override
242 List<V> _wrap(Object key, List<V> iterable) =>
243 new _WrappedList(_map, key, iterable);
244 List<V> operator [](Object key) => super[key];
245 List<V> removeAll(Object key) => super.removeAll(key);
246 Map<K, List<V>> asMap() => new _WrappedMap<K, V, List<V>>(this);
247 @Deprecated('Will be removed in 0.22.0')
248 Map<K, List<V>> toMap() => asMap();
249 }
250
251 /**
252 * A multimap implementation that uses [Set]s to store the values associated
253 * with each key.
254 */
255 class SetMultimap<K, V> extends _BaseMultimap<K, V, Set<V>> {
256 SetMultimap() : super();
257 @override
258 Set<V> _create() => new Set<V>();
259 @override
260 void _add(Set<V> iterable, V value) {
261 iterable.add(value);
262 }
263 @override
264 void _addAll(Set<V> iterable, Iterable<V> value) => iterable.addAll(value);
265 @override
266 void _clear(Set<V> iterable) => iterable.clear();
267 @override
268 bool _remove(Set<V> iterable, Object value) => iterable.remove(value);
269 @override
270 Set<V> _wrap(Object key, Iterable<V> iterable) =>
271 new _WrappedSet(_map, key, iterable);
272 Set<V> operator [](Object key) => super[key];
273 Set<V> removeAll(Object key) => super.removeAll(key);
274 Map<K, Set<V>> asMap() => new _WrappedMap<K, V, Set<V>>(this);
275 @Deprecated('Will be removed in 0.22.0')
276 Map<K, Set<V>> toMap() => asMap();
277 }
278
279 /**
280 * A [Map] that delegates its operations to an underlying multimap.
281 */
282 class _WrappedMap<K, V, C extends Iterable<V>> implements Map<K, C> {
283 final _BaseMultimap<K, V, C> _multimap;
284
285 _WrappedMap(this._multimap);
286
287 C operator [](Object key) => _multimap[key];
288
289 void operator []=(K key, C value) {
290 throw new UnsupportedError("Insert unsupported on map view");
291 }
292
293 void addAll(Map<K, C> other) {
294 throw new UnsupportedError("Insert unsupported on map view");
295 }
296
297 C putIfAbsent(K key, C ifAbsent()) {
298 throw new UnsupportedError("Insert unsupported on map view");
299 }
300
301 void clear() => _multimap.clear();
302 bool containsKey(Object key) => _multimap.containsKey(key);
303 bool containsValue(Object value) => _multimap.containsValue(value);
304 void forEach(void f(K key, C value)) => _multimap.forEachKey(f);
305 bool get isEmpty => _multimap.isEmpty;
306 bool get isNotEmpty => _multimap.isNotEmpty;
307 Iterable<K> get keys => _multimap.keys;
308 int get length => _multimap.length;
309 C remove(Object key) => _multimap.removeAll(key);
310 Iterable<C> get values => _multimap._groupedValues;
311 }
312
313 /**
314 * Iterable wrapper that syncs to an underlying map.
315 */
316 class _WrappedIterable<K, V, C extends Iterable<V>> implements Iterable<V> {
317 final K _key;
318 final Map<K, C> _map;
319 C _delegate;
320
321 _WrappedIterable(this._map, this._key, this._delegate);
322
323 _addToMap() => _map[_key] = _delegate;
324
325 /**
326 * Ensures we hold an up-to-date delegate. In the case where all mappings for
327 * _key are removed from the multimap, the Iterable referenced by _delegate is
328 * removed from the underlying map. At that point, any new addition via the
329 * multimap triggers the creation of a new Iterable, and the empty delegate
330 * we hold would be stale. As such, we check the underlying map and update
331 * our delegate when the one we hold is empty.
332 */
333 _syncDelegate() {
334 if (_delegate.isEmpty) {
335 var updated = _map[_key];
336 if (updated != null) {
337 _delegate = updated;
338 }
339 }
340 }
341
342 bool any(bool test(V element)) {
343 _syncDelegate();
344 return _delegate.any(test);
345 }
346
347 bool contains(Object element) {
348 _syncDelegate();
349 return _delegate.contains(element);
350 }
351
352 V elementAt(int index) {
353 _syncDelegate();
354 return _delegate.elementAt(index);
355 }
356
357 bool every(bool test(V element)) {
358 _syncDelegate();
359 return _delegate.every(test);
360 }
361
362 Iterable expand(Iterable f(V element)) {
363 _syncDelegate();
364 return _delegate.expand(f);
365 }
366
367 V get first {
368 _syncDelegate();
369 return _delegate.first;
370 }
371
372 V firstWhere(bool test(V element), {V orElse()}) {
373 _syncDelegate();
374 return _delegate.firstWhere(test, orElse: orElse);
375 }
376
377 fold(initialValue, combine(previousValue, V element)) {
378 _syncDelegate();
379 return _delegate.fold(initialValue, combine);
380 }
381
382 void forEach(void f(V element)) {
383 _syncDelegate();
384 _delegate.forEach(f);
385 }
386
387 bool get isEmpty {
388 _syncDelegate();
389 return _delegate.isEmpty;
390 }
391
392 bool get isNotEmpty {
393 _syncDelegate();
394 return _delegate.isNotEmpty;
395 }
396
397 Iterator<V> get iterator {
398 _syncDelegate();
399 return _delegate.iterator;
400 }
401
402 String join([String separator = ""]) {
403 _syncDelegate();
404 return _delegate.join(separator);
405 }
406
407 V get last {
408 _syncDelegate();
409 return _delegate.last;
410 }
411
412 V lastWhere(bool test(V element), {V orElse()}) {
413 _syncDelegate();
414 return _delegate.lastWhere(test, orElse: orElse);
415 }
416
417 int get length {
418 _syncDelegate();
419 return _delegate.length;
420 }
421
422 Iterable map(f(V element)) {
423 _syncDelegate();
424 return _delegate.map(f);
425 }
426
427 V reduce(V combine(V value, V element)) {
428 _syncDelegate();
429 return _delegate.reduce(combine);
430 }
431
432 V get single {
433 _syncDelegate();
434 return _delegate.single;
435 }
436
437 V singleWhere(bool test(V element)) {
438 _syncDelegate();
439 return _delegate.singleWhere(test);
440 }
441
442 Iterable<V> skip(int n) {
443 _syncDelegate();
444 return _delegate.skip(n);
445 }
446
447 Iterable<V> skipWhile(bool test(V value)) {
448 _syncDelegate();
449 return _delegate.skipWhile(test);
450 }
451
452 Iterable<V> take(int n) {
453 _syncDelegate();
454 return _delegate.take(n);
455 }
456
457 Iterable<V> takeWhile(bool test(V value)) {
458 _syncDelegate();
459 return _delegate.takeWhile(test);
460 }
461
462 List<V> toList({bool growable: true}) {
463 _syncDelegate();
464 return _delegate.toList(growable: growable);
465 }
466
467 Set<V> toSet() {
468 _syncDelegate();
469 return _delegate.toSet();
470 }
471
472 String toString() {
473 _syncDelegate();
474 return _delegate.toString();
475 }
476
477 Iterable<V> where(bool test(V element)) {
478 _syncDelegate();
479 return _delegate.where(test);
480 }
481 }
482
483 class _WrappedList<K, V> extends _WrappedIterable<K, V, List<V>>
484 implements List<V> {
485 _WrappedList(Map<K, List<V>> map, K key, List<V> delegate)
486 : super(map, key, delegate);
487
488 V operator [](int index) => elementAt(index);
489
490 void operator []=(int index, V value) {
491 _syncDelegate();
492 _delegate[index] = value;
493 }
494
495 void add(V value) {
496 _syncDelegate();
497 var wasEmpty = _delegate.isEmpty;
498 _delegate.add(value);
499 if (wasEmpty) _addToMap();
500 }
501
502 void addAll(Iterable<V> iterable) {
503 _syncDelegate();
504 var wasEmpty = _delegate.isEmpty;
505 _delegate.addAll(iterable);
506 if (wasEmpty) _addToMap();
507 }
508
509 Map<int, V> asMap() {
510 _syncDelegate();
511 return _delegate.asMap();
512 }
513
514 void clear() {
515 _syncDelegate();
516 _delegate.clear();
517 _map.remove(_key);
518 }
519
520 void fillRange(int start, int end, [V fillValue]) {
521 _syncDelegate();
522 _delegate.fillRange(start, end, fillValue);
523 }
524
525 Iterable<V> getRange(int start, int end) {
526 _syncDelegate();
527 return _delegate.getRange(start, end);
528 }
529
530 int indexOf(V element, [int start = 0]) {
531 _syncDelegate();
532 return _delegate.indexOf(element, start);
533 }
534
535 void insert(int index, V element) {
536 _syncDelegate();
537 var wasEmpty = _delegate.isEmpty;
538 _delegate.insert(index, element);
539 if (wasEmpty) _addToMap();
540 }
541
542 void insertAll(int index, Iterable<V> iterable) {
543 _syncDelegate();
544 var wasEmpty = _delegate.isEmpty;
545 _delegate.insertAll(index, iterable);
546 if (wasEmpty) _addToMap();
547 }
548
549 int lastIndexOf(V element, [int start]) {
550 _syncDelegate();
551 return _delegate.lastIndexOf(element, start);
552 }
553
554 void set length(int newLength) {
555 _syncDelegate();
556 var wasEmpty = _delegate.isEmpty;
557 _delegate.length = newLength;
558 if (wasEmpty) _addToMap();
559 }
560
561 bool remove(Object value) {
562 _syncDelegate();
563 bool removed = _delegate.remove(value);
564 if (_delegate.isEmpty) _map.remove(_key);
565 return removed;
566 }
567
568 V removeAt(int index) {
569 _syncDelegate();
570 V removed = _delegate.removeAt(index);
571 if (_delegate.isEmpty) _map.remove(_key);
572 return removed;
573 }
574
575 V removeLast() {
576 _syncDelegate();
577 V removed = _delegate.removeLast();
578 if (_delegate.isEmpty) _map.remove(_key);
579 return removed;
580 }
581
582 void removeRange(int start, int end) {
583 _syncDelegate();
584 _delegate.removeRange(start, end);
585 if (_delegate.isEmpty) _map.remove(_key);
586 }
587
588 void removeWhere(bool test(V element)) {
589 _syncDelegate();
590 _delegate.removeWhere(test);
591 if (_delegate.isEmpty) _map.remove(_key);
592 }
593
594 void replaceRange(int start, int end, Iterable<V> iterable) {
595 _syncDelegate();
596 _delegate.replaceRange(start, end, iterable);
597 if (_delegate.isEmpty) _map.remove(_key);
598 }
599
600 void retainWhere(bool test(V element)) {
601 _syncDelegate();
602 _delegate.retainWhere(test);
603 if (_delegate.isEmpty) _map.remove(_key);
604 }
605
606 Iterable<V> get reversed {
607 _syncDelegate();
608 return _delegate.reversed;
609 }
610
611 void setAll(int index, Iterable<V> iterable) {
612 _syncDelegate();
613 _delegate.setAll(index, iterable);
614 }
615
616 void setRange(int start, int end, Iterable<V> iterable, [int skipCount = 0]) {
617 _syncDelegate();
618 }
619
620 void shuffle([Random random]) {
621 _syncDelegate();
622 _delegate.shuffle(random);
623 }
624
625 void sort([int compare(V a, V b)]) {
626 _syncDelegate();
627 _delegate.sort(compare);
628 }
629
630 List<V> sublist(int start, [int end]) {
631 _syncDelegate();
632 return _delegate.sublist(start, end);
633 }
634 }
635
636 class _WrappedSet<K, V> extends _WrappedIterable<K, V, Set<V>>
637 implements Set<V> {
638 _WrappedSet(Map<K, Iterable<V>> map, K key, Iterable<V> delegate)
639 : super(map, key, delegate);
640
641 bool add(V value) {
642 _syncDelegate();
643 var wasEmpty = _delegate.isEmpty;
644 bool wasAdded = _delegate.add(value);
645 if (wasEmpty) _addToMap();
646 return wasAdded;
647 }
648
649 void addAll(Iterable<V> elements) {
650 _syncDelegate();
651 var wasEmpty = _delegate.isEmpty;
652 _delegate.addAll(elements);
653 if (wasEmpty) _addToMap();
654 }
655
656 void clear() {
657 _syncDelegate();
658 _delegate.clear();
659 _map.remove(_key);
660 }
661
662 bool containsAll(Iterable<Object> other) {
663 _syncDelegate();
664 return _delegate.containsAll(other);
665 }
666
667 Set<V> difference(Set<V> other) {
668 _syncDelegate();
669 return _delegate.difference(other);
670 }
671
672 Set<V> intersection(Set<Object> other) {
673 _syncDelegate();
674 return _delegate.intersection(other);
675 }
676
677 V lookup(Object object) {
678 _syncDelegate();
679 return _delegate.lookup(object);
680 }
681
682 bool remove(Object value) {
683 _syncDelegate();
684 bool removed = _delegate.remove(value);
685 if (_delegate.isEmpty) _map.remove(_key);
686 return removed;
687 }
688
689 void removeAll(Iterable<Object> elements) {
690 _syncDelegate();
691 _delegate.removeAll(elements);
692 if (_delegate.isEmpty) _map.remove(_key);
693 }
694
695 void removeWhere(bool test(V element)) {
696 _syncDelegate();
697 _delegate.removeWhere(test);
698 if (_delegate.isEmpty) _map.remove(_key);
699 }
700
701 void retainAll(Iterable<Object> elements) {
702 _syncDelegate();
703 _delegate.retainAll(elements);
704 if (_delegate.isEmpty) _map.remove(_key);
705 }
706
707 void retainWhere(bool test(V element)) {
708 _syncDelegate();
709 _delegate.retainWhere(test);
710 if (_delegate.isEmpty) _map.remove(_key);
711 }
712
713 Set<V> union(Set<V> other) {
714 _syncDelegate();
715 return _delegate.union(other);
716 }
717 }
OLDNEW
« no previous file with comments | « quiver/lib/src/collection/lru_map.dart ('k') | quiver/lib/src/collection/treeset.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698