Changeset 1515 for trunk/eraser6/Eraser.Manager/DirectExecutor.cs
- Timestamp:
- 1/13/2010 4:29:25 AM (2 years ago)
- Location:
- trunk/eraser6
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
Eraser.Manager/DirectExecutor.cs (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk/eraser6
- Property svn:mergeinfo changed
/branches/eraser6/SpeedMeter (added) merged: 1502-1514
- Property svn:mergeinfo changed
-
trunk/eraser6/Eraser.Manager/DirectExecutor.cs
r1496 r1515 251 251 252 252 //Run the task 253 TaskProgressManager progress = new TaskProgressManager(task);254 253 foreach (ErasureTarget target in task.Targets) 255 254 try 256 255 { 257 progress.Event.CurrentTarget = target;258 ++progress.Event.CurrentTargetIndex;259 260 256 UnusedSpaceTarget unusedSpaceTarget = 261 257 target as UnusedSpaceTarget; … … 264 260 265 261 if (unusedSpaceTarget != null) 266 EraseUnusedSpace(task, unusedSpaceTarget , progress);262 EraseUnusedSpace(task, unusedSpaceTarget); 267 263 else if (fileSystemObjectTarget != null) 268 EraseFilesystemObject(task, fileSystemObjectTarget , progress);264 EraseFilesystemObject(task, fileSystemObjectTarget); 269 265 else 270 266 throw new ArgumentException(S._("Unknown erasure target.")); … … 324 320 325 321 /// <summary> 326 /// Manages the progress for any operation.327 /// </summary>328 private class ProgressManager329 {330 /// <summary>331 /// Starts measuring the speed of the task.332 /// </summary>333 public void Start()334 {335 startTime = DateTime.Now;336 }337 338 /// <summary>339 /// Tracks the amount of the operation completed.340 /// </summary>341 public long Completed342 {343 get344 {345 return completed;346 }347 set348 {349 lastCompleted += value - completed;350 completed = value;351 }352 }353 354 /// <summary>355 /// The amount to reach before the operation completes.356 /// </summary>357 public long Total358 {359 get360 {361 return total;362 }363 set364 {365 total = value;366 }367 }368 369 /// <summary>370 /// Gets the percentage of the operation completed.371 /// </summary>372 public float Progress373 {374 get375 {376 return (float)((double)Completed / Total);377 }378 }379 380 /// <summary>381 /// Computes the speed of the erase, in units of completion per second,382 /// based on the information collected in the previous 15 seconds.383 /// </summary>384 public int Speed385 {386 get387 {388 if (DateTime.Now == startTime)389 return 0;390 391 if ((DateTime.Now - lastSpeedCalc).Seconds < 5 && lastSpeed != 0)392 return lastSpeed;393 394 //Calculate how much time has passed395 double timeElapsed = (DateTime.Now - lastSpeedCalc).TotalSeconds;396 if (timeElapsed == 0.0)397 return 0;398 399 //Then compute the speed of the calculation400 lastSpeed = (int)(lastCompleted / timeElapsed);401 lastSpeedCalc = DateTime.Now;402 lastCompleted = 0;403 return lastSpeed;404 }405 }406 407 /// <summary>408 /// Calculates the estimated amount of time left based on the total409 /// amount of information to erase and the current speed of the erase410 /// </summary>411 public TimeSpan TimeLeft412 {413 get414 {415 if (Speed == 0)416 return new TimeSpan(0, 0, -1);417 return new TimeSpan(0, 0, (int)((Total - Completed) / Speed));418 }419 }420 421 /// <summary>422 /// The starting time of the operation, used to determine average speed.423 /// </summary>424 private DateTime startTime;425 426 /// <summary>427 /// The last time a speed calculation was computed so that speed is not428 /// computed too often.429 /// </summary>430 private DateTime lastSpeedCalc;431 432 /// <summary>433 /// The last calculated speed of the operation.434 /// </summary>435 private int lastSpeed;436 437 /// <summary>438 /// The amount of the operation completed since the last speed computation.439 /// </summary>440 private long lastCompleted;441 442 /// <summary>443 /// The amount of the operation completed.444 /// </summary>445 private long completed;446 447 /// <summary>448 /// The amount to reach before the operation is completed.449 /// </summary>450 private long total;451 }452 453 /// <summary>454 /// Provides a common interface to track the progress made by the Erase functions.455 /// </summary>456 private class TaskProgressManager : ProgressManager457 {458 /// <summary>459 /// Constructor.460 /// </summary>461 public TaskProgressManager(Task task)462 {463 foreach (ErasureTarget target in task.Targets)464 Total += target.TotalData;465 466 Event = new TaskProgressEventArgs(task);467 Start();468 }469 470 /// <summary>471 /// The TaskProgressEventArgs object representing the progress of the current472 /// task.473 /// </summary>474 public TaskProgressEventArgs Event475 {476 get477 {478 return evt;479 }480 set481 {482 evt = value;483 }484 }485 486 private TaskProgressEventArgs evt;487 }488 489 /// <summary>490 322 /// Executes a unused space erase. 491 323 /// </summary> 492 324 /// <param name="task">The task currently being executed</param> 493 325 /// <param name="target">The target of the unused space erase.</param> 494 /// <param name="progress">The progress manager object managing the progress of the task</param> 495 private void EraseUnusedSpace(Task task, UnusedSpaceTarget target, TaskProgressManager progress) 326 private void EraseUnusedSpace(Task task, UnusedSpaceTarget target) 496 327 { 497 328 //Check for sufficient privileges to run the unused space erasure. … … 532 363 VolumeInfo volInfo = VolumeInfo.FromMountpoint(target.Drive); 533 364 FileSystem fsManager = FileSystemManager.Get(volInfo); 534 365 366 //Start sampling the speed of the task. 367 SteppedProgressManager progress = new SteppedProgressManager(); 368 target.Progress = progress; 369 task.Progress.Steps.Add(new SteppedProgressManager.Step( 370 progress, 1.0f / task.Targets.Count)); 371 535 372 //Erase the cluster tips of every file on the drive. 536 373 if (target.EraseClusterTips) 537 374 { 538 progress.Event.CurrentTargetStatus = S._("Searching for files' cluster tips..."); 539 progress.Event.CurrentTargetTotalPasses = method.Passes; 540 progress.Event.CurrentItemProgress = -1.0f; 541 progress.Event.TimeLeft = new TimeSpan(0, 0, -1); 542 543 //Start counting statistics 375 //Define the callback handlers 376 ProgressManager tipSearch = new ProgressManager(); 377 progress.Steps.Add(new SteppedProgressManager.Step(tipSearch, 378 0.0f, S._("Searching for files' cluster tips..."))); 379 tipSearch.Total = 1; 380 ClusterTipsSearchProgress searchProgress = delegate(string path) 381 { 382 if (currentTask.Canceled) 383 throw new OperationCanceledException(S._("The task was cancelled.")); 384 385 task.OnProgressChanged(target, 386 new ProgressChangedEventArgs(tipSearch, 387 new TaskProgressChangedEventArgs(path, 0, 0))); 388 }; 389 544 390 ProgressManager tipProgress = new ProgressManager(); 545 tipProgress.Start(); 546 547 //Define the callback handlers 548 ClusterTipsSearchProgress searchProgress = delegate(string path) 549 { 550 progress.Event.CurrentItemName = path; 551 task.OnProgressChanged(progress.Event); 391 progress.Steps.Add(new SteppedProgressManager.Step(tipProgress, 0.1f, 392 S._("Erasing cluster tips..."))); 393 ClusterTipsEraseProgress eraseProgress = 394 delegate(int currentFile, int totalFiles, string currentFilePath) 395 { 396 tipSearch.Completed = tipSearch.Total; 397 tipProgress.Total = totalFiles; 398 tipProgress.Completed = currentFile; 399 task.OnProgressChanged(target, 400 new ProgressChangedEventArgs(tipProgress, 401 new TaskProgressChangedEventArgs(currentFilePath, 0, 0))); 552 402 553 403 if (currentTask.Canceled) … … 555 405 }; 556 406 557 ClusterTipsEraseProgress eraseProgress = 558 delegate(int currentFile, int totalFiles, string currentFilePath) 559 { 560 tipProgress.Total = totalFiles; 561 tipProgress.Completed = currentFile; 562 563 progress.Event.CurrentTargetStatus = S._("Erasing cluster tips..."); 564 progress.Event.CurrentItemName = currentFilePath; 565 progress.Event.CurrentItemProgress = tipProgress.Progress; 566 progress.Event.CurrentTargetProgress = progress.Event.CurrentItemProgress / 10; 567 progress.Event.TimeLeft = tipProgress.TimeLeft; 568 task.OnProgressChanged(progress.Event); 569 570 if (currentTask.Canceled) 571 throw new OperationCanceledException(S._("The task was cancelled.")); 572 }; 573 407 //Start counting statistics 574 408 fsManager.EraseClusterTips(VolumeInfo.FromMountpoint(target.Drive), 575 409 method, task.Log, searchProgress, eraseProgress); … … 585 419 Eraser.Util.File.SetCompression(info.FullName, false); 586 420 421 ProgressManager mainProgress = new ProgressManager(); 422 progress.Steps.Add(new SteppedProgressManager.Step(mainProgress, 423 target.EraseClusterTips ? 0.8f : 0.9f, S._("Erasing unused space..."))); 424 587 425 //Continue creating files while there is free space. 588 progress.Event.CurrentTargetStatus = S._("Erasing unused space...");589 progress.Event.CurrentItemName = target.Drive;590 task.OnProgressChanged(progress.Event);591 426 while (volInfo.AvailableFreeSpace > 0) 592 427 { … … 600 435 //Set the length of the file to be the amount of free space left 601 436 //or the maximum size of one of these dumps. 437 mainProgress.Total = mainProgress.Completed + volInfo.AvailableFreeSpace; 602 438 long streamLength = Math.Min(ErasureMethod.FreeSpaceFileUnit, 603 volInfo.AvailableFreeSpace);439 mainProgress.Total); 604 440 605 441 //Handle IO exceptions gracefully, because the filesystem … … 624 460 delegate(long lastWritten, long totalData, int currentPass) 625 461 { 626 progress.Completed = Math.Min(progress.Total, 627 progress.Completed + lastWritten); 628 progress.Event.CurrentItemPass = currentPass; 629 progress.Event.CurrentItemProgress = progress.Progress; 630 if (target.EraseClusterTips) 631 progress.Event.CurrentTargetProgress = (float) 632 (0.1f + progress.Event.CurrentItemProgress * 0.8f); 633 else 634 progress.Event.CurrentTargetProgress = (float) 635 (progress.Event.CurrentItemProgress * 0.9f); 636 progress.Event.TimeLeft = progress.TimeLeft; 637 task.OnProgressChanged(progress.Event); 462 mainProgress.Completed += lastWritten; 463 task.OnProgressChanged(target, 464 new ProgressChangedEventArgs(mainProgress, 465 new TaskProgressChangedEventArgs(target.Drive, currentPass, method.Passes))); 638 466 639 467 if (currentTask.Canceled) … … 644 472 } 645 473 474 //Mark the main bulk of the progress as complete 475 mainProgress.Completed = mainProgress.Total; 476 646 477 //Erase old resident file system table files 647 progress.Event.CurrentItemName = S._("Old resident file system table files"); 648 task.OnProgressChanged(progress.Event); 649 ProgressManager residentFilesProgress = new ProgressManager(); 650 residentFilesProgress.Start(); 478 ProgressManager residentProgress = new ProgressManager(); 479 progress.Steps.Add(new SteppedProgressManager.Step(residentProgress, 480 0.05f, S._("Old resident file system table files"))); 651 481 fsManager.EraseOldFileSystemResidentFiles(volInfo, info, method, 652 482 delegate(int currentFile, int totalFiles) 653 483 { 654 resident FilesProgress.Completed = currentFile;655 resident FilesProgress.Total = totalFiles;656 progress.Event.CurrentItemProgress = residentFilesProgress.Progress;657 progress.Event.TimeLeft = residentFilesProgress.TimeLeft;658 task.OnProgressChanged(progress.Event);484 residentProgress.Completed = currentFile; 485 residentProgress.Total = totalFiles; 486 task.OnProgressChanged(target, 487 new ProgressChangedEventArgs(residentProgress, 488 new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 659 489 660 490 if (currentTask.Canceled) … … 662 492 } 663 493 ); 494 495 residentProgress.Completed = residentProgress.Total = 1; 664 496 } 665 497 finally 666 498 { 667 499 //Remove the folder holding all our temporary files. 668 progress.Event.CurrentTargetStatus = S._("Removing temporary files..."); 669 task.OnProgressChanged(progress.Event); 500 ProgressManager tempFiles = new ProgressManager(); 501 progress.Steps.Add(new SteppedProgressManager.Step(tempFiles, 502 0.0f, S._("Removing temporary files..."))); 503 task.OnProgressChanged(target, new ProgressChangedEventArgs(tempFiles, 504 new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 670 505 fsManager.DeleteFolder(info); 506 tempFiles.Completed = tempFiles.Total = 1; 671 507 } 672 508 673 509 //Then clean the old file system entries 674 progress.Event.CurrentTargetStatus = S._("Erasing unused directory structures...");675 ProgressManager fsEntriesProgress = new ProgressManager();676 fsEntriesProgress.Start();510 ProgressManager structureProgress = new ProgressManager(); 511 progress.Steps.Add(new SteppedProgressManager.Step(structureProgress, 512 0.05f, S._("Erasing unused directory structures..."))); 677 513 fsManager.EraseDirectoryStructures(volInfo, 678 514 delegate(int currentFile, int totalFiles) … … 682 518 683 519 //Compute the progress 684 fsEntriesProgress.Total = totalFiles;685 fsEntriesProgress.Completed = currentFile;520 structureProgress.Total = totalFiles; 521 structureProgress.Completed = currentFile; 686 522 687 523 //Set the event parameters, then broadcast the progress event. 688 progress.Event.TimeLeft = fsEntriesProgress.TimeLeft; 689 progress.Event.CurrentItemProgress = fsEntriesProgress.Progress; 690 progress.Event.CurrentTargetProgress = (float)( 691 0.9 + progress.Event.CurrentItemProgress / 10); 692 task.OnProgressChanged(progress.Event); 524 task.OnProgressChanged(target, 525 new ProgressChangedEventArgs(structureProgress, 526 new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 693 527 } 694 528 ); 695 } 696 697 /// <summary> 698 /// Traverses the given folder and deletes it securely only if it is 699 /// empty. 700 /// </summary> 701 /// <param name="info">The folder to check.</param> 702 private delegate void FolderEraseDelegate(DirectoryInfo info); 529 530 structureProgress.Completed = structureProgress.Total; 531 target.Progress = null; 532 } 703 533 704 534 /// <summary> … … 708 538 /// <param name="target">The target of the erasure.</param> 709 539 /// <param name="progress">The progress manager for the current task.</param> 710 private void EraseFilesystemObject(Task task, FileSystemObjectTarget target, 711 TaskProgressManager progress) 540 private void EraseFilesystemObject(Task task, FileSystemObjectTarget target) 712 541 { 713 542 //Retrieve the list of files to erase. … … 719 548 720 549 //Calculate the total amount of data required to finish the wipe. 721 dataTotal = method.CalculateEraseDataSize(paths, dataTotal);550 //dataTotal = method.CalculateEraseDataSize(paths, dataTotal); 722 551 723 552 //Set the event's current target status. 724 progress.Event.CurrentTargetStatus = S._("Erasing files..."); 553 TaskEventArgs eventArgs = new TaskEventArgs(task); 554 SteppedProgressManager progress = new SteppedProgressManager(); 555 target.Progress = progress; 556 task.Progress.Steps.Add(new SteppedProgressManager.Step(progress, 1.0f / task.Targets.Count)); 725 557 726 558 //Iterate over every path, and erase the path. … … 728 560 { 729 561 //Update the task progress 730 progress.Event.CurrentTargetProgress = i / (float)paths.Count;731 progress. Event.CurrentTarget = target;732 progress.Event.CurrentItemName = paths[i];733 progress.Event.CurrentItemProgress = 0;734 progress.Event.CurrentTargetTotalPasses = method.Passes;735 task.OnProgressChanged(progress.Event);562 ProgressManager step = new ProgressManager(); 563 progress.Steps.Add(new SteppedProgressManager.Step(step, 564 1.0f / paths.Count, S._("Erasing files..."))); 565 task.OnProgressChanged(target, 566 new ProgressChangedEventArgs(step, 567 new TaskProgressChangedEventArgs(paths[i], 0, method.Passes))); 736 568 737 569 //Get the filesystem provider to handle the secure file erasures … … 768 600 } 769 601 770 long itemWritten = 0;771 602 fsManager.EraseFileSystemObject(info, method, 772 603 delegate(long lastWritten, long totalData, int currentPass) 773 604 { 774 dataTotal -= lastWritten;775 progress.Completed += lastWritten;776 progress.Event.CurrentItemPass = currentPass;777 progress.Event.CurrentItemProgress = (float)778 ((itemWritten += lastWritten) / (float)totalData);779 progress.Event.CurrentTargetProgress =780 (i + progress.Event.CurrentItemProgress) /781 (float)paths.Count;782 progress.Event.TimeLeft = progress.TimeLeft;783 task.OnProgressChanged(progress.Event);784 785 605 if (currentTask.Canceled) 786 606 throw new OperationCanceledException(S._("The task was cancelled.")); 607 608 step.Completed += lastWritten; 609 step.Total = totalData; 610 task.OnProgressChanged(target, 611 new ProgressChangedEventArgs(step, 612 new TaskProgressChangedEventArgs(info.FullName, currentPass, method.Passes))); 787 613 }); 788 614 … … 791 617 if (fileInfo != null) 792 618 fsManager.DeleteFile(fileInfo); 619 step.Completed = step.Total = 1; 793 620 } 794 621 catch (UnauthorizedAccessException) … … 828 655 if (target is FolderTarget) 829 656 { 830 progress.Event.CurrentTargetStatus = S._("Removing folders..."); 657 ProgressManager step = new ProgressManager(); 658 progress.Steps.Add(new SteppedProgressManager.Step(step, 659 0.0f, S._("Removing folders..."))); 831 660 832 661 //Remove all subfolders which are empty. 833 662 FolderTarget fldr = (FolderTarget)target; 834 663 FileSystem fsManager = FileSystemManager.Get(VolumeInfo.FromMountpoint(fldr.Path)); 835 FolderEraseDelegateeraseEmptySubFolders = null;664 Action<DirectoryInfo> eraseEmptySubFolders = null; 836 665 eraseEmptySubFolders = delegate(DirectoryInfo info) 837 666 { 838 foreach (DirectoryInfo subDir in info.GetDirectories())839 eraseEmptySubFolders(subDir);840 841 progress.Event.CurrentItemName = info.FullName;842 task.OnProgressChanged(progress.Event);843 844 FileSystemInfo[] files = info.GetFileSystemInfos();845 if (files.Length == 0)846 fsManager.DeleteFolder(info);667 foreach (DirectoryInfo subDir in info.GetDirectories()) 668 eraseEmptySubFolders(subDir); 669 task.OnProgressChanged(target, 670 new ProgressChangedEventArgs(step, 671 new TaskProgressChangedEventArgs(info.FullName, 0, 0))); 672 673 FileSystemInfo[] files = info.GetFileSystemInfos(); 674 if (files.Length == 0) 675 fsManager.DeleteFolder(info); 847 676 }; 848 677 eraseEmptySubFolders(new DirectoryInfo(fldr.Path)); … … 851 680 { 852 681 DirectoryInfo info = new DirectoryInfo(fldr.Path); 853 progress.Event.CurrentItemName = info.FullName; 854 task.OnProgressChanged(progress.Event); 682 task.OnProgressChanged(target, 683 new ProgressChangedEventArgs(step, 684 new TaskProgressChangedEventArgs(info.FullName, 0, 0))); 855 685 856 686 //See if this is the root of a volume. … … 871 701 if (target is RecycleBinTarget) 872 702 { 873 progress.Event.CurrentTargetStatus = S._("Emptying recycle bin..."); 874 task.OnProgressChanged(progress.Event); 703 ProgressManager step = new ProgressManager(); 704 progress.Steps.Add(new SteppedProgressManager.Step(step, 705 0.0f, S._("Emptying recycle bin..."))); 706 task.OnProgressChanged(target, 707 new ProgressChangedEventArgs(step, 708 new TaskProgressChangedEventArgs(string.Empty, 0, 0))); 875 709 876 710 ShellApi.EmptyRecycleBin(EmptyRecycleBinOptions.NoConfirmation | 877 711 EmptyRecycleBinOptions.NoProgressUI | EmptyRecycleBinOptions.NoSound); 878 712 } 713 714 target.Progress = null; 879 715 } 880 716
Note: See TracChangeset
for help on using the changeset viewer.
