|
@@ -41,6 +41,19 @@ uses
|
|
|
type
|
|
|
EFileMem = Class(Exception);
|
|
|
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ TFileMemStats = record
|
|
|
+ ReadsCount : Integer;
|
|
|
+ WriteCount : Integer;
|
|
|
+ ReadsBytesCount : Integer;
|
|
|
+ WriteBytesCount : Integer;
|
|
|
+ IncreaseSizeCount : Integer;
|
|
|
+ IncreaseSizeBytesCount : Integer;
|
|
|
+ function ToString : String;
|
|
|
+ procedure Clear;
|
|
|
+ end;
|
|
|
+ {$ENDIF}
|
|
|
+
|
|
|
TFileMem = Class(TAbstractMem)
|
|
|
private
|
|
|
FFileStream : TFileStream;
|
|
@@ -48,6 +61,9 @@ type
|
|
|
FFileName: String;
|
|
|
FIsStableCache: Boolean;
|
|
|
FIsFlushingCache : Boolean;
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ FStats : TFileMemStats;
|
|
|
+ {$ENDIF}
|
|
|
function OnCacheNeedDataProc(var ABuffer; AStartPos : Integer; ASize : Integer) : Boolean;
|
|
|
function OnCacheSaveDataProc(const ABuffer; AStartPos : Integer; ASize : Integer) : Boolean;
|
|
|
procedure SetMaxCacheSize(const Value: Integer);
|
|
@@ -77,16 +93,46 @@ type
|
|
|
function LockCache : TCacheMem;
|
|
|
procedure UnlockCache;
|
|
|
property FileName : String read FFileName;
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ function GetStatsReport(AClearStats : Boolean) : String; override;
|
|
|
+ {$ENDIF}
|
|
|
End;
|
|
|
|
|
|
implementation
|
|
|
|
|
|
+{$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+{ TFileMemStats }
|
|
|
+
|
|
|
+function TFileMemStats.ToString: String;
|
|
|
+begin
|
|
|
+ Result := Format('FileMemStats Reads:%d (%d b) Writes:%d (%d b) Increases:%d (%d b)',
|
|
|
+ [Self.ReadsCount,Self.ReadsBytesCount,
|
|
|
+ Self.WriteCount,Self.WriteBytesCount,
|
|
|
+ Self.IncreaseSizeCount,Self.IncreaseSizeBytesCount
|
|
|
+ ]);
|
|
|
+end;
|
|
|
+
|
|
|
+procedure TFileMemStats.Clear;
|
|
|
+begin
|
|
|
+ Self.ReadsCount := 0;
|
|
|
+ Self.WriteCount := 0;
|
|
|
+ Self.ReadsBytesCount := 0;
|
|
|
+ Self.WriteBytesCount := 0;
|
|
|
+ Self.IncreaseSizeCount := 0;
|
|
|
+ Self.IncreaseSizeBytesCount := 0;
|
|
|
+end;
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
{ TFileMem }
|
|
|
|
|
|
function TFileMem.AbsoluteRead(const AAbsolutePosition: Int64; var ABuffer; ASize: Integer): Integer;
|
|
|
begin
|
|
|
FFileStream.Seek(AAbsolutePosition,soFromBeginning);
|
|
|
Result := FFileStream.Read(ABuffer,ASize);
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ inc(FStats.ReadsCount);
|
|
|
+ inc(FStats.ReadsBytesCount,ASize);
|
|
|
+ {$ENDIF}
|
|
|
end;
|
|
|
|
|
|
function TFileMem.AbsoluteWrite(const AAbsolutePosition: Int64; const ABuffer; ASize: Integer): Integer;
|
|
@@ -94,6 +140,10 @@ begin
|
|
|
FFileStream.Seek(AAbsolutePosition,soFromBeginning);
|
|
|
Result := FFileStream.Write(ABuffer,ASize);
|
|
|
CacheIsNOTStable;
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ inc(FStats.WriteCount);
|
|
|
+ inc(FStats.WriteBytesCount,ASize);
|
|
|
+ {$ENDIF}
|
|
|
end;
|
|
|
|
|
|
procedure TFileMem.CacheIsNOTStable;
|
|
@@ -110,6 +160,15 @@ constructor TFileMem.Create(const AFileName: String; AReadOnly: Boolean);
|
|
|
var LFileMode : Integer;
|
|
|
LReadOnly : Boolean;
|
|
|
begin
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ FStats.Clear;
|
|
|
+ FStats.ReadsCount := 0;
|
|
|
+ FStats.WriteCount := 0;
|
|
|
+ FStats.ReadsBytesCount := 0;
|
|
|
+ FStats.WriteBytesCount := 0;
|
|
|
+ FStats.IncreaseSizeCount := 0;
|
|
|
+ FStats.IncreaseSizeBytesCount := 0;
|
|
|
+ {$ENDIF}
|
|
|
FIsStableCache := True;
|
|
|
FIsFlushingCache := False;
|
|
|
FFileName := AFileName;
|
|
@@ -148,12 +207,18 @@ begin
|
|
|
Exit;
|
|
|
end;
|
|
|
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ inc(FStats.IncreaseSizeCount);
|
|
|
+ {$ENDIF}
|
|
|
FFileStream.Seek(0,soFromEnd);
|
|
|
// GoTo ANextAvailablePos
|
|
|
if (FFileStream.Position<ANextAvailablePos) then begin
|
|
|
SetLength(LBuff,ANextAvailablePos - FFileStream.Position);
|
|
|
FillChar(LBuff[0],Length(LBuff),0);
|
|
|
FFileStream.Write(LBuff[0],Length(LBuff));
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ inc(FStats.IncreaseSizeBytesCount,Length(LBuff));
|
|
|
+ {$ENDIF}
|
|
|
end;
|
|
|
if (FFileStream.Position<ANextAvailablePos) then raise EFileMem.Create(Format('End file position (%d) is less than next available pos %d',[FFileStream.Position,ANextAvailablePos]));
|
|
|
// At this time ANextAvailablePos <= FFileStream.Position
|
|
@@ -162,6 +227,9 @@ begin
|
|
|
SetLength(LBuff,AMaxAvailablePos - FFileStream.Position);
|
|
|
FillChar(LBuff[0],Length(LBuff),0);
|
|
|
FFileStream.Write(LBuff[0],Length(LBuff));
|
|
|
+ {$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+ inc(FStats.IncreaseSizeBytesCount,Length(LBuff));
|
|
|
+ {$ENDIF}
|
|
|
end else AMaxAvailablePos := FFileStream.Size;
|
|
|
CacheIsNOTStable;
|
|
|
end;
|
|
@@ -196,6 +264,14 @@ begin
|
|
|
Result := FCache.MaxCacheSize;
|
|
|
end;
|
|
|
|
|
|
+{$IFDEF ABSTRACTMEM_ENABLE_STATS}
|
|
|
+function TFileMem.GetStatsReport(AClearStats : Boolean) : String;
|
|
|
+begin
|
|
|
+ Result := FStats.ToString + #10 + FCache.GetStatsReport(AClearStats);
|
|
|
+ if AClearStats then FStats.Clear;
|
|
|
+end;
|
|
|
+{$ENDIF}
|
|
|
+
|
|
|
function TFileMem.IsAbstractMemInfoStable: Boolean;
|
|
|
begin
|
|
|
Result := FIsStableCache;
|