Ejemplo n.º 1
0
        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();
                            }
                        }
        }