import 'dart:collection'; class FixedList { final int maxLength; final List _list; FixedList(this.maxLength, {List? list}) : _list = list ?? []; add(T item) { if (_list.length == maxLength) { _list.removeAt(0); } _list.add(item); } clear() { _list.clear(); } List get list => List.unmodifiable(_list); int get length => _list.length; T operator [](int index) => _list[index]; FixedList copyWith() { return FixedList( maxLength, list: _list, ); } } class FixedMap { int maxSize; final Map _map = {}; final Queue _queue = Queue(); FixedMap(this.maxSize); put(K key, V value) { if (_map.length == maxSize) { final oldestKey = _queue.removeFirst(); _map.remove(oldestKey); } _map[key] = value; _queue.add(key); return value; } clear() { _map.clear(); _queue.clear(); } updateMaxSize(int size){ maxSize = size; } V? get(K key) => _map[key]; bool containsKey(K key) => _map.containsKey(key); int get length => _map.length; Map get map => Map.unmodifiable(_map); } extension ListExtension on List { List intersection(List list) { return where((item) => list.contains(item)).toList(); } List> batch(int maxConcurrent) { final batches = (length / maxConcurrent).ceil(); final List> res = []; for (int i = 0; i < batches; i++) { if (i != batches - 1) { res.add(sublist(i * maxConcurrent, maxConcurrent * (i + 1))); } else { res.add(sublist(i * maxConcurrent, length)); } } return res; } List safeSublist(int start) { if (start <= 0) return this; if (start > length) return []; return sublist(start); } }