Esempio n. 1
0
        void CompactOnePureValueFileIteration(ref StructList <uint> toRemoveFileIds)
        {
            _cancellation.ThrowIfCancellationRequested();
            _writerBytesPerSecondLimiter = new BytesPerSecondLimiter(_keyValueDB.CompactorWriteBytesPerSecondLimit);
            var writer         = _keyValueDB.StartPureValuesFile(out var valueFileId);
            var firstIteration = true;

            while (true)
            {
                var wastefulFileId =
                    FindMostWastefulFile(firstIteration
                        ? uint.MaxValue
                        : _keyValueDB.MaxTrLogFileSize - writer.GetCurrentPositionWithoutWriter());
                firstIteration = false;
                if (wastefulFileId == 0)
                {
                    break;
                }
                MoveValuesContent(writer, wastefulFileId, valueFileId);
                if (_fileStats.GetOrFakeValueRef(wastefulFileId).IsFreeToDelete())
                {
                    toRemoveFileIds.Add(wastefulFileId);
                }
                _fileStats.GetOrFakeValueRef(wastefulFileId) = new FileStat(0);
            }

            var valueFile = _keyValueDB.FileCollection.GetFile(valueFileId);

            valueFile !.HardFlushTruncateSwitchToReadOnlyMode();
            _keyValueDB.Logger?.CompactionCreatedPureValueFile(valueFileId, valueFile.GetSize(),
                                                               (uint)_newPositionMap.Count, 28 * (ulong)_newPositionMap.EnsureCapacity(0)
                                                               );
        }
Esempio n. 2
0
        void MoveValuesContent(ISpanWriter writer, uint wastefulFileId, uint pvlFileId)
        {
            const uint blockSize      = 256 * 1024;
            var        wastefulStream = _keyValueDB.FileCollection.GetFile(wastefulFileId);
            var        totalSize      = wastefulStream !.GetSize();
            var        blocks         = (int)((totalSize + blockSize - 1) / blockSize);
            var        wasteInMemory  = new byte[blocks][];
            var        pos            = 0UL;
            var        readLimiter    = new BytesPerSecondLimiter(_keyValueDB.CompactorReadBytesPerSecondLimit);

            for (var i = 0; i < blocks; i++)
            {
                _cancellation.ThrowIfCancellationRequested();
                wasteInMemory[i] = new byte[blockSize];
                var readSize = totalSize - pos;
                if (readSize > blockSize)
                {
                    readSize = blockSize;
                }
                wastefulStream.RandomRead(wasteInMemory[i].AsSpan(0, (int)readSize), pos, true);
                pos += readSize;
                readLimiter.Limit(pos);
            }

            _keyValueDB.IterateRoot(_root, (valueFileId, valueOfs, valueSize) =>
            {
                if (valueFileId != wastefulFileId)
                {
                    return;
                }
                var size = (uint)Math.Abs(valueSize);
                _newPositionMap.Add(((ulong)wastefulFileId << 32) | valueOfs,
                                    ((ulong)pvlFileId << 32) + (ulong)writer.GetCurrentPositionWithoutWriter());
                pos = valueOfs;
                while (size > 0)
                {
                    _cancellation.ThrowIfCancellationRequested();
                    var blockId    = pos / blockSize;
                    var blockStart = pos % blockSize;
                    var writeSize  = (uint)(blockSize - blockStart);
                    if (writeSize > size)
                    {
                        writeSize = size;
                    }
                    writer.WriteBlockWithoutWriter(
                        ref MemoryMarshal.GetReference(wasteInMemory[blockId].AsSpan((int)blockStart, (int)writeSize)),
                        writeSize);
                    size -= writeSize;
                    pos  += writeSize;
                    _writerBytesPerSecondLimiter.Limit((ulong)writer.GetCurrentPositionWithoutWriter());
                }
            });
        }