public IEnumerable <object> Read(params Type[] eventTypes) { var typeReaders = CreateTypeReaders(eventTypes.ToDictionary(t => t, t => (Action <object>)(_ => { }))); var relevantTypeReaders = new ReaderProgressSinglyLinkedList(typeReaders); var nextReader = relevantTypeReaders.First; var subsequentReader = nextReader.Next; while (true) { // Use first reader, unless a subsequent reader in priority queue has an older message. if (subsequentReader != null && nextReader.NextSequenceId > subsequentReader.NextSequenceId) { // Scan until we can find new insert point relevantTypeReaders.RemoveFirst(); var node = subsequentReader; while (true) { if (node.Next == null) { relevantTypeReaders.AddAfter(node, nextReader); break; } if (nextReader.NextSequenceId < node.Next.NextSequenceId) { relevantTypeReaders.AddAfter(node, nextReader); break; } node = node.Next; } // Get next nextReader = relevantTypeReaders.First; subsequentReader = nextReader.Next; } var instance = nextReader.Reader.ReadPooled(); yield return(instance); var nextSeqId = nextReader.Reader.ReadNextSequenceId(); if (nextSeqId == null) { relevantTypeReaders.RemoveFirst(); if (relevantTypeReaders.First == null) { break; } nextReader = relevantTypeReaders.First; subsequentReader = nextReader.Next; } else { nextReader.NextSequenceId = nextSeqId.Value; } } foreach (var type in typeReaders) { type?.Dispose(); } }
public void Invoke(Dictionary <Type, Action <object> > handlers) { var typeReaders = CreateTypeReaders(handlers); var relevantTypeReaders = new ReaderProgressSinglyLinkedList(typeReaders); var nextReader = relevantTypeReaders.First; var subsequentReader = nextReader.Next; while (true) { // Use first reader, unless a subsequent reader in priority queue has an older message. if (subsequentReader != null && nextReader.NextSequenceId > subsequentReader.NextSequenceId) { // Scan until we can find new insert point relevantTypeReaders.RemoveFirst(); var node = subsequentReader; while (true) { if (node.Next == null) { relevantTypeReaders.AddAfter(node, nextReader); break; } if (nextReader.NextSequenceId < node.Next.NextSequenceId) { relevantTypeReaders.AddAfter(node, nextReader); break; } node = node.Next; } // Get next nextReader = relevantTypeReaders.First; subsequentReader = nextReader.Next; } var handler = nextReader.Reader.Handler; var instance = nextReader.Reader.ReadPooled(); handler(instance); var nextSeqId = nextReader.Reader.ReadNextSequenceId(); if (nextSeqId == null) { relevantTypeReaders.RemoveFirst(); if (relevantTypeReaders.First == null) { break; } nextReader = relevantTypeReaders.First; subsequentReader = nextReader.Next; } else { nextReader.NextSequenceId = nextSeqId.Value; } } foreach (var type in typeReaders) { type?.Dispose(); } }