public void RemoveOrphanedPages() {
using (var manifestInst = this.Manifest.GetLatestManifest()) {
// find all the sbt files in the data directory
var files = Directory.GetFiles(this.Manifest.BaseFileName, "*.sbt").ToDictionary(f => Path.GetFileNameWithoutExtension(f.ToLower()));
for (int level = 0; level < manifestInst.NumLevels - 1; level++) {
foreach (var page in manifestInst.GetPagesAtLevel(level)) {
// Yes this is kind of backwards to add the file path and then strip it off, but I want to make sure we are using the exact same logic
// as that which creates the file names.
string fileForPage = Path.GetFileNameWithoutExtension(Config.SortedBlockTableFile(this.Manifest.BaseFileName, page.Level, page.Version));
// Remove the page from the file list because it's in the manifest and we've accounted for it.
files.Remove(fileForPage);
}
}
// Loop over the leftover files and handle them
foreach (var file in files.Keys) {
try {
var parts = file.Split('-');
int level = int.Parse(parts[0]);
int version = int.Parse(parts[1]);
// First let's check the version number, we don't want to remove any new files that are being created while this is happening
if (level < manifestInst.NumLevels && version < manifestInst.CurrentVersion(level)) {
string orphanedFile = Config.SortedBlockTableFile(Manifest.BaseFileName, level, version);
// Delete the file.
Helper.DeleteFile(orphanedFile, true, (msg) => { Manifest.LogMessage(msg); });
Manifest.LogMessage("Removing Orphaned Pages '{0}'", orphanedFile);
}
} catch {
// Best effort, here. If we fail, continue.
}
}
}
// Now process the indexes as well
Manifest.LogMessage("Removing Orphaned Index Pages");
lock (_secondaryIndexes) {
foreach (var idx in _secondaryIndexes) {
idx.Value.RemoveOrphanedPages();
}
}
}