blob: f9e4c5e7056bb35324a32474c3675e9552bf48a0 [file] [log] [blame]
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
// All rights reserved. Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
typedef _MapFactory<K, V> = Map<K, V> Function();
class CopyOnWriteMap<K, V> implements Map<K, V> {
final _MapFactory<K, V>? _mapFactory;
bool _copyBeforeWrite;
Map<K, V> _map;
CopyOnWriteMap(this._map, [this._mapFactory]) : _copyBeforeWrite = true;
// Read-only methods: just forward.
@override
V? operator [](Object? key) => _map[key];
@override
Map<K2, V2> cast<K2, V2>() => CopyOnWriteMap<K2, V2>(_map.cast<K2, V2>());
@override
bool containsKey(Object? key) => _map.containsKey(key);
@override
bool containsValue(Object? value) => _map.containsValue(value);
@override
Iterable<MapEntry<K, V>> get entries => _map.entries;
@override
void forEach(void Function(K, V) f) => _map.forEach(f);
@override
bool get isEmpty => _map.isEmpty;
@override
bool get isNotEmpty => _map.isNotEmpty;
@override
Iterable<K> get keys => _map.keys;
@override
int get length => _map.length;
@override
Map<K2, V2> map<K2, V2>(MapEntry<K2, V2> Function(K, V) f) => _map.map(f);
@override
Iterable<V> get values => _map.values;
// Mutating methods: copy first if needed.
@override
void operator []=(K key, V value) {
_maybeCopyBeforeWrite();
_map[key] = value;
}
@override
void addAll(Map<K, V> other) {
_maybeCopyBeforeWrite();
_map.addAll(other);
}
@override
void addEntries(Iterable<MapEntry<K, V>> entries) {
_maybeCopyBeforeWrite();
_map.addEntries(entries);
}
@override
void clear() {
_maybeCopyBeforeWrite();
_map.clear();
}
@override
V putIfAbsent(K key, V Function() ifAbsent) {
_maybeCopyBeforeWrite();
return _map.putIfAbsent(key, ifAbsent);
}
@override
V? remove(Object? key) {
_maybeCopyBeforeWrite();
return _map.remove(key);
}
@override
void removeWhere(bool Function(K, V) test) {
_maybeCopyBeforeWrite();
_map.removeWhere(test);
}
@override
String toString() => _map.toString();
@override
V update(K key, V Function(V) update, {V Function()? ifAbsent}) {
_maybeCopyBeforeWrite();
return _map.update(key, update, ifAbsent: ifAbsent);
}
@override
void updateAll(V Function(K, V) update) {
_maybeCopyBeforeWrite();
_map.updateAll(update);
}
// Internal.
void _maybeCopyBeforeWrite() {
if (!_copyBeforeWrite) return;
_copyBeforeWrite = false;
_map = _mapFactory != null
? (_mapFactory!()..addAll(_map))
: Map<K, V>.from(_map);
}
}