Browse Source

FileStorage allow lowmemoryusage

Allows to not use memory when reading safebox, direct read from disk (less mem usage)
PascalCoin 6 years ago
parent
commit
689533a382
1 changed files with 38 additions and 21 deletions
  1. 38 21
      src/core/UFileStorage.pas

+ 38 - 21
src/core/UFileStorage.pas

@@ -39,6 +39,7 @@ Type
 
 
   TFileStorage = Class(TStorage)
   TFileStorage = Class(TStorage)
   private
   private
+    FLowMemoryUsage: Boolean;
     FStorageLock : TPCCriticalSection;
     FStorageLock : TPCCriticalSection;
     FBlockChainStream : TFileStream;
     FBlockChainStream : TFileStream;
     FPendingBufferOperationsStream : TFileStream;
     FPendingBufferOperationsStream : TFileStream;
@@ -86,6 +87,7 @@ Type
     Procedure SetBlockChainFile(BlockChainFileName : AnsiString);
     Procedure SetBlockChainFile(BlockChainFileName : AnsiString);
     Function HasUpgradedToVersion2 : Boolean; override;
     Function HasUpgradedToVersion2 : Boolean; override;
     Procedure CleanupVersion1Data; override;
     Procedure CleanupVersion1Data; override;
+    property LowMemoryUsage : Boolean read FLowMemoryUsage write FLowMemoryUsage;
   End;
   End;
 
 
 implementation
 implementation
@@ -208,6 +210,7 @@ end;
 constructor TFileStorage.Create(AOwner: TComponent);
 constructor TFileStorage.Create(AOwner: TComponent);
 begin
 begin
   inherited;
   inherited;
+  FLowMemoryUsage := False;
   FDatabaseFolder := '';
   FDatabaseFolder := '';
   FBlockChainFileName := '';
   FBlockChainFileName := '';
   FBlockChainStream := Nil;
   FBlockChainStream := Nil;
@@ -462,7 +465,7 @@ begin
         if (sr.Attr and FileAttrs) = FileAttrs then begin
         if (sr.Attr and FileAttrs) = FileAttrs then begin
           auxfn := folder+PathDelim+sr.Name;
           auxfn := folder+PathDelim+sr.Name;
           If LoadBankFileInfo(auxfn,sbHeader) then begin
           If LoadBankFileInfo(auxfn,sbHeader) then begin
-            if (((max_block<0) Or (sbHeader.blocksCount<=max_block)) AND (sbHeader.blocksCount>blockscount)) And
+            if (((max_block<0) Or (sbHeader.endBlock<=max_block)) AND (sbHeader.blocksCount>blockscount)) And
               (sbHeader.startBlock=0) And (sbHeader.endBlock=sbHeader.startBlock+sbHeader.blocksCount-1) then begin
               (sbHeader.startBlock=0) And (sbHeader.endBlock=sbHeader.startBlock+sbHeader.blocksCount-1) then begin
               filename := auxfn;
               filename := auxfn;
               blockscount := sbHeader.blocksCount;
               blockscount := sbHeader.blocksCount;
@@ -477,17 +480,23 @@ begin
       TLog.NewLog(ltinfo,Self.ClassName,'Loading SafeBox protocol:'+IntToStr(goodSbHeader.protocol)+' with '+inttostr(blockscount)+' blocks from file '+filename);
       TLog.NewLog(ltinfo,Self.ClassName,'Loading SafeBox protocol:'+IntToStr(goodSbHeader.protocol)+' with '+inttostr(blockscount)+' blocks from file '+filename);
       fs := TFileStream.Create(filename,fmOpenRead);
       fs := TFileStream.Create(filename,fmOpenRead);
       try
       try
-        ms := TMemoryStream.Create;
-        Try
-          ms.CopyFrom(fs,0);
-          fs.Position := 0;
-          ms.Position := 0;
-          if not Bank.LoadBankFromStream(ms,False,'',restoreProgressNotify,errors) then begin
+        fs.Position := 0;
+        if LowMemoryUsage then begin
+          if not Bank.LoadBankFromStream(fs,False,'',restoreProgressNotify,errors) then begin
             TLog.NewLog(lterror,ClassName,'Error reading bank from file: '+filename+ ' Error: '+errors);
             TLog.NewLog(lterror,ClassName,'Error reading bank from file: '+filename+ ' Error: '+errors);
           end;
           end;
-        Finally
-          ms.Free;
-        End;
+        end else begin
+          ms := TMemoryStream.Create;
+          Try
+            ms.CopyFrom(fs,0);
+            ms.Position := 0;
+            if not Bank.LoadBankFromStream(ms,False,'',restoreProgressNotify,errors) then begin
+              TLog.NewLog(lterror,ClassName,'Error reading bank from file: '+filename+ ' Error: '+errors);
+            end;
+          Finally
+            ms.Free;
+          End;
+        end;
       finally
       finally
         fs.Free;
         fs.Free;
       end;
       end;
@@ -509,14 +518,18 @@ begin
     fs := TFileStream.Create(bankfilename,fmCreate);
     fs := TFileStream.Create(bankfilename,fmCreate);
     try
     try
       fs.Size := 0;
       fs.Size := 0;
-      ms := TMemoryStream.Create;
-      try
-        Bank.SafeBox.SaveSafeBoxToAStream(ms,0,Bank.SafeBox.BlocksCount-1);
-        ms.Position := 0;
-        fs.Position := 0;
-        fs.CopyFrom(ms,0);
-      finally
-        ms.Free;
+      fs.Position:=0;
+      if LowMemoryUsage then begin
+        Bank.SafeBox.SaveSafeBoxToAStream(fs,0,Bank.SafeBox.BlocksCount-1);
+      end else begin
+        ms := TMemoryStream.Create;
+        try
+          Bank.SafeBox.SaveSafeBoxToAStream(ms,0,Bank.SafeBox.BlocksCount-1);
+          ms.Position := 0;
+          fs.CopyFrom(ms,0);
+        finally
+          ms.Free;
+        end;
       end;
       end;
     finally
     finally
       fs.Free;
       fs.Free;
@@ -560,7 +573,7 @@ begin
   Finally
   Finally
     UnlockBlockChainStream;
     UnlockBlockChainStream;
   End;
   End;
-  if Assigned(Bank) then SaveBank;
+  if Assigned(Bank) then SaveBank(False);
 end;
 end;
 
 
 Const CT_SafeboxsToStore = 10;
 Const CT_SafeboxsToStore = 10;
@@ -569,8 +582,12 @@ class function TFileStorage.GetSafeboxCheckpointingFileName(const BaseDataFolder
 begin
 begin
   Result := '';
   Result := '';
   If not ForceDirectories(BaseDataFolder) then exit;
   If not ForceDirectories(BaseDataFolder) then exit;
-  // We will store checkpointing
-  Result := BaseDataFolder + PathDelim+'checkpoint'+ inttostr((block DIV CT_BankToDiskEveryNBlocks) MOD CT_SafeboxsToStore)+'.safebox';
+  if TPCSafeBox.MustSafeBoxBeSaved(block) then begin
+    // We will store checkpointing
+    Result := BaseDataFolder + PathDelim+'checkpoint'+ inttostr((block DIV CT_BankToDiskEveryNBlocks) MOD CT_SafeboxsToStore)+'.safebox';
+  end else begin
+    Result := BaseDataFolder + PathDelim+'checkpoint_'+inttostr(block)+'.safebox';
+  end;
 end;
 end;
 
 
 function TFileStorage.GetBlockHeaderFirstBytePosition(Stream : TStream; Block: Cardinal; CanInitialize : Boolean; var iBlockHeaders : Integer; var BlockHeaderFirstBlock: Cardinal): Boolean;
 function TFileStorage.GetBlockHeaderFirstBytePosition(Stream : TStream; Block: Cardinal; CanInitialize : Boolean; var iBlockHeaders : Integer; var BlockHeaderFirstBlock: Cardinal): Boolean;