<commit_before>namespace EventStore
{
	using System;
	using System.Collections.Generic;
	using System.Linq;
	using Dispatcher;
	using Persistence;

	public class OptimisticEventStore : IStoreEvents
	{
		private readonly CommitTracker tracker = new CommitTracker();
		private readonly IPersistStreams persistence;
		private readonly IDispatchCommits dispatcher;

		public OptimisticEventStore(IPersistStreams persistence, IDispatchCommits dispatcher)
		{
			this.persistence = persistence;
			this.dispatcher = dispatcher;
		}

		public virtual CommittedEventStream ReadFromSnapshotUntil(Guid streamId, int maxRevision)
		{
			maxRevision = maxRevision > 0 ? maxRevision : int.MaxValue;
			return this.Read(this.persistence.GetFromSnapshotUntil(streamId, maxRevision), true);
		}
		public virtual CommittedEventStream ReadFrom(Guid streamId, int minRevision)
		{
			return this.Read(this.persistence.GetFrom(streamId, minRevision), false);
		}
		protected virtual CommittedEventStream Read(IEnumerable<Commit> commits, bool applySnapshot)
		{
			var streamId = Guid.Empty;
			var sequence = 0;
			var revision = 0;
			object snapshot = null;
			ICollection<object> events = new LinkedList<object>();
			ICollection<Guid> commitIdentifiers = new HashSet<Guid>();

			foreach (var commit in commits ?? new Commit[0])
			{
				streamId = commit.StreamId;
				sequence = commit.CommitSequence;
				revision = commit.StreamRevision;

				snapshot = commit.Snapshot ?? snapshot;
				events.AddEventsOrClearOnSnapshot(commit, applySnapshot);
				commitIdentifiers.Add(commit.CommitId);

				this.tracker.Track(commit);
			}

			snapshot = applySnapshot ? snapshot : null;
			return new CommittedEventStream(
				streamId, revision, sequence, events.ToArray(), commitIdentifiers, snapshot);
		}

		public virtual void Write(CommitAttempt attempt)
		{
			if (!attempt.IsValid() || attempt.IsEmpty())
				return;

			this.ThrowOnDuplicateOrConcurrentWrites(attempt);
			this.PersistAndDispatch(attempt);
		}
		protected virtual void ThrowOnDuplicateOrConcurrentWrites(CommitAttempt current)
		{
			if (this.tracker.Contains(current))
				throw new DuplicateCommitException();

			var previous = this.tracker.GetStreamHead(current.StreamId);
			if (previous == null)
				return;

			if (previous.CommitSequence > current.PreviousCommitSequence)
				throw new ConcurrencyException();<commit_msg>Reordered operations during building of the stream to ensure tracking of most recent commits occurs first.<commit_after>namespace EventStore
{
	using System;
	using System.Collections.Generic;
	using Dispatcher;
	using Persistence;

	public class OptimisticEventStore : IStoreEvents
	{
		private readonly CommitTracker tracker = new CommitTracker();
		private readonly IPersistStreams persistence;
		private readonly IDispatchCommits dispatcher;

		public OptimisticEventStore(IPersistStreams persistence, IDispatchCommits dispatcher)
		{
			this.persistence = persistence;
			this.dispatcher = dispatcher;
		}

		public virtual CommittedEventStream ReadFromSnapshotUntil(Guid streamId, int maxRevision)
		{
			maxRevision = maxRevision > 0 ? maxRevision : int.MaxValue;
			return this.Read(this.persistence.GetFromSnapshotUntil(streamId, maxRevision), true);
		}
		public virtual CommittedEventStream ReadFrom(Guid streamId, int minRevision)
		{
			return this.Read(this.persistence.GetFrom(streamId, minRevision), false);
		}
		protected virtual CommittedEventStream Read(IEnumerable<Commit> commits, bool applySnapshot)
		{
			var streamId = Guid.Empty;
			var revision = 0;
			var sequence = 0;
			object snapshot = null;
			ICollection<object> events = new LinkedList<object>();
			ICollection<Guid> commitIdentifiers = new HashSet<Guid>();

			foreach (var commit in commits ?? new Commit[0])
			{
				this.tracker.Track(commit);
				commitIdentifiers.Add(commit.CommitId);

				streamId = commit.StreamId;
				revision = commit.StreamRevision;
				sequence = commit.CommitSequence;
				snapshot = commit.Snapshot ?? snapshot;

				events.AddEventsOrClearOnSnapshot(commit, applySnapshot);
			}

			snapshot = applySnapshot ? snapshot : null;
			return new CommittedEventStream(streamId, revision, sequence, events, commitIdentifiers, snapshot);
		}

		public virtual void Write(CommitAttempt attempt)
		{
			if (!attempt.IsValid() || attempt.IsEmpty())
				return;

			this.ThrowOnDuplicateOrConcurrentWrites(attempt);
			this.PersistAndDispatch(attempt);
		}
		protected virtual void ThrowOnDuplicateOrConcurrentWrites(CommitAttempt current)
		{
			if (this.tracker.Contains(current))
				throw new DuplicateCommitException();

			var previous = this.tracker.GetStreamHead(current.StreamId);
			if (previous == null)
				return;

			if (previous.CommitSequence > current.PreviousCommitSequence)
				throw new ConcurrencyException();
{'fraction_non_alphanumeric': 0.08502695976773122, 'fraction_numerical': 0.0016590626296142678, 'mean_word_length': 4.831922611850061, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 17, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3742099', 'n_tokens_mistral': 1571, 'n_tokens_neox': 1333, 'n_words': 331}