private void ScavengeInternal(IIndexScavengerLog log, CancellationToken ct) { var toScavenge = _indexMap.InOrder().ToList(); foreach (var pTable in toScavenge) { var startNew = Stopwatch.StartNew(); try { ct.ThrowIfCancellationRequested(); using (var reader = _tfReaderFactory()) { var indexmapFile = Path.Combine(_directory, IndexMapFilename); var scavengeResult = _indexMap.Scavenge(pTable.Id, ct, (streamId, currentHash) => UpgradeHash(streamId, currentHash), entry => reader.ExistsAt(entry.Position), entry => ReadEntry(reader, entry.Position), _fileNameProvider, _ptableVersion, _indexCacheDepth, _skipIndexVerify); if (scavengeResult.IsSuccess) { _indexMap = scavengeResult.ScavengedMap; _indexMap.SaveToFile(indexmapFile); scavengeResult.OldTable.MarkForDestruction(); var entriesDeleted = scavengeResult.OldTable.Count - scavengeResult.NewTable.Count; log.IndexTableScavenged(scavengeResult.Level, scavengeResult.Index, startNew.Elapsed, entriesDeleted, scavengeResult.NewTable.Count, scavengeResult.SpaceSaved); } else { log.IndexTableNotScavenged(scavengeResult.Level, scavengeResult.Index, startNew.Elapsed, pTable.Count, ""); } } } catch (OperationCanceledException) { log.IndexTableNotScavenged(-1, -1, startNew.Elapsed, pTable.Count, "Scavenge cancelled"); throw; } catch (Exception ex) { log.IndexTableNotScavenged(-1, -1, startNew.Elapsed, pTable.Count, ex.Message); throw; } } }