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); }