Selaa lähdekoodia

New BTree index TAccountsOrderedBySalePrice (Accounts ordered by Sale price)

This index will be used for a future PayToKey feature obtaining available accounts at "AccountsOrderedBySalePrice"
Pascal Coin 4 vuotta sitten
vanhempi
commit
0d430b4a52

+ 24 - 1
src/core/UAccounts.pas

@@ -219,6 +219,7 @@ Type
     // OrderedAccountKeysList (Added after Build 3.0.1) allows an indexed search of public keys in the safebox with mem optimization
     FOrderedAccountKeysList : TSafeboxPubKeysAndAccounts;
     FAccountsOrderedByUpdatedBlock : TAccountsOrderedByUpdatedBlock;
+    FAccountsOrderedBySalePrice : TAccountsOrderedBySalePrice;
     {$ENDIF}
     FModifiedBlocksSeparatedChain : TOrderedBlockAccountList; // Used when has PreviousSafebox (Used if we are on a Separated chain)
     //
@@ -327,6 +328,7 @@ Type
     property PCAbstractMem : TPCAbstractMem read FPCAbstractMem;
     {$ENDIF}
     Function AccountsOrderedByUpdatedBlock : TAccountsOrderedByUpdatedBlock;
+    Function AccountsOrderedBySalePrice : TAccountsOrderedBySalePrice;
   End;
 
 
@@ -2413,6 +2415,15 @@ begin
   end;
 end;
 
+function TPCSafeBox.AccountsOrderedBySalePrice: TAccountsOrderedBySalePrice;
+begin
+  {$IFDEF USE_ABSTRACTMEM}
+  Result := FPCAbstractMem.AccountsOrderedBySalePrice;
+  {$ELSE}
+  Result := FAccountsOrderedBySalePrice;
+  {$ENDIF}
+end;
+
 function TPCSafeBox.AccountsOrderedByUpdatedBlock: TAccountsOrderedByUpdatedBlock;
 begin
   {$IFDEF USE_ABSTRACTMEM}
@@ -2838,6 +2849,7 @@ begin
   FAggregatedHashrate := TBigNum.Create(0);
   FOrderedByName := TOrderedRawList.Create;
   FAccountsOrderedByUpdatedBlock := TAccountsOrderedByUpdatedBlock.Create(GetAccount);
+  FAccountsOrderedBySalePrice := TAccountsOrderedBySalePrice.Create(GetAccount);
   {$ENDIF}
   FListOfOrderedAccountKeysList := TList<TOrderedAccountKeysList>.Create;
   FCurrentProtocol := CT_PROTOCOL_1;
@@ -2883,6 +2895,7 @@ begin
   FreeAndNil(FSubChains);
   {$IFnDEF USE_ABSTRACTMEM}
   FreeAndNil(FAccountsOrderedByUpdatedBlock);
+  FreeAndNil(FAccountsOrderedBySalePrice);
   {$ENDIF}
 
   If Assigned(FPreviousSafeBox) then begin
@@ -3638,8 +3651,13 @@ begin
         for j := low(LBlock.accounts) to High(LBlock.accounts) do begin
           FAccountsOrderedByUpdatedBlock.Update(
             LBlock.accounts[j].account,
-            LBlock.accounts[j].updated_on_block_active_mode,
+            0,
             LBlock.accounts[j].updated_on_block_active_mode);
+          FAccountsOrderedBySalePrice.UpdateAccountBySalePrice(
+            LBlock.accounts[j].account,
+            CT_AccountInfo_NUL,
+            LBlock.accounts[j].accountInfo
+            );
         end;
         {$ENDIF}
         for j := low(LBlock.accounts) to High(LBlock.accounts) do begin
@@ -4758,6 +4776,11 @@ begin
     blockAccount.accounts[iAccount].updated_on_block_active_mode,
     newUpdated_block_active_mode
    );
+  FAccountsOrderedBySalePrice.UpdateAccountBySalePrice(
+    account_number,
+    blockAccount.accounts[iAccount].accountInfo,
+    newAccountInfo
+   );
   {$ENDIF}
 
   if (NOT TAccountComp.EqualAccountKeys(blockAccount.accounts[iAccount].accountInfo.accountKey,newAccountInfo.accountKey)) then begin

+ 32 - 7
src/core/UPCAbstractMem.pas

@@ -121,6 +121,7 @@ type
     FSavingOldGridCache : Boolean;
     FSavingOldDefaultCacheDataBlocksSize : Integer;
     FAccountsOrderedByUpdatedBlock : TAccountsOrderedByUpdatedBlock;
+    FAccountsOrderedBySalePrice : TAccountsOrderedBySalePrice;
 
     function IsChecking : Boolean;
     procedure DoCheck;
@@ -180,6 +181,7 @@ type
     Property MaxAccountKeysCache : Integer read GetMaxAccountKeysCache write SetMaxAccountKeysCache;
     Property SavingNewSafeboxMode : Boolean read FSavingNewSafeboxMode write SetSavingNewSafeboxMode;
     Property AccountsOrderedByUpdatedBlock : TAccountsOrderedByUpdatedBlock read FAccountsOrderedByUpdatedBlock;
+    Property AccountsOrderedBySalePrice : TAccountsOrderedBySalePrice read FAccountsOrderedBySalePrice;
   end;
 
 implementation
@@ -188,7 +190,7 @@ uses UAccounts;
 
 const
   CT_PCAbstractMem_FileVersion = 100;
-  CT_PCAbstractMem_HeaderVersion = 2;
+  CT_PCAbstractMem_HeaderVersion = 3;
 
 function _AccountCache_Comparision(const Left, Right: TAccountCache.PAVLCacheMemData): Integer;
 begin
@@ -313,6 +315,7 @@ const
   [32..35] 4 bytes: FZoneAggregatedHashrate.position
   [36..39] 4 bytes: LZoneBuffersBlockHash
   [40..43] 4 bytes: LZoneAccountsOrderedByUpdatedBlock.position
+  [44..47] 4 bytes: LZoneAccountsOrderedBySalePrice.position
   ...
   [96..99] 4 bytes: Header version
   }
@@ -321,7 +324,8 @@ var LZone,
   LZoneAccounts,
   LZoneAccountsNames,
   LZoneAccountKeys,
-  LZoneAccountsOrderedByUpdatedBlock : TAMZone;
+  LZoneAccountsOrderedByUpdatedBlock,
+  LZoneAccountsOrderedBySalePrice : TAMZone;
   LZoneBuffersBlockHash : TAbstractMemPosition;
   LHeader, LBuffer, LBigNum : TBytes;
   LIsGood : Boolean;
@@ -336,6 +340,7 @@ begin
   FreeAndNil(FAccountKeys);
   FreeAndNil(FBufferBlocksHash);
   FreeAndNil(FAccountsOrderedByUpdatedBlock);
+  FreeAndNil(FAccountsOrderedBySalePrice);
   //
   Result := False;
   AIsNewStructure := True;
@@ -347,6 +352,7 @@ begin
   FZoneAggregatedHashrate.Clear;
   LZoneBuffersBlockHash := 0;
   LZoneAccountsOrderedByUpdatedBlock.Clear;
+  LZoneAccountsOrderedBySalePrice.Clear;
 
   if (FAbstractMem.ReadFirstData(LZone,LHeader)) then begin
     // Check if header is valid:
@@ -370,6 +376,7 @@ begin
         Move(LHeader[32], FZoneAggregatedHashrate.position, 4);
         LZoneBuffersBlockHash := LZone.position + 36;
         Move(LHeader[40], LZoneAccountsOrderedByUpdatedBlock.position, 4);
+        Move(LHeader[44], LZoneAccountsOrderedBySalePrice.position, 4);
         //
         Move(LHeader[96], LHeaderVersion, 4);
         if (LHeaderVersion>CT_PCAbstractMem_HeaderVersion) then begin
@@ -377,12 +384,17 @@ begin
         end else begin
           AIsNewStructure := False;
           //
-          if (LZoneAccountsOrderedByUpdatedBlock.position=0) then begin
-            if (Not FAbstractMem.ReadOnly) then begin
+          if (Not FAbstractMem.ReadOnly) then begin
+            if (LZoneAccountsOrderedByUpdatedBlock.position=0) then begin
               LZoneAccountsOrderedByUpdatedBlock := FAbstractMem.New(TAbstractMemBTree.MinAbstractMemInitialPositionSize);
               Move(LZoneAccountsOrderedByUpdatedBlock.position,LHeader[40],4);
               FAbstractMem.Write(LZone.position,LHeader[0],Length(LHeader));
             end;
+            if (LZoneAccountsOrderedBySalePrice.position=0) then begin
+              LZoneAccountsOrderedBySalePrice := FAbstractMem.New(TAbstractMemBTree.MinAbstractMemInitialPositionSize);
+              Move(LZoneAccountsOrderedBySalePrice.position,LHeader[44],4);
+              FAbstractMem.Write(LZone.position,LHeader[0],Length(LHeader));
+            end;
           end;
         end;
       end;
@@ -407,6 +419,8 @@ begin
     LZoneBuffersBlockHash := LZone.position+36;
     LZoneAccountsOrderedByUpdatedBlock := FAbstractMem.New(
       TAbstractMemBTree.MinAbstractMemInitialPositionSize);
+    LZoneAccountsOrderedBySalePrice := FAbstractMem.New(
+      TAbstractMemBTree.MinAbstractMemInitialPositionSize);
 
     Move(LZoneBlocks.position,       LHeader[16],4);
     Move(LZoneAccounts.position,     LHeader[20],4);
@@ -415,6 +429,7 @@ begin
     Move(FZoneAggregatedHashrate.position,LHeader[32],4);
     LHeaderVersion := CT_PCAbstractMem_HeaderVersion;
     Move(LZoneAccountsOrderedByUpdatedBlock, LHeader[40],4);
+    Move(LZoneAccountsOrderedBySalePrice, LHeader[44],4);
     Move(LHeaderVersion,             LHeader[96],4);
 
     FAbstractMem.Write(LZone.position,LHeader[0],Length(LHeader));
@@ -442,11 +457,12 @@ begin
   end;
   FBufferBlocksHash := TPCAbstractMemBytesBuffer32Safebox.Create(FAbstractMem,LZoneBuffersBlockHash,FBlocks.Count);
 
-  if (LZoneAccountsOrderedByUpdatedBlock.position<>0) then begin
-    FAccountsOrderedByUpdatedBlock := TAccountsOrderedByUpdatedBlock.Create(FAbstractMem,LZoneAccountsOrderedByUpdatedBlock,DoGetAccount);
-  end;
+  FAccountsOrderedByUpdatedBlock := TAccountsOrderedByUpdatedBlock.Create(FAbstractMem,LZoneAccountsOrderedByUpdatedBlock,DoGetAccount);
   FAccounts.AccountsOrderedByUpdatedBlock := FAccountsOrderedByUpdatedBlock;
 
+  FAccountsOrderedBySalePrice := TAccountsOrderedBySalePrice.Create(FAbstractMem,LZoneAccountsOrderedBySalePrice,DoGetAccount);
+  FAccounts.AccountsOrderedBySalePrice := FAccountsOrderedBySalePrice;
+
   FAccountCache.Clear;
 
   if (Not AIsNewStructure) And (Not FAbstractMem.ReadOnly) And (LHeaderVersion<CT_PCAbstractMem_HeaderVersion) then begin
@@ -792,9 +808,18 @@ procedure TPCAbstractMem.UpgradeAbstractMemVersion(const ACurrentHeaderVersion:
 var LFirstTC, LTC : TTickCount;
   i : integer;
   LAccount : TAccount;
+  LaccInfoNul : TAccountInfo;
 begin
   LFirstTC := TPlatform.GetTickCount;
   LTC := LFirstTC;
+  if (ACurrentHeaderVersion=2) then begin
+    // Set accounts price
+    LaccInfoNul.Clear;
+    for i := 0 to AccountsCount-1 do begin
+      LAccount := GetAccount(i);
+      AccountsOrderedBySalePrice.UpdateAccountBySalePrice(LAccount.account,LaccInfoNul,LAccount.accountInfo);
+    end;
+  end;
   TLog.NewLog(ltinfo,ClassName,Format('Finalized upgrade AbstractMem file from %d to %d in %.2f seconds',[ACurrentHeaderVersion,CT_PCAbstractMem_HeaderVersion, TPlatform.GetElapsedMilliseconds(LFirstTC)/1000]));
 end;
 

+ 16 - 2
src/core/UPCAbstractMemAccounts.pas

@@ -22,13 +22,16 @@ type
   private
     FAccountKeys: TPCAbstractMemAccountKeys;
     FAccountsOrderedByUpdatedBlock : TAccountsOrderedByUpdatedBlock;
+    FAccountsOrderedBySalePrice : TAccountsOrderedBySalePrice;
   protected
     procedure LoadFrom(const ABytes: TBytes; var AItem: TAccount); override;
     procedure SaveTo(const AItem: TAccount; AIsAddingItem : Boolean; var ABytes: TBytes); override;
   public
+    Constructor Create(AAbstractMem : TAbstractMem; const AInitialZone : TAMZone; ADefaultElementsPerBlock : Integer; AUseCache : Boolean); override;
     class procedure LoadAccountFromTBytes(const ABytes: TBytes; const AAccountKeys : TPCAbstractMemAccountKeys; var AItem: TAccount);
     property AccountKeys: TPCAbstractMemAccountKeys read FAccountKeys write FAccountKeys;
     property AccountsOrderedByUpdatedBlock: TAccountsOrderedByUpdatedBlock read FAccountsOrderedByUpdatedBlock write FAccountsOrderedByUpdatedBlock;
+    property AccountsOrderedBySalePrice: TAccountsOrderedBySalePrice read FAccountsOrderedBySalePrice write FAccountsOrderedBySalePrice;
   end;
 
   EAbsctractMemAccounts = Class(Exception);
@@ -39,6 +42,16 @@ uses UAccounts;
 
 { TPCAbstractMemListAccounts }
 
+constructor TPCAbstractMemListAccounts.Create(AAbstractMem: TAbstractMem;
+  const AInitialZone: TAMZone; ADefaultElementsPerBlock: Integer;
+  AUseCache: Boolean);
+begin
+  inherited;
+  FAccountKeys := Nil;
+  FAccountsOrderedByUpdatedBlock := Nil;
+  FAccountsOrderedBySalePrice := Nil;
+end;
+
 class procedure TPCAbstractMemListAccounts.LoadAccountFromTBytes(
   const ABytes: TBytes; const AAccountKeys: TPCAbstractMemAccountKeys;
   var AItem: TAccount);
@@ -136,9 +149,10 @@ begin
     if LPrevious.updated_on_block_active_mode<>AItem.updated_on_block_active_mode then begin
       FAccountsOrderedByUpdatedBlock.Update(AItem.account,LPrevious.updated_on_block_active_mode,AItem.updated_on_block_active_mode);
     end;
-
+    FAccountsOrderedBySalePrice.UpdateAccountBySalePrice(AItem.account,LPrevious.accountInfo,AItem.accountInfo);
   end else begin
-    FAccountsOrderedByUpdatedBlock.Update(AItem.account,LPrevious.updated_on_block_active_mode,AItem.updated_on_block_active_mode);
+    FAccountsOrderedByUpdatedBlock.Update(AItem.account,0,AItem.updated_on_block_active_mode);
+    FAccountsOrderedBySalePrice.UpdateAccountBySalePrice(AItem.account,CT_AccountInfo_NUL,AItem.accountInfo);
   end;
 
   LStream := TMemoryStream.Create;

+ 81 - 1
src/core/UPCAccountsOrdenations.pas

@@ -62,9 +62,21 @@ type
     function Update(const AAccountNumber, AOldUpdatedBlock, ANewUpdatedBlock : Integer) : Boolean;
   End;
 
+  TAccountsOrderedBySalePrice = Class({$IFDEF USE_ABSTRACTMEM}TAbstractMemBTree{$ELSE}TMemoryBTree<Integer>{$ENDIF})
+  protected
+    FCallReturnAccount : TCallReturnAccount;
+    FSearching_AccountNumber : Integer;
+    FSearching_AccountInfo : TAccountInfo;
+    function DoCompareData(const ALeftData, ARightData: TAbstractMemPosition): Integer; override;
+  public
+    function NodeDataToString(const AData : TAbstractMemPosition) : String; override;
+    function UpdateAccountBySalePrice(const AAccountNumber : Integer; const AOldAccountInfo, ANewAccountInfo : TAccountInfo) : Boolean;
+    constructor Create({$IFDEF USE_ABSTRACTMEM}AAbstractMem : TAbstractMem; const AInitialZone: TAMZone; {$ENDIF}ACallReturnAccount : TCallReturnAccount);
+  End;
+
 implementation
 
-Uses UPCAbstractMemAccounts;
+Uses UPCAbstractMemAccounts, UAccounts;
 
 { TAccountsOrderedByUpdatedBlock }
 
@@ -162,4 +174,72 @@ begin
   end else Result := Format('(Pos:%d not found)',[AData]);
 end;
 
+{ TAccounstBySalePrice }
+
+constructor TAccountsOrderedBySalePrice.Create({$IFDEF USE_ABSTRACTMEM}AAbstractMem: TAbstractMem;
+  const AInitialZone: TAMZone; {$ENDIF}ACallReturnAccount: TCallReturnAccount);
+begin
+  {$IFDEF USE_ABSTRACTMEM}
+  inherited Create(AAbstractMem,AInitialZone,False,15);
+  {$ELSE}
+  inherited Create(Nil,False,15);
+  {$ENDIF}
+  FCallReturnAccount := ACallReturnAccount;
+  FSearching_AccountNumber := -1;
+  FSearching_AccountInfo.Clear;
+end;
+
+function TAccountsOrderedBySalePrice.DoCompareData(const ALeftData,
+  ARightData: TAbstractMemPosition): Integer;
+var LLeftAccount, LRightAccount : TAccount;
+  LopResult : Int64;
+begin
+  if (ALeftData = ARightData) then Exit(0);
+
+  FCallReturnAccount(ARightData,LRightAccount);
+  if ((FSearching_AccountNumber>=0) And (ALeftData=FSearching_AccountNumber)) then begin
+    LopResult := FSearching_AccountInfo.price - LRightAccount.accountInfo.price;
+  end else begin
+    FCallReturnAccount(ALeftData,LLeftAccount);
+    LopResult := LLeftAccount.accountInfo.price - LRightAccount.accountInfo.price;
+  end;
+  if LopResult<0 then Result := -1
+  else if LopResult>0 then Result := 1
+  else Result := ALeftData - ARightData;
+end;
+
+function TAccountsOrderedBySalePrice.NodeDataToString(
+  const AData: TAbstractMemPosition): String;
+var LAccount : TAccount;
+begin
+  if FCallReturnAccount(AData,LAccount) then begin
+    Result := Format('(Acc:%d price:%s)',[LAccount.account,TAccountComp.FormatMoney(LAccount.accountInfo.price)]);
+  end else Result := Format('(Pos:%d not found)',[AData]);
+end;
+
+function TAccountsOrderedBySalePrice.UpdateAccountBySalePrice(const AAccountNumber: Integer;
+  const AOldAccountInfo, ANewAccountInfo: TAccountInfo): Boolean;
+var Ldone : Boolean;
+begin
+  if (TAccountComp.IsAccountForSale(AOldAccountInfo)=TAccountComp.IsAccountForSale(ANewAccountInfo)) and
+    (AOldAccountInfo.price = ANewAccountInfo.price) then Exit(True); // No updates, no need to change
+  Lock;
+  Try
+    FSearching_AccountNumber := AAccountNumber;
+    FSearching_AccountInfo := AOldAccountInfo;
+    Ldone := Delete(AAccountNumber);
+    if (Ldone) and (Not TAccountComp.IsAccountForSale(AOldAccountInfo)) then raise EAbsctractMemAccounts.Create('ERROR DEV 20210126-1');
+    if (Not Ldone) and (TAccountComp.IsAccountForSale(AOldAccountInfo)) then raise EAbsctractMemAccounts.Create('ERROR DEV 20210126-2');
+    FSearching_AccountInfo := ANewAccountInfo;
+    if (TAccountComp.IsAccountForSale(ANewAccountInfo)) then begin
+      if Not Add(AAccountNumber) then raise EAbsctractMemAccounts.Create('ERROR DEV 20210126-3');
+    end;
+    FSearching_AccountNumber := -1;
+    FSearching_AccountInfo.Clear;
+  Finally
+    Unlock;
+  End;
+  Result := True;
+end;
+
 end.