diff --git a/AuraTrader/AuraTrader.dproj b/AuraTrader/AuraTrader.dproj index db13ae8..08ef546 100644 --- a/AuraTrader/AuraTrader.dproj +++ b/AuraTrader/AuraTrader.dproj @@ -4,7 +4,7 @@ 20.3 FMX True - Release + Debug Win64 AuraTrader 3 diff --git a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas index a2b260e..aee166d 100644 --- a/Src/AST/Myc.Ast.Compiler.TypeChecker.pas +++ b/Src/AST/Myc.Ast.Compiler.TypeChecker.pas @@ -775,7 +775,7 @@ begin if allScalar then begin - def := TScalarRecordRegistry.Intern(scalarDefFields); + def := TScalarRecord.TRegistry.Intern(scalarDefFields); staticType := TTypes.CreateRecord(def); Result := TAst.RecordLiteral(Node.Identity, fieldList, def, nil, staticType); end diff --git a/Src/Data/Myc.Data.Scalar.JSON.pas b/Src/Data/Myc.Data.Scalar.JSON.pas index b26d1a8..e544364 100644 --- a/Src/Data/Myc.Data.Scalar.JSON.pas +++ b/Src/Data/Myc.Data.Scalar.JSON.pas @@ -63,7 +63,7 @@ begin fields[i] := TScalarRecordField.Create(fieldKey, TScalar.TKind(GetEnumValue(TypeInfo(TScalar.TKind), kindStr))); end; - Result := TScalarRecordRegistry.Intern(fields); + Result := TScalarRecord.TRegistry.Intern(fields); finally jsonValue.Free; end; diff --git a/Src/Myc.Trade.DataFeed.pas b/Src/Myc.Trade.DataFeed.pas index 87df3a6..92880f2 100644 --- a/Src/Myc.Trade.DataFeed.pas +++ b/Src/Myc.Trade.DataFeed.pas @@ -53,8 +53,8 @@ type function GetIsValid: Boolean; public constructor Create(const APath, ASymbol, AExtension: String; AYear, AMonth: Integer; const ABasename: String); - function GetBaseFileName: string; function GetFullFileName: string; + property BaseFileName: string read FBasename; property IsValid: Boolean read GetIsValid; property Extension: String read FExtension; property Path: String read FPath; @@ -84,10 +84,14 @@ type // Loading Logic function DoLoad(const FileName: string; const Gate: TLatch): TFuture>; function LoadDataFile(const DataFile: TDataFile): TFuture>; - function GetNextFile(const Curr: TDataFile): TDataFile; // Processing Logic - function ProcessFile(FileInfo: TDataFile; const DataFile: TFuture>; const Terminated: TState): TState; + function ProcessFile( + const Files: TArray; + Index: Integer; + const DataFile: TFuture>; + const Terminated: TState + ): TState; function ProcessChunks(const Batches: TArray; Terminated: TState): TState; @@ -97,7 +101,6 @@ type // Helpers function ParseFileName(const FileName: string): TDataFile; - function FindFirstFile(const Symbol: string): TFuture; procedure UpdateSymbols; private @@ -213,14 +216,9 @@ begin FBasename := ABasename; end; -function TScalarRecordFeed.TDataFile.GetBaseFileName: string; -begin - Result := FBasename; -end; - function TScalarRecordFeed.TDataFile.GetFullFileName: string; begin - Result := TPath.Combine(FPath, GetBaseFileName + FExtension); + Result := TPath.Combine(FPath, FBasename + FExtension); end; function TScalarRecordFeed.TDataFile.GetIsValid: Boolean; @@ -350,51 +348,6 @@ begin ); end; -function TScalarRecordFeed.FindFirstFile(const Symbol: string): TFuture; -begin - var symName := Symbol; - Result := - FSymbols.Chain( - function(const Symbols: TDictionary>): TDataFile - var - symbolFiles: TArray; - begin - if Symbols.TryGetValue(symName, symbolFiles) and (Length(symbolFiles) > 0) then - Result := symbolFiles[0] - else - Result := Default(TDataFile); - end - ); -end; - -function TScalarRecordFeed.GetNextFile(const Curr: TDataFile): TDataFile; -var - allSymbolFiles: TArray; - foundIndex: Integer; -begin - Result := Default(TDataFile); - if not Curr.IsValid or not FSymbols.Done.IsSet then - exit; - - if not FSymbols.Value.TryGetValue(Curr.Symbol, allSymbolFiles) then - exit; - - foundIndex := -1; - for var i := 0 to High(allSymbolFiles) do - begin - if allSymbolFiles[i].GetBaseFileName() = Curr.GetBaseFileName() then - begin - foundIndex := i; - break; - end; - end; - - if (foundIndex <> -1) and (foundIndex < High(allSymbolFiles)) then - begin - Result := allSymbolFiles[foundIndex + 1]; - end; -end; - function TScalarRecordFeed.ParseFileName(const FileName: string): TDataFile; var path, fileNameNoPath, baseName, ext, symbol: string; @@ -608,32 +561,64 @@ end; function TScalarRecordFeed.ProcessData(const Symbol: String; const Terminated: TState): TState; begin var cTerminated := Terminated; + var cSymbol := Symbol; + // We fetch the list once, then iterate by index. Result := - FindFirstFile(Symbol) - .Chain( - function(const FirstInfo: TDataFile): TState + FSymbols.Chain( + function(const AllSymbols: TDictionary>): TState + var + files: TArray; + begin + if AllSymbols.TryGetValue(cSymbol, files) and (Length(files) > 0) then begin - Result := ProcessFile(FirstInfo, LoadDataFile(FirstInfo), cTerminated); - end); + // Start with Index 0 + Result := ProcessFile(files, 0, LoadDataFile(files[0]), cTerminated); + end + else + begin + Result := TState.Null; + end; + end + ); end; -function TScalarRecordFeed.ProcessFile(FileInfo: TDataFile; const DataFile: TFuture>; const Terminated: TState): TState; +function TScalarRecordFeed.ProcessFile( + const Files: TArray; + Index: Integer; + const DataFile: TFuture>; + const Terminated: TState +): TState; begin - if not FileInfo.IsValid or Terminated.IsSet then + // Check bounds and termination + if (Index < 0) or (Index > High(Files)) or Terminated.IsSet then exit(DataFile.Done); - var nextInfo := GetNextFile(FileInfo); - var nextFuture := LoadDataFile(nextInfo); + var currentInfo := Files[Index]; + if not currentInfo.IsValid then + exit(DataFile.Done); + + // Prefetch logic: Prepare the next file immediately (if available) + var nextIndex := Index + 1; + var nextFuture: TFuture>; + + if nextIndex <= High(Files) then + nextFuture := LoadDataFile(Files[nextIndex]) + else + nextFuture := TFuture>.Construct(TArray(nil)); // End of stream var cTerminated := Terminated; + + // Process current data, then recurse to next index Result := DataFile.Chain( function(const Batches: TArray): TState begin var done := ProcessChunks(Batches, Terminated); - Result := TaskManager.RunTask(done, function: TState begin Result := ProcessFile(nextInfo, nextFuture, cTerminated); end); + // Recurse with Index + 1 + Result := + TaskManager.RunTask(done, function: TState begin Result := ProcessFile(Files, nextIndex, nextFuture, cTerminated); end); end ); end;