library eventsource.src.cache; import "package:collection/collection.dart"; import "event.dart"; //TODO use more efficient data structure than List class EventCache { final int cacheCapacity; final bool comparableIds; Map> _caches = new Map>(); EventCache({this.cacheCapacity, this.comparableIds: true}); void replay(Sink sink, String lastEventId, [String channel = ""]) { List cache = _caches[channel]; if (cache == null || cache.isEmpty) { // nothing to replay return; } // find the location of lastEventId in the queue int index; if (comparableIds) { // if comparableIds, we can use binary search index = binarySearch(cache, lastEventId); } else { // otherwise, we starts from the last one and look one by one index = cache.length - 1; while (index > 0 && cache[index].id != lastEventId) { index--; } } if (index >= 0) { // add them all to the sink cache.sublist(index).forEach(sink.add); } } /// Add a new [Event] to the cache(s) of the specified channel(s). /// Please note that we assume events are added with increasing values of /// [Event.id]. void add(Event event, [Iterable channels = const [""]]) { for (String channel in channels) { List cache = _caches.putIfAbsent(channel, () => new List()); if (cacheCapacity != null && cache.length >= cacheCapacity) { cache.removeAt(0); } cache.add(event); } } void clear([Iterable channels = const [""]]) { channels.forEach(_caches.remove); } void clearAll() { _caches.clear(); } }