示例#1
0
        internal bool Run()
        {
            if (_keyValueDB.FileCollection.GetCount() == 0)
            {
                return(false);
            }
            _root = _keyValueDB.LastCommited;
            var dontTouchGeneration = _keyValueDB.GetGeneration(_root.TrLogFileId);

            InitFileStats(dontTouchGeneration);
            CalculateFileUsefullness();
            var totalWaste = CalcTotalWaste();

            if (totalWaste < (ulong)_keyValueDB.MaxTrLogFileSize / 4)
            {
                if (_keyValueDB.DistanceFromLastKeyIndex(_root) < (ulong)(_keyValueDB.MaxTrLogFileSize / 4))
                {
                    return(false);
                }
                _keyValueDB.CreateIndexFile(_cancellation);
                _keyValueDB.FileCollection.DeleteAllUnknownFiles();
                return(false);
            }
            _cancellation.ThrowIfCancellationRequested();
            uint valueFileId;
            var  writer = _keyValueDB.StartPureValuesFile(out valueFileId);

            _newPositionMap = new Dictionary <ulong, uint>();
            var toRemoveFileIds = new List <uint>();

            while (true)
            {
                var wastefullFileId = FindMostWastefullFile(_keyValueDB.MaxTrLogFileSize - writer.GetCurrentPosition());
                if (wastefullFileId == 0)
                {
                    break;
                }
                MoveValuesContent(writer, wastefullFileId);
                _fileStats[wastefullFileId] = new FileStat(0);
                toRemoveFileIds.Add(wastefullFileId);
            }
            var valueFile = _keyValueDB.FileCollection.GetFile(valueFileId);

            valueFile.HardFlush();
            valueFile.Truncate();
            var btreesCorrectInTransactionId = _keyValueDB.AtomicallyChangeBTree(root => root.RemappingIterate((uint oldFileId, uint oldOffset, out uint newFileId, out uint newOffset) =>
            {
                newFileId = valueFileId;
                _cancellation.ThrowIfCancellationRequested();
                return(_newPositionMap.TryGetValue(((ulong)oldFileId << 32) | oldOffset, out newOffset));
            }));

            _keyValueDB.CreateIndexFile(_cancellation);
            _keyValueDB.WaitForFinishingTransactionsBefore(btreesCorrectInTransactionId, _cancellation);
            if (_newPositionMap.Count == 0)
            {
                toRemoveFileIds.Add(valueFileId);
            }
            _keyValueDB.MarkAsUnknown(toRemoveFileIds);
            _keyValueDB.FileCollection.DeleteAllUnknownFiles();
            return(true);
        }