Changeset 25 for trunk/UDriveScan.pas


Ignore:
Timestamp:
Apr 5, 2016, 10:54:28 PM (8 years ago)
Author:
chronos
Message:
  • Added: Record transfer speed to chart during scan operation.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/UDriveScan.pas

    r24 r25  
    77uses
    88  Classes, SysUtils, Syncobjs, UBlockMap, Forms, DOM, UConfig, UPhysDrive,
    9   UXMLUtils, Contnrs;
     9  UXMLUtils, Contnrs, ExtCtrls, DateUtils;
    1010
    1111type
    1212  TDriveScan = class;
    1313
    14   TRunMode = (rmRead, rmWrite, rmNone);
     14  TRunMode = (rmRead, rmWrite, rmNone, rmSpeed);
    1515  TExceptionEvent = procedure (Sender: TObject; E: Exception) of object;
    1616
     
    4747  end;
    4848
     49  { TSpeedValue }
     50
     51  TSpeedValue = record
     52    Null: Boolean;
     53    Max: Int64;
     54    Average: Int64;
     55    Min: Int64;
     56    procedure Reset;
     57    procedure UpdateValue(Value: Int64);
     58  end;
     59
    4960  { TDriveScan }
    5061
     
    5768    ScanThread: TScanThread;
    5869    LastExceptionMessage: string;
     70    SpeedTimer: TTimer;
     71    SpeedTimeLast: TDateTime;
     72    SectorLast: Integer;
    5973    procedure DoOnExceptionSync;
    6074    procedure DoOnException(Sender: TObject; E: Exception);
     
    6579    procedure SetDriveName(AValue: string);
    6680    procedure SetSectorCount(AValue: Integer);
     81    procedure SpeedTimerExecute(Sender: TObject);
    6782  public
    6883    Lock: TCriticalSection;
     
    7792    SectorStart: Integer;
    7893    SectorEnd: Integer;
     94    SpeedSteps: array of TSpeedValue;
     95    SpeedStepsCount: Integer;
    7996    function GetName: string;
    8097    function GetElapsedTime: TDateTime;
     
    107124  SUnknownRunMode = 'Unknown run mode';
    108125
     126{ TSpeedValue }
     127
     128procedure TSpeedValue.Reset;
     129begin
     130  Null := True;
     131end;
     132
     133procedure TSpeedValue.UpdateValue(Value: Int64);
     134begin
     135  if Null then begin
     136    Min := High(Int64);
     137    Max := Low(Int64);
     138    Average := 0;
     139  end;
     140  Null := False;
     141  if Value > Max then Max := Value;
     142  // TODO: Computer average
     143  Average := Value;
     144  if Value < Min then Min := Value;
     145end;
     146
    109147{ TDriveScanProfile }
    110148
     
    213251
    214252procedure TDriveScan.Reset;
     253var
     254  I: Integer;
    215255begin
    216256  TimeStart := Now;
     
    218258  BlockMap.Clear;
    219259  FSectorCurrent := SectorStart;
     260  SetLength(SpeedSteps, SpeedStepsCount);
     261  for I := 0 to Length(SpeedSteps) - 1 do
     262    SpeedSteps[I].Reset;
    220263end;
    221264
     
    228271    ScanThread.Scan := Self;
    229272    ScanThread.Start;
     273    SpeedTimeLast := Now;
     274    SectorLast := SectorCurrent;
     275    SpeedTimer.Enabled := True;
    230276  end;
    231277end;
     
    294340end;
    295341
     342procedure TDriveScan.SpeedTimerExecute(Sender: TObject);
     343var
     344  SpeedTimeCurrent: TDateTime;
     345  Index: Integer;
     346begin
     347  SpeedTimeCurrent := Now;
     348  Index := Trunc(SectorCurrent / SectorCount * SpeedStepsCount);
     349  if Index >= Length(SpeedSteps) then Index := Length(SpeedSteps) - 1;
     350  SpeedSteps[Index].UpdateValue(
     351    Trunc((SectorCurrent - SectorLast) * SectorSize / ((SpeedTimeCurrent - SpeedTimeLast) / OneSecond)));
     352  SpeedTimeLast := SpeedTimeCurrent;
     353  SectorLast := SectorCurrent;
     354end;
     355
    296356function TDriveScan.GetName: string;
    297357begin
     
    305365begin
    306366  if not Terminated then begin
     367    SpeedTimer.Enabled := False;
    307368    Terminated := True;
    308369    ScanThread.Terminate;
     
    324385  Lock := TCriticalSection.Create;
    325386  BlockMap := TBlockMap.Create;
     387  SpeedTimer := TTimer.Create(nil);
     388  SpeedTimer.Interval := 500;
     389  SpeedTimer.Enabled := False;
     390  SpeedTimer.OnTimer := SpeedTimerExecute;
     391  SpeedStepsCount := 1000;
    326392  SectorSize := 4096;
    327393  Terminated := True;
     
    333399begin
    334400  Stop;
     401  FreeAndNil(SpeedTimer);
    335402  FreeAndNil(BlockMap);
    336403  FreeAndNil(Lock);
     
    341408var
    342409  NewNode: TDOMNode;
     410  NewNode2: TDOMNode;
     411  NewNode3: TDOMNode;
     412  I: Integer;
    343413begin
    344414  with Node do begin
     
    358428    AppendChild(NewNode);
    359429    BlockMap.SaveToNode(NewNode);
     430
     431    NewNode := OwnerDocument.CreateElement('Speed');
     432    AppendChild(NewNode);
     433    WriteInt64(NewNode, 'Count', Length(SpeedSteps));
     434    NewNode2 := OwnerDocument.CreateElement('Steps');
     435    NewNode.AppendChild(NewNode2);
     436    for I := 0 to Length(SpeedSteps) - 1 do
     437    if not SpeedSteps[I].Null then begin
     438      NewNode3 := OwnerDocument.CreateElement('Step');
     439      NewNode2.AppendChild(NewNode3);
     440      WriteInteger(NewNode3, 'Index', I);
     441      WriteInt64(NewNode3, 'Avg', SpeedSteps[I].Average);
     442      WriteInt64(NewNode3, 'Min', SpeedSteps[I].Min);
     443      WriteInt64(NewNode3, 'Max', SpeedSteps[I].Max);
     444    end;
    360445  end;
    361446end;
     
    364449var
    365450  NewNode: TDOMNode;
     451  NewNode2: TDOMNode;
     452  NewNode3: TDOMNode;
     453  I: Integer;
    366454begin
    367455  with Node do begin
     
    381469    if Assigned(NewNode) then
    382470      BlockMap.LoadFromNode(NewNode);
    383   end;
     471
     472    NewNode := FindNode('Speed');
     473    if Assigned(NewNode) then begin
     474      SpeedStepsCount := ReadInt64(NewNode, 'Count', 0);
     475      SetLength(SpeedSteps, SpeedStepsCount);
     476      NewNode2 := NewNode.FindNode('Steps');
     477      if Assigned(NewNode2) then begin
     478        NewNode3 := NewNode2.FirstChild;
     479        while Assigned(NewNode3) and (NewNode3.NodeName = 'Step') do begin
     480          I := ReadInteger(NewNode3, 'Index', 0);
     481          SpeedSteps[I].Average := ReadInt64(NewNode3, 'Avg', 0);
     482          SpeedSteps[I].Min := ReadInt64(NewNode3, 'Min', 0);
     483          SpeedSteps[I].Max := ReadInt64(NewNode3, 'Max', 0);
     484          SpeedSteps[I].Null := False;
     485          NewNode3 := NewNode3.NextSibling;
     486        end;
     487      end;
     488    end;
     489end;
    384490end;
    385491
Note: See TracChangeset for help on using the changeset viewer.