public void Compact() { var newPositions = new Dictionary <string, StreamInformation>(StringComparer.InvariantCultureIgnoreCase); var newFilePath = dataPath + ".compacting"; streamSource.DeleteIfExists(newFilePath); using (var newFile = streamSource.OpenReadWrite(newFilePath)) using (var newWriter = new BinaryWriter(newFile)) using (var current = streamSource.OpenRead(dataPath)) using (var reader = new BinaryReader(current)) { while (true) { PersistedEvent persistedEvent; try { persistedEvent = ReadPersistedEvent(reader); } catch (EndOfStreamException) { break; } StreamInformation value; if (idToPos.TryGetValue(persistedEvent.Id, out value) == false) { continue; } if (value.LastPosition == Deleted || value.LastPosition == DoesNotExists) { continue; } StreamInformation information; if (newPositions.TryGetValue(persistedEvent.Id, out information) == false) { information = new StreamInformation { LastPosition = DoesNotExists, StreamLength = 0 }; } persistedEvent.Previous = information.LastPosition; newPositions[persistedEvent.Id] = new StreamInformation { LastPosition = newFile.Position, StreamLength = persistedEvent.StreamLength }; WriteItem(persistedEvent, newWriter); } streamSource.Flush(newFile); compactionLock.EnterWriteLock(); try { newFile.Close(); streamSource.DeleteOnClose(dataPath); Stream result; while (cachedReadStreams.TryDequeue(out result)) { result.Dispose(); } binaryWriter.Dispose(); file.Dispose(); streamSource.RenameToLatest(newFilePath, dataPath); file = streamSource.OpenReadWrite(dataPath); binaryWriter = new BinaryWriter(file, Encoding.UTF8, leaveOpen: true); streamSource.DeleteIfExists("data.offsets"); FlushOffsets(); idToPos.Clear(); foreach (var val in newPositions) { idToPos[val.Key] = val.Value; } } finally { compactionLock.ExitWriteLock(); } } }