Esempio n. 1
0
 public bool IsStreamDeleted(TStreamId streamId) => _readIndex.IsStreamDeleted(streamId);
Esempio n. 2
0
        private void ScavengeChunk(TFChunk oldChunk)
        {
            var sw = Stopwatch.StartNew();

            var chunkNumber        = oldChunk.ChunkHeader.ChunkStartNumber;
            var newScavengeVersion = oldChunk.ChunkHeader.ChunkScavengeVersion + 1;
            var chunkSize          = oldChunk.ChunkHeader.ChunkSize;

            var tmpChunkPath = Path.Combine(_db.Config.Path, Guid.NewGuid() + ".scavenge.tmp");
            var newChunkPath = _db.Config.FileNamingStrategy.GetFilenameFor(chunkNumber, newScavengeVersion);

            Log.Trace("Scavenging chunk #{0} ({1}) started. Scavenged chunk: {2} --> {3}.",
                      chunkNumber,
                      Path.GetFileName(oldChunk.FileName),
                      Path.GetFileName(tmpChunkPath),
                      Path.GetFileName(newChunkPath));

            TFChunk newChunk;

            try
            {
                newChunk = TFChunk.CreateNew(tmpChunkPath, chunkSize, chunkNumber, newScavengeVersion);
            }
            catch (IOException exc)
            {
                Log.ErrorException(exc, "IOException during creating new chunk for scavenging purposes. Ignoring...");
                return;
            }

            var positionMapping   = new List <PosMap>();
            var positioningNeeded = false;
            var result            = oldChunk.TryReadFirst();
            int cnt = 0;

            while (result.Success)
            {
                cnt += 1;
                var record = result.LogRecord;
                switch (record.RecordType)
                {
                case LogRecordType.Prepare:
                {
                    var prepare = (PrepareLogRecord)record;

                    if (!_readIndex.IsStreamDeleted(prepare.EventStreamId) ||
                        (prepare.Flags & PrepareFlags.StreamDelete) != 0)        // delete tombstone should be left
                    {
                        var posMap = WriteRecord(newChunk, record);
                        positionMapping.Add(posMap);
                        positioningNeeded = posMap.LogPos != posMap.ActualPos;
                    }
                    break;
                }

                case LogRecordType.Commit:
                {
                    var posMap = WriteRecord(newChunk, record);
                    positionMapping.Add(posMap);
                    positioningNeeded = posMap.LogPos != posMap.ActualPos;
                    break;
                }

                default:
                    throw new ArgumentOutOfRangeException();
                }
                if (result.NextPosition == -1)
                {
                    break;
                }
                result = oldChunk.TryReadSameOrClosest((int)result.NextPosition);
            }

            var oldSize = oldChunk.ChunkFooter.ActualChunkSize + oldChunk.ChunkFooter.MapSize + ChunkHeader.Size + ChunkFooter.Size;
            var newSize = newChunk.ActualDataSize
                          + (positioningNeeded ? sizeof(ulong) * positionMapping.Count : 0)
                          + ChunkHeader.Size
                          + ChunkFooter.Size;

            if (false && oldSize <= newSize)
            {
                Log.Trace("Scavenging of chunk #{0} ({1}) completed in {2}.\n"
                          + "Old version is kept as it is smaller.\n"
                          + "Old chunk size: {3}, scavenged size: {4}.\n"
                          + "Scavenged chunk removed.",
                          chunkNumber,
                          oldChunk.FileName,
                          sw.Elapsed,
                          oldSize,
                          newSize);

                newChunk.Dispose();
                File.Delete(newChunk.FileName);
            }
            else
            {
                newChunk.CompleteScavenge(positioningNeeded ? positionMapping : null);
                newChunk.Dispose();

                File.Move(tmpChunkPath, newChunkPath);

                newChunk = TFChunk.FromCompletedFile(newChunkPath);
                var removedChunk = _db.Manager.SwapChunk(chunkNumber, newChunk);
                Debug.Assert(ReferenceEquals(removedChunk, oldChunk)); // only scavenging could switch, so old should be always same
                oldChunk.MarkForDeletion();

                Log.Trace("Scavenging of chunk #{0} ({1}) completed in {2} into ({3} --> {4}).\n"
                          + "Old size: {5}, new size: {6}, new scavenge version: {7}.",
                          chunkNumber,
                          Path.GetFileName(oldChunk.FileName),
                          sw.Elapsed,
                          Path.GetFileName(tmpChunkPath),
                          Path.GetFileName(newChunkPath),
                          oldSize,
                          newSize,
                          newScavengeVersion);
            }
        }
Esempio n. 3
0
        public static bool IsStreamDeleted <TStreamId>(this IReadIndex <TStreamId> self, string streamName)
        {
            var streamId = self.GetStreamId(streamName);

            return(self.IsStreamDeleted(streamId));
        }