// Copyright 2017 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. import 'dart:collection'; /// A list optimized for containment queries. /// /// Consider using an [ObserverList] instead of a [List] when the number of /// [contains] calls dominates the number of [add] and [remove] calls. // TODO(ianh): Use DelegatingIterable, possibly moving it from the collection // package to foundation, or to dart:collection. class ObserverList<T> extends Iterable<T> { final List<T> _list = <T>[]; bool _isDirty = false; HashSet<T> _set; /// Adds an item to the end of this list. void add(T item) { _isDirty = true; _list.add(item); } /// Removes an item from the list. /// /// This is O(N) in the number of items in the list. /// /// Returns whether the item was present in the list. bool remove(T item) { _isDirty = true; return _list.remove(item); } @override bool contains(Object element) { if (_list.length < 3) return _list.contains(element); if (_isDirty) { if (_set == null) { _set = new HashSet<T>.from(_list); } else { _set.clear(); _set.addAll(_list); } _isDirty = false; } return _set.contains(element); } @override Iterator<T> get iterator => _list.iterator; @override bool get isEmpty => _list.isEmpty; @override bool get isNotEmpty => _list.isNotEmpty; }